diff --git a/src/add-ons/translators/tifftranslator/Jamfile b/src/add-ons/translators/tifftranslator/Jamfile index e3a285350d..e8e5c76c41 100755 --- a/src/add-ons/translators/tifftranslator/Jamfile +++ b/src/add-ons/translators/tifftranslator/Jamfile @@ -11,6 +11,7 @@ Translator TIFFTranslator : TiffUintField.cpp TiffUnknownField.cpp TiffIfd.cpp + TiffIfdList.cpp TIFFMain.cpp TIFFTranslator.cpp TIFFView.cpp diff --git a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp index 48c1e4eff2..ac26c387d3 100755 --- a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp +++ b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp @@ -34,6 +34,7 @@ #include "TIFFTranslator.h" #include "TIFFView.h" #include "TiffIfd.h" +#include "TiffIfdList.h" #include "StreamBuffer.h" #include "BitReader.h" @@ -432,7 +433,7 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays) ifd.GetUint(TAG_SAMPLES_PER_PIXEL) != 1) return B_NO_TRANSLATOR; - // Only 1D and fill byte boundery t4options are + // Only 1D and fill byte boundary t4options are // supported if (ifd.HasField(TAG_T4_OPTIONS)) t4options = ifd.GetUint(TAG_T4_OPTIONS); @@ -660,8 +661,8 @@ copy_tiff_name(char *strname, TiffDetails *pdetails, swap_action swp) } status_t -identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, - ssize_t amtread, uint8 *read, swap_action swp, +identify_tiff_header(BPositionIO *inSource, BMessage *ioExtension, + translator_info *outInfo, ssize_t amtread, uint8 *read, swap_action swp, TiffDetails *pdetails = NULL) { if (amtread != 4) @@ -678,16 +679,33 @@ identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, // swap_data() error return B_ERROR; } - TiffIfd ifd(firstIFDOffset, *inSource, swp); + TiffIfdList ifdlist(firstIFDOffset, *inSource, swp); status_t initcheck; - initcheck = ifd.InitCheck(); + initcheck = ifdlist.InitCheck(); // Read in some fields in order to determine whether or not // this particular TIFF image is supported by this translator // Check the required fields if (initcheck == B_OK) { + + int32 document_count, document_index = 1; + document_count = ifdlist.GetCount(); + + if (ioExtension) { + // Add page count to ioExtension + ioExtension->RemoveName(DOCUMENT_COUNT); + ioExtension->AddInt32(DOCUMENT_COUNT, document_count); + + // Check if a document index has been specified + ioExtension->FindInt32(DOCUMENT_INDEX, &document_index); + if (document_index < 1 || document_index > document_count) + return B_NO_TRANSLATOR; + } + + // Identify the page the user asked for + TiffIfd *pifd = ifdlist.GetIfd(document_index - 1); bool bAllocArrays = true; TiffDetails localdetails; @@ -696,7 +714,7 @@ identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, pdetails = &localdetails; } status_t result; - result = check_tiff_fields(ifd, pdetails, bAllocArrays); + result = check_tiff_fields(*pifd, pdetails, bAllocArrays); if (result == B_OK && outInfo) { outInfo->type = B_TIFF_FORMAT; @@ -823,7 +841,7 @@ TIFFTranslator::Identify(BPositionIO *inSource, return B_NO_TRANSLATOR; } - return identify_tiff_header(inSource, outInfo, 4, ch, swp); + return identify_tiff_header(inSource, ioExtension, outInfo, 4, ch, swp); } } @@ -1144,8 +1162,9 @@ TIFFTranslator::decode_huffman(StreamBuffer *pstreambuf, TiffDetails &details, } status_t -TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread, - uint8 *read, swap_action swp, uint32 outType, BPositionIO *outDestination) +TIFFTranslator::translate_from_tiff(BPositionIO *inSource, + BMessage *ioExtension, ssize_t amtread, uint8 *read, swap_action swp, + uint32 outType, BPositionIO *outDestination) { // Can only output to bits for now if (outType != B_TRANSLATOR_BITMAP) @@ -1154,7 +1173,7 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread, status_t result; TiffDetails details; - result = identify_tiff_header(inSource, NULL, + result = identify_tiff_header(inSource, ioExtension, NULL, amtread, read, swp, &details); if (result == B_OK) { // If the TIFF is supported by this translator @@ -1415,7 +1434,7 @@ TIFFTranslator::Translate(BPositionIO *inSource, return B_NO_TRANSLATOR; } - return translate_from_tiff(inSource, 4, ch, swp, outType, + return translate_from_tiff(inSource, ioExtension, 4, ch, swp, outType, outDestination); } } diff --git a/src/add-ons/translators/tifftranslator/TIFFTranslator.h b/src/add-ons/translators/tifftranslator/TIFFTranslator.h index c6084dd3ac..acbec428ef 100755 --- a/src/add-ons/translators/tifftranslator/TIFFTranslator.h +++ b/src/add-ons/translators/tifftranslator/TIFFTranslator.h @@ -43,6 +43,10 @@ #include #include "DecodeTree.h" +// IO Extension Names: +#define DOCUMENT_COUNT "/documentCount" +#define DOCUMENT_INDEX "/documentIndex" + #define TIFF_TRANSLATOR_VERSION 100 #define TIFF_IN_QUALITY 0.1 @@ -142,8 +146,8 @@ private: ssize_t decode_t4(BitReader &stream, TiffDetails &details, uint8 *pbits, bool bfirstLine); - status_t translate_from_tiff(BPositionIO *inSource, ssize_t amtread, - uint8 *read, swap_action swp, uint32 outType, + status_t translate_from_tiff(BPositionIO *inSource, BMessage *ioExtension, + ssize_t amtread, uint8 *read, swap_action swp, uint32 outType, BPositionIO *outDestination); DecodeTree *fpblackTree; diff --git a/src/add-ons/translators/tifftranslator/TiffIfd.cpp b/src/add-ons/translators/tifftranslator/TiffIfd.cpp index ba879465ca..c2248d40f0 100755 --- a/src/add-ons/translators/tifftranslator/TiffIfd.cpp +++ b/src/add-ons/translators/tifftranslator/TiffIfd.cpp @@ -104,8 +104,8 @@ TiffIfd::LoadFields(uint32 offset, BPositionIO &io, swap_action swp) finitStatus = B_IO_ERROR; return; } - if (swap_data(B_UINT32_TYPE, &nextIFDOffset, 4, swp) != B_OK) { - finitStauts = B_ERROR; + if (swap_data(B_UINT32_TYPE, &fnextIFDOffset, 4, swp) != B_OK) { + finitStatus = B_ERROR; return; } } diff --git a/src/add-ons/translators/tifftranslator/TiffIfdList.cpp b/src/add-ons/translators/tifftranslator/TiffIfdList.cpp new file mode 100644 index 0000000000..d650705e1e --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffIfdList.cpp @@ -0,0 +1,120 @@ +/*****************************************************************************/ +// TiffIfdList +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffIfdList.cpp +// +// This object is for storing all IFD entries from a TIFF file +// +// +// Copyright (c) 2003 OpenBeOS Project +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +/*****************************************************************************/ + +#include "TiffIfdList.h" + +status_t +TiffIfdList::LoadIfds(uint32 offset, BPositionIO &io, swap_action swp) +{ + Empty(); + + TiffIfdNode *pnode = NULL; + while (offset) { + // Create new node at the end of the list + if (!fpfirst) { + fpfirst = new TiffIfdNode; + pnode = fpfirst; + } else { + pnode->pnext = new TiffIfdNode; + pnode = pnode->pnext; + } + if (!pnode) { + finitStatus = B_NO_MEMORY; + break; + } + + // Create new TiffIfd and check its status + pnode->pnext = NULL; + pnode->pifd = new TiffIfd(offset, io, swp); + if (!pnode->pifd) { + finitStatus = B_NO_MEMORY; + break; + } + if (pnode->pifd->InitCheck() != B_OK) { + finitStatus = pnode->pifd->InitCheck(); + break; + } + + offset = pnode->pifd->GetNextIfdOffset(); + fcount++; + } + + if (finitStatus != B_OK) + fcount = 0; + + return finitStatus; +} + +TiffIfdList::TiffIfdList(uint32 offset, BPositionIO &io, swap_action swp) +{ + fpfirst = NULL; + finitStatus = B_OK; + fcount = 0; + + LoadIfds(offset, io, swp); +} + +TiffIfdList::~TiffIfdList() +{ + Empty(); +} + +void +TiffIfdList::Empty() +{ + TiffIfdNode *pnode, *pdelme; + pnode = fpfirst; + + while (pnode) { + pdelme = pnode; + pnode = pnode->pnext; + + delete pdelme->pifd; + delete pdelme; + } + fpfirst = NULL; + fcount = 0; + finitStatus = B_OK; +} + +// index is zero based +TiffIfd * +TiffIfdList::GetIfd(int32 index) +{ + if (index < 0 || index >= fcount) + return NULL; + + TiffIfdNode *pnode = fpfirst; + while (index--) + pnode = pnode->pnext; + + return pnode->pifd; +} + diff --git a/src/add-ons/translators/tifftranslator/TiffIfdList.h b/src/add-ons/translators/tifftranslator/TiffIfdList.h new file mode 100644 index 0000000000..564c71160e --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffIfdList.h @@ -0,0 +1,62 @@ +/*****************************************************************************/ +// TiffIfdList +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffIfdList.h +// +// This object is for storing all IFD entries from a TIFF file +// +// +// Copyright (c) 2003 OpenBeOS Project +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +/*****************************************************************************/ + +#ifndef TIFF_IFD_LIST_H +#define TIFF_IFD_LIST_H + +#include +#include +#include "TiffIfd.h" + +struct TiffIfdNode { + TiffIfd *pifd; + TiffIfdNode *pnext; +}; + +class TiffIfdList { +public: + TiffIfdList(uint32 offset, BPositionIO &io, swap_action swp); + ~TiffIfdList(); + status_t InitCheck() { return finitStatus; }; + + status_t LoadIfds(uint32 offset, BPositionIO &io, swap_action swp); + void Empty(); + + int32 GetCount() { return fcount; }; + TiffIfd *GetIfd(int32 index); + // index is zero based + +private: + status_t finitStatus; + TiffIfdNode *fpfirst; + int32 fcount; +}; + +#endif // #ifndef TIFF_IFD_LIST_H