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
This commit is contained in:
Matthew Wilber
2003-04-01 05:58:22 +00:00
parent 552edc59bd
commit 711386ad0e
4 changed files with 150 additions and 90 deletions
@@ -360,46 +360,65 @@ identify_bits_header(BPositionIO *inSource, translator_info *outInfo,
// return B_NO_TRANSLATOR, otherwise, // return B_NO_TRANSLATOR, otherwise,
// return B_OK // return B_OK
status_t status_t
check_tiff_fields(TiffIfd &ifd) check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails)
{ {
uint32 value; TiffDetails details;
TiffUintField *pfield = NULL; memset(&details, 0, sizeof(TiffDetails));
// Only the default values are supported for the try {
// following fields // Only the default values are supported for the
if (ifd.GetUintField(TAG_FILL_ORDER, pfield) == B_OK && // following fields. HasField is called so that
pfield->GetUint(value) == B_OK && // if a field is not present, a TiffIfdFieldNotFoundException
value != 1) // will not be thrown when GetUint is called.
return B_NO_TRANSLATOR; // (If they are not present, that is fine, but if
// they are present and have a non-default value,
if (ifd.GetUintField(TAG_ORIENTATION, pfield) == B_OK && // that is a problem)
pfield->GetUint(value) == B_OK && if (ifd.HasField(TAG_FILL_ORDER) &&
value != 1) ifd.GetUint(TAG_FILL_ORDER) != 1)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
if (ifd.HasField(TAG_ORIENTATION) &&
if (ifd.GetUintField(TAG_PLANAR_CONFIGURATION, pfield) == B_OK && ifd.GetUint(TAG_ORIENTATION) != 1)
pfield->GetUint(value) == B_OK && return B_NO_TRANSLATOR;
value != 1) if (ifd.HasField(TAG_PLANAR_CONFIGURATION) &&
return B_NO_TRANSLATOR; 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 && printf("width: %d\nheight: %d\ncompression: %d\ninterpretation: %d\n",
pfield->GetUint(value) == B_OK && details.width, details.height, details.compression,
value != 1) details.interpretation);
return B_NO_TRANSLATOR;
// 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 // return read in details if output
if (ifd.GetUintField(TAG_COMPRESSION, pfield) != B_OK) // pointer is supplied
if (pdetails)
memcpy(pdetails, &details, sizeof(TiffDetails));
} catch (TiffIfdException) {
printf("-- Caught TiffIfdException --\n");
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
if (pfield->GetUint(value) != B_OK) }
return B_NO_TRANSLATOR;
return B_OK; return B_OK;
} }
status_t status_t
identify_tiff_header(BPositionIO *inSource, translator_info *outInfo, 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) if (amtread != 4)
return B_ERROR; 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 // Read in some fields in order to determine whether or not
// this particular TIFF image is supported by this translator // this particular TIFF image is supported by this translator
// Get some stats and print them out // Check the required fields
if (initcheck == B_OK) { if (initcheck == B_OK)
uint32 value; return check_tiff_fields(ifd, pdetails);
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);
}
if (initcheck != B_OK && initcheck != B_ERROR && initcheck != B_NO_MEMORY) if (initcheck != B_OK && initcheck != B_ERROR && initcheck != B_NO_MEMORY)
// return B_NO_TRANSLATOR if unexpected data was encountered // return B_NO_TRANSLATOR if unexpected data was encountered
@@ -54,6 +54,15 @@
#define BBT_OUT_QUALITY 0.4 #define BBT_OUT_QUALITY 0.4
#define BBT_OUT_CAPABILITY 0.6 #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 { class TIFFTranslator : public BTranslator {
public: public:
TIFFTranslator(); TIFFTranslator();
@@ -129,48 +129,66 @@ TiffIfd::~TiffIfd()
fnextIFDOffset = 0; fnextIFDOffset = 0;
} }
// --------------------------------------------------------------- bool
// GetUintField TiffIfd::HasField(uint16 tag)
// {
// Retrieves the TiffUintField with the given tag. TiffField *pfield = GetField(tag);
// if (pfield)
// Preconditions: return true;
// else
// Parameters: tag, the field id tag return false;
// }
// poutField, the pointer to the desired field
// is stored here uint32
// TiffIfd::GetCount(uint16 tag)
// Postconditions: {
// TiffField *pfield = GetField(tag);
// Returns: B_OK if the field was found and it is a TiffUintField if (pfield)
// based object, return pfield->GetCount();
// else
// B_BAD_TYPE if the field was found BUT it was not a throw TiffIfdFieldNotFoundException();
// TiffUintField based object }
//
// B_BAD_INDEX if a field with the given tag uint32
// was not found TiffIfd::GetUint(uint16 tag, uint32 index)
// --------------------------------------------------------------- {
status_t TiffField *pfield = GetField(tag);
TiffIfd::GetUintField(uint16 tag, TiffUintField *&poutField) if (pfield) {
TiffUintField *puintField = NULL;
puintField = dynamic_cast<TiffUintField *>(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++) { for (uint16 i = 0; i < ffieldCount; i++) {
TiffField *pfield; TiffField *pfield = fpfields[i];
if (pfield) {
pfield = fpfields[i]; uint16 ltag = pfield->GetTag();
if (pfield && tag == pfield->GetTag()) { if (tag == ltag)
TiffUintField *puintField = NULL; return pfield;
else if (ltag > tag)
puintField = dynamic_cast<TiffUintField *>(pfield); break;
if (puintField) {
poutField = puintField;
return B_OK;
} else
return B_BAD_TYPE;
} }
} }
return B_BAD_INDEX; return NULL;
} }
@@ -36,16 +36,47 @@
#include "TiffField.h" #include "TiffField.h"
#include "TiffUintField.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 { class TiffIfd {
public: public:
TiffIfd(uint32 offset, BPositionIO &io, swap_action swp); TiffIfd(uint32 offset, BPositionIO &io, swap_action swp);
~TiffIfd(); ~TiffIfd();
status_t InitCheck() { return finitStatus; }; 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: private:
void LoadFields(uint32 offset, BPositionIO &io, swap_action swp); void LoadFields(uint32 offset, BPositionIO &io, swap_action swp);
TiffField *GetField(uint16 tag);
TiffField **fpfields; TiffField **fpfields;
status_t finitStatus; status_t finitStatus;