From 711386ad0efa77cfa6f5c83a6b4b954dcef8b61c Mon Sep 17 00:00:00 2001 From: Matthew Wilber Date: Tue, 1 Apr 2003 05:58:22 +0000 Subject: [PATCH] Changed TiffIfd to use exceptions which makes it much more convenient to work with git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3050 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../tifftranslator/TIFFTranslator.cpp | 100 +++++++++--------- .../tifftranslator/TIFFTranslator.h | 9 ++ .../translators/tifftranslator/TiffIfd.cpp | 94 +++++++++------- .../translators/tifftranslator/TiffIfd.h | 37 ++++++- 4 files changed, 150 insertions(+), 90 deletions(-) diff --git a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp index 422fd6d6ba..1e6fe0b50b 100755 --- a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp +++ b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp @@ -360,46 +360,65 @@ identify_bits_header(BPositionIO *inSource, translator_info *outInfo, // return B_NO_TRANSLATOR, otherwise, // return B_OK status_t -check_tiff_fields(TiffIfd &ifd) +check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails) { - uint32 value; - TiffUintField *pfield = NULL; + TiffDetails details; + memset(&details, 0, sizeof(TiffDetails)); - // Only the default values are supported for the - // following fields - if (ifd.GetUintField(TAG_FILL_ORDER, pfield) == B_OK && - pfield->GetUint(value) == B_OK && - value != 1) - return B_NO_TRANSLATOR; - - if (ifd.GetUintField(TAG_ORIENTATION, pfield) == B_OK && - pfield->GetUint(value) == B_OK && - value != 1) - return B_NO_TRANSLATOR; - - if (ifd.GetUintField(TAG_PLANAR_CONFIGURATION, pfield) == B_OK && - pfield->GetUint(value) == B_OK && - value != 1) - return B_NO_TRANSLATOR; + try { + // Only the default values are supported for the + // following fields. HasField is called so that + // if a field is not present, a TiffIfdFieldNotFoundException + // will not be thrown when GetUint is called. + // (If they are not present, that is fine, but if + // they are present and have a non-default value, + // that is a problem) + if (ifd.HasField(TAG_FILL_ORDER) && + ifd.GetUint(TAG_FILL_ORDER) != 1) + return B_NO_TRANSLATOR; + if (ifd.HasField(TAG_ORIENTATION) && + ifd.GetUint(TAG_ORIENTATION) != 1) + return B_NO_TRANSLATOR; + if (ifd.HasField(TAG_PLANAR_CONFIGURATION) && + ifd.GetUint(TAG_PLANAR_CONFIGURATION) != 1) + return B_NO_TRANSLATOR; + if (ifd.HasField(TAG_SAMPLE_FORMAT) && + ifd.GetUint(TAG_SAMPLE_FORMAT) != 1) + return B_NO_TRANSLATOR; + + // Copy fields useful to TIFFTranslator + details.width = ifd.GetUint(TAG_IMAGE_WIDTH); + details.height = ifd.GetUint(TAG_IMAGE_HEIGHT); + details.compression = ifd.GetUint(TAG_COMPRESSION); + details.interpretation = ifd.GetUint(TAG_PHOTO_INTERPRETATION); - if (ifd.GetUintField(TAG_SAMPLE_FORMAT, pfield) == B_OK && - pfield->GetUint(value) == B_OK && - value != 1) - return B_NO_TRANSLATOR; + printf("width: %d\nheight: %d\ncompression: %d\ninterpretation: %d\n", + details.width, details.height, details.compression, + details.interpretation); + + // Currently, only uncompressed, non-tile RGB + // images are supported + if (details.compression != COMPRESSION_NONE) + return B_NO_TRANSLATOR; + if (details.interpretation != PHOTO_RGB) + return B_NO_TRANSLATOR; - // Only uncompressed images are supported - if (ifd.GetUintField(TAG_COMPRESSION, pfield) != B_OK) + // return read in details if output + // pointer is supplied + if (pdetails) + memcpy(pdetails, &details, sizeof(TiffDetails)); + + } catch (TiffIfdException) { + printf("-- Caught TiffIfdException --\n"); return B_NO_TRANSLATOR; - if (pfield->GetUint(value) != B_OK) - return B_NO_TRANSLATOR; - + } return B_OK; } status_t identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, - ssize_t amtread, uint8 *read, swap_action swp) + ssize_t amtread, uint8 *read, swap_action swp, TiffDetails *pdetails = NULL) { if (amtread != 4) return B_ERROR; @@ -425,26 +444,9 @@ identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, // Read in some fields in order to determine whether or not // this particular TIFF image is supported by this translator - // Get some stats and print them out - if (initcheck == B_OK) { - uint32 value; - TiffUintField *pfield = NULL; - - if (ifd.GetUintField(TAG_IMAGE_WIDTH, pfield) == B_OK) { - if (pfield->GetUint(value) == B_OK) - printf("image width: %d\n", value); - } - if (ifd.GetUintField(TAG_IMAGE_HEIGHT, pfield) == B_OK) { - if (pfield->GetUint(value) == B_OK) - printf("image height: %d\n", value); - } - if (ifd.GetUintField(TAG_COMPRESSION, pfield) == B_OK) { - if (pfield->GetUint(value) == B_OK) - printf("compression: %d\n", value); - } - - return check_tiff_fields(ifd); - } + // Check the required fields + if (initcheck == B_OK) + return check_tiff_fields(ifd, pdetails); if (initcheck != B_OK && initcheck != B_ERROR && initcheck != B_NO_MEMORY) // return B_NO_TRANSLATOR if unexpected data was encountered diff --git a/src/add-ons/translators/tifftranslator/TIFFTranslator.h b/src/add-ons/translators/tifftranslator/TIFFTranslator.h index 1419d3cda5..4c5b9fed99 100755 --- a/src/add-ons/translators/tifftranslator/TIFFTranslator.h +++ b/src/add-ons/translators/tifftranslator/TIFFTranslator.h @@ -54,6 +54,15 @@ #define BBT_OUT_QUALITY 0.4 #define BBT_OUT_CAPABILITY 0.6 +// structure for storing only the TIFF fields +// that are of interest to the TIFFTranslator +struct TiffDetails { + uint32 width; + uint32 height; + uint32 compression; + uint16 interpretation; +}; + class TIFFTranslator : public BTranslator { public: TIFFTranslator(); diff --git a/src/add-ons/translators/tifftranslator/TiffIfd.cpp b/src/add-ons/translators/tifftranslator/TiffIfd.cpp index de60602239..223d98fafc 100755 --- a/src/add-ons/translators/tifftranslator/TiffIfd.cpp +++ b/src/add-ons/translators/tifftranslator/TiffIfd.cpp @@ -129,48 +129,66 @@ TiffIfd::~TiffIfd() fnextIFDOffset = 0; } -// --------------------------------------------------------------- -// GetUintField -// -// Retrieves the TiffUintField with the given tag. -// -// Preconditions: -// -// Parameters: tag, the field id tag -// -// poutField, the pointer to the desired field -// is stored here -// -// Postconditions: -// -// Returns: B_OK if the field was found and it is a TiffUintField -// based object, -// -// B_BAD_TYPE if the field was found BUT it was not a -// TiffUintField based object -// -// B_BAD_INDEX if a field with the given tag -// was not found -// --------------------------------------------------------------- -status_t -TiffIfd::GetUintField(uint16 tag, TiffUintField *&poutField) +bool +TiffIfd::HasField(uint16 tag) +{ + TiffField *pfield = GetField(tag); + if (pfield) + return true; + else + return false; +} + +uint32 +TiffIfd::GetCount(uint16 tag) +{ + TiffField *pfield = GetField(tag); + if (pfield) + return pfield->GetCount(); + else + throw TiffIfdFieldNotFoundException(); +} + +uint32 +TiffIfd::GetUint(uint16 tag, uint32 index) +{ + TiffField *pfield = GetField(tag); + if (pfield) { + + TiffUintField *puintField = NULL; + puintField = dynamic_cast(pfield); + if (puintField) { + + uint32 num; + status_t ret = puintField->GetUint(num, index); + if (ret == B_OK) + return num; + else if (ret == B_BAD_INDEX) + throw TiffIfdBadIndexException(); + else + throw TiffIfdUnexpectedTypeException(); + + } else + throw TiffIfdUnexpectedTypeException(); + } + + throw TiffIfdFieldNotFoundException(); +} + +TiffField * +TiffIfd::GetField(uint16 tag) { for (uint16 i = 0; i < ffieldCount; i++) { - TiffField *pfield; - - pfield = fpfields[i]; - if (pfield && tag == pfield->GetTag()) { - TiffUintField *puintField = NULL; - - puintField = dynamic_cast(pfield); - if (puintField) { - poutField = puintField; - return B_OK; - } else - return B_BAD_TYPE; + TiffField *pfield = fpfields[i]; + if (pfield) { + uint16 ltag = pfield->GetTag(); + if (tag == ltag) + return pfield; + else if (ltag > tag) + break; } } - return B_BAD_INDEX; + return NULL; } diff --git a/src/add-ons/translators/tifftranslator/TiffIfd.h b/src/add-ons/translators/tifftranslator/TiffIfd.h index 5f32bab84b..345f6ee23f 100755 --- a/src/add-ons/translators/tifftranslator/TiffIfd.h +++ b/src/add-ons/translators/tifftranslator/TiffIfd.h @@ -36,16 +36,47 @@ #include "TiffField.h" #include "TiffUintField.h" +class TiffIfdException { +public: + TiffIfdException() { }; +}; +class TiffIfdFieldNotFoundException : public TiffIfdException { +public: + TiffIfdFieldNotFoundException() { }; +}; +class TiffIfdUnexpectedTypeException : public TiffIfdException { +public: + TiffIfdUnexpectedTypeException() { }; +}; +class TiffIfdBadIndexException : public TiffIfdException { +public: + TiffIfdBadIndexException() { }; +}; + class TiffIfd { public: TiffIfd(uint32 offset, BPositionIO &io, swap_action swp); - ~TiffIfd(); - + ~TiffIfd(); status_t InitCheck() { return finitStatus; }; - status_t GetUintField(uint16 tag, TiffUintField *&poutField); + + bool HasField(uint16 tag); + uint32 GetCount(uint16 tag); + // throws: TiffIfdFieldNotFoundException() + + uint32 GetUint(uint16 tag, uint32 index = 0); + // index is the base one index for the desired + // number in the specified field. When index is the default + // value of zero: if the count is one, the + // first number will be returned, if it is not + // one, TiffIfdBadIndexException() will be thrown + // + // throws: TiffIfdFieldNotFoundException(), + // TiffIfdUnexpectedTypeException(), + // TiffIfdBadIndexException() private: void LoadFields(uint32 offset, BPositionIO &io, swap_action swp); + TiffField *GetField(uint16 tag); TiffField **fpfields; status_t finitStatus;