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

View File

@ -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

View File

@ -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();

View File

@ -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<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++) {
TiffField *pfield;
pfield = fpfields[i];
if (pfield && tag == pfield->GetTag()) {
TiffUintField *puintField = NULL;
puintField = dynamic_cast<TiffUintField *>(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;
}

View File

@ -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;