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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user