diff --git a/src/add-ons/translators/tifftranslator/Jamfile b/src/add-ons/translators/tifftranslator/Jamfile index f324bfeba4..6ba8bb9338 100755 --- a/src/add-ons/translators/tifftranslator/Jamfile +++ b/src/add-ons/translators/tifftranslator/Jamfile @@ -1,5 +1,13 @@ SubDir OBOS_TOP src add-ons translators tifftranslator ; -Translator TIFFTranslator : TIFFMain.cpp TIFFTranslator.cpp TIFFView.cpp TIFFWindow.cpp ; +Translator TIFFTranslator : + TiffField.cpp + TiffUintField.cpp + TiffUnknownField.cpp + TiffIfd.cpp + TIFFMain.cpp + TIFFTranslator.cpp + TIFFView.cpp + TIFFWindow.cpp ; LinkSharedOSLibs TIFFTranslator : be translation ; diff --git a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp index c8fab820c8..422fd6d6ba 100755 --- a/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp +++ b/src/add-ons/translators/tifftranslator/TIFFTranslator.cpp @@ -33,6 +33,7 @@ #include #include "TIFFTranslator.h" #include "TIFFView.h" +#include "TiffIfd.h" // The input formats that this translator supports. translation_format gInputFormats[] = { @@ -258,6 +259,201 @@ TIFFTranslator::OutputFormats(int32 *out_count) const return NULL; } +// --------------------------------------------------------------- +// identify_bits_header +// +// Determines if the data in inSource is in the +// B_TRANSLATOR_BITMAP ('bits') format. If it is, it returns +// info about the data in inSource to outInfo and pheader. +// +// Preconditions: +// +// Parameters: inSource, The source of the image data +// +// outInfo, Information about the translator +// is copied here +// +// amtread, Amount of data read from inSource +// before this function was called +// +// read, Pointer to the data that was read +// in before this function was called +// +// pheader, The bits header is copied here after +// it is read in from inSource +// +// Postconditions: +// +// Returns: B_NO_TRANSLATOR, if the data does not look like +// bits format data +// +// B_ERROR, if the header data could not be converted to host +// format +// +// B_OK, if the data looks like bits data and no errors were +// encountered +// --------------------------------------------------------------- +status_t +identify_bits_header(BPositionIO *inSource, translator_info *outInfo, + ssize_t amtread, uint8 *read, TranslatorBitmap *pheader = NULL) +{ + TranslatorBitmap header; + + memcpy(&header, read, amtread); + // copy portion of header already read in + // read in the rest of the header + ssize_t size = sizeof(TranslatorBitmap) - amtread; + if (inSource->Read( + (reinterpret_cast (&header)) + amtread, size) != size) + return B_NO_TRANSLATOR; + + // convert to host byte order + if (swap_data(B_UINT32_TYPE, &header, sizeof(TranslatorBitmap), + B_SWAP_BENDIAN_TO_HOST) != B_OK) + return B_ERROR; + + // check if header values are reasonable + if (header.colors != B_RGB32 && + header.colors != B_RGB32_BIG && + header.colors != B_RGBA32 && + header.colors != B_RGBA32_BIG && + header.colors != B_RGB24 && + header.colors != B_RGB24_BIG && + header.colors != B_RGB16 && + header.colors != B_RGB16_BIG && + header.colors != B_RGB15 && + header.colors != B_RGB15_BIG && + header.colors != B_RGBA15 && + header.colors != B_RGBA15_BIG && + header.colors != B_CMAP8 && + header.colors != B_GRAY8 && + header.colors != B_GRAY1 && + header.colors != B_CMYK32 && + header.colors != B_CMY32 && + header.colors != B_CMYA32 && + header.colors != B_CMY24) + return B_NO_TRANSLATOR; + if (header.rowBytes * (header.bounds.Height() + 1) != header.dataSize) + return B_NO_TRANSLATOR; + + if (outInfo) { + outInfo->type = B_TRANSLATOR_BITMAP; + outInfo->group = B_TRANSLATOR_BITMAP; + outInfo->quality = BBT_IN_QUALITY; + outInfo->capability = BBT_IN_CAPABILITY; + strcpy(outInfo->name, "Be Bitmap Format (TGATranslator)"); + strcpy(outInfo->MIME, "image/x-be-bitmap"); + } + + if (pheader) { + pheader->magic = header.magic; + pheader->bounds = header.bounds; + pheader->rowBytes = header.rowBytes; + pheader->colors = header.colors; + pheader->dataSize = header.dataSize; + } + + return B_OK; +} + +// If this TIFF has unsupported features, +// return B_NO_TRANSLATOR, otherwise, +// return B_OK +status_t +check_tiff_fields(TiffIfd &ifd) +{ + uint32 value; + TiffUintField *pfield = NULL; + + // 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; + + if (ifd.GetUintField(TAG_SAMPLE_FORMAT, pfield) == B_OK && + pfield->GetUint(value) == B_OK && + value != 1) + return B_NO_TRANSLATOR; + + // Only uncompressed images are supported + if (ifd.GetUintField(TAG_COMPRESSION, pfield) != B_OK) + 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) +{ + if (amtread != 4) + return B_ERROR; + + uint32 firstIFDOffset = 0; + ssize_t nread = inSource->Read(&firstIFDOffset, 4); + if (nread != 4) { + printf("Unable to read first IFD offset\n"); + return B_NO_TRANSLATOR; + } + if (swap_data(B_UINT32_TYPE, &firstIFDOffset, sizeof(uint32), swp) != B_OK) { + printf("swap_data() error\n"); + return B_ERROR; + } + printf("First IFD: 0x%.8lx\n", firstIFDOffset); + TiffIfd ifd(firstIFDOffset, *inSource, swp); + + status_t initcheck; + initcheck = ifd.InitCheck(); + printf("Init Check: %d\n", + static_cast(initcheck)); + + // 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); + } + + if (initcheck != B_OK && initcheck != B_ERROR && initcheck != B_NO_MEMORY) + // return B_NO_TRANSLATOR if unexpected data was encountered + return B_NO_TRANSLATOR; + else + // return B_OK, B_ERROR or B_NO_MEMORY + return initcheck; +} + // --------------------------------------------------------------- // Identify // @@ -306,9 +502,65 @@ TIFFTranslator::Identify(BPositionIO *inSource, outType = B_TRANSLATOR_BITMAP; if (outType != B_TRANSLATOR_BITMAP && outType != B_TIFF_FORMAT) return B_NO_TRANSLATOR; - - return B_NO_TRANSLATOR; - // translator isn't implemented yet + + // Convert the magic numbers to the various byte orders so that + // I won't have to convert the data read in to see whether or not + // it is a supported type + uint32 nbits = B_TRANSLATOR_BITMAP; + if (swap_data(B_UINT32_TYPE, &nbits, sizeof(uint32), + B_SWAP_HOST_TO_BENDIAN) != B_OK) + return B_ERROR; + + // Read in the magic number and determine if it + // is a supported type + uint8 ch[4]; + inSource->Seek(0, SEEK_SET); + if (inSource->Read(ch, 4) != 4) + return B_NO_TRANSLATOR; + + // Read settings from ioExtension + bool bheaderonly = false, bdataonly = false; + if (ioExtension) { + if (ioExtension->FindBool(B_TRANSLATOR_EXT_HEADER_ONLY, &bheaderonly)) + // if failed, make sure bool is default value + bheaderonly = false; + if (ioExtension->FindBool(B_TRANSLATOR_EXT_DATA_ONLY, &bdataonly)) + // if failed, make sure bool is default value + bdataonly = false; + + if (bheaderonly && bdataonly) + // can't both "only write the header" and "only write the data" + // at the same time + return B_BAD_VALUE; + } + + uint32 n32ch; + memcpy(&n32ch, ch, sizeof(uint32)); + // if B_TRANSLATOR_BITMAP type + if (n32ch == nbits) + return identify_bits_header(inSource, outInfo, 4, ch); + + // Might be TIFF image + else { + // TIFF Byte Order / Magic + const uint8 kleSig[] = { 0x49, 0x49, 0x2a, 0x00 }; + const uint8 kbeSig[] = { 0x4d, 0x4d, 0x00, 0x2a }; + + swap_action swp; + if (memcmp(ch, kleSig, 4) == 0) { + swp = B_SWAP_LENDIAN_TO_HOST; + printf("Byte Order: little endian\n"); + } else if (memcmp(ch, kbeSig, 4) == 0) { + swp = B_SWAP_BENDIAN_TO_HOST; + printf("Byte Order: big endian\n"); + } else { + // If not a TIFF or a Be Bitmap image + printf("Invalid byte order value\n"); + return B_NO_TRANSLATOR; + } + + return identify_tiff_header(inSource, outInfo, 4, ch, swp); + } } // --------------------------------------------------------------- @@ -375,7 +627,9 @@ TIFFTranslator::Translate(BPositionIO *inSource, // // Postconditions: // -// Returns: +// Returns: B_BAD_VALUE if outView or outExtent is NULL, +// B_NO_MEMORY if the view couldn't be allocated, +// B_OK if no errors // --------------------------------------------------------------- status_t TIFFTranslator::MakeConfigurationView(BMessage *ioExtension, BView **outView, @@ -386,6 +640,9 @@ TIFFTranslator::MakeConfigurationView(BMessage *ioExtension, BView **outView, TIFFView *view = new TIFFView(BRect(0, 0, 225, 175), "TIFFTranslator Settings", B_FOLLOW_ALL, B_WILL_DRAW); + if (!view) + return B_NO_MEMORY; + *outView = view; *outExtent = view->Bounds(); diff --git a/src/add-ons/translators/tifftranslator/TIFFWindow.h b/src/add-ons/translators/tifftranslator/TIFFWindow.h index b7258d2b98..f4652f0070 100755 --- a/src/add-ons/translators/tifftranslator/TIFFWindow.h +++ b/src/add-ons/translators/tifftranslator/TIFFWindow.h @@ -45,4 +45,4 @@ public: // Posts a quit message so that the application closes properly }; -#endif +#endif // #define TIFFWINDOW_H diff --git a/src/add-ons/translators/tifftranslator/TiffField.cpp b/src/add-ons/translators/tifftranslator/TiffField.cpp new file mode 100755 index 0000000000..3f43b4949e --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffField.cpp @@ -0,0 +1,48 @@ +/*****************************************************************************/ +// TiffField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffField.cpp +// +// This object is for storing TIFF fields +// +// +// 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 +#include +#include "TiffField.h" + +TiffField::TiffField(IFDEntry &entry) +{ + finitStatus = B_ERROR; + // responsibility of derived class to set this properly + + ftag = entry.tag; + ffieldType = entry.fieldType; + fcount = entry.count; + + printf("TiffField::ftag: %d\n", ftag); + printf("TiffField::ffieldType: %d\n", ffieldType); + printf("TiffField::fcount: %d\n", + static_cast(fcount)); +} diff --git a/src/add-ons/translators/tifftranslator/TiffField.h b/src/add-ons/translators/tifftranslator/TiffField.h new file mode 100755 index 0000000000..f24b58b02b --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffField.h @@ -0,0 +1,128 @@ +/*****************************************************************************/ +// TiffField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffField.h +// +// This object is for storing TIFF fields +// +// +// 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_FIELD_H +#define TIFF_FIELD_H + +#include + +// TIFF field id numbers for fields that the +// TIFFTranslator needs to know about / use +// (not a complete list of all tags) +#define TAG_NEW_SUBFILE_TYPE 254 + #define NEW_SUBFILE_TYPE_REDUCED 1 + #define NEW_SUBFILE_TYPE_PAGE 2 + #define NEW_SUBFILE_TYPE_MASK 4 +#define TAG_SUBFILE_TYPE 255 + #define SUBFILE_TYPE_FULL 1 + #define SUBFILE_TYPE_REDUCED 2 + #define SUBFILE_TYPE_PAGE 3 +#define TAG_IMAGE_WIDTH 256 +#define TAG_IMAGE_HEIGHT 257 +#define TAG_BITS_PER_SAMPLE 258 +#define TAG_COMPRESSION 259 + #define COMPRESSION_NONE 1 + #define COMPRESSION_HUFFMAN 2 + #define COMPRESSION_T4 3 + #define COMPRESSION_T6 4 + #define COMPRESSION_LZW 5 + #define COMPRESSION_PACKBITS 32773 +#define TAG_PHOTO_INTERPRETATION 262 + #define PHOTO_WHITEZERO 0 + #define PHOTO_BLACKZERO 1 + #define PHOTO_RGB 2 + #define PHOTO_PALETTE 3 + #define PHOTO_MASK 4 +#define TAG_FILL_ORDER 266 +#define TAG_STRIP_OFFSETS 273 +#define TAG_ORIENTATION 274 +#define TAG_SAMPLES_PER_PIXEL 277 +#define TAG_ROWS_PER_STRIP 278 +#define TAG_STRIP_BYTE_COUNTS 279 +#define TAG_PLANAR_CONFIGURATION 284 +#define TAG_RESOLUTION_UNIT 296 +#define TAG_COLOR_MAP 320 +#define TAG_EXTRA_SAMPLES 338 +#define TAG_SAMPLE_FORMAT 339 + +// Some types of data that can +// exist in a TIFF field +enum TIFF_ENTRY_TYPE { + TIFF_BYTE = 1, + TIFF_ASCII, + TIFF_SHORT, + TIFF_LONG, + TIFF_RATIONAL, + TIFF_SBYTE, + TIFF_UNDEFINED, + TIFF_SSHORT, + TIFF_SRATIONAL, + TIFF_FLOAT, + TIFF_DOUBLE +}; + +struct IFDEntry { + uint16 tag; + // uniquely identifies the field + uint16 fieldType; + // number, string, float, etc. + uint32 count; + // length / number of values + + // The actual value or the file offset + // where the actual value is located + union { + float floatval; + uint32 longval; + uint16 shortvals[2]; + uint8 bytevals[4]; + }; +}; + +class TiffField { +public: + TiffField(IFDEntry &entry); + virtual ~TiffField() {}; + + status_t InitCheck() { return finitStatus; }; + uint16 GetTag() { return ftag; }; + uint16 GetType() { return ffieldType; }; + uint32 GetCount() { return fcount; }; + +protected: + status_t finitStatus; + +private: + uint16 ftag; + uint16 ffieldType; + uint32 fcount; +}; + +#endif // #define TIFF_FIELD_H diff --git a/src/add-ons/translators/tifftranslator/TiffIfd.cpp b/src/add-ons/translators/tifftranslator/TiffIfd.cpp new file mode 100755 index 0000000000..de60602239 --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffIfd.cpp @@ -0,0 +1,176 @@ +/*****************************************************************************/ +// TiffIfd +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffIfd.cpp +// +// This object is for storing a TIFF Image File Directory +// +// +// 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 +#include +#include "TiffIfd.h" +#include "TiffUintField.h" +#include "TiffUnknownField.h" + +void +TiffIfd::LoadFields(uint32 offset, BPositionIO &io, swap_action swp) +{ + if (io.ReadAt(offset, &ffieldCount, 2) != 2) { + finitStatus = B_IO_ERROR; + return; + } else { + if (swap_data(B_UINT16_TYPE, &ffieldCount, 2, swp) != B_OK) { + finitStatus = B_ERROR; + return; + } else { + printf("TiffIfd::ffieldCount: %d\n", ffieldCount); + + fpfields = new TiffField *[ffieldCount]; + if (!fpfields) { + finitStatus = B_NO_MEMORY; + return; + } else { + memset(fpfields, 0, ffieldCount * sizeof(TiffField *)); + // set all pointers to TiffFields to NULL + + // Load TIFF IFD Entries + offset += 2; + uint16 i; + finitStatus = B_OK; + for (i = 0; i < ffieldCount; i++, offset += 12) { + IFDEntry entry; + + if (io.ReadAt(offset, &entry, 12) != 12) { + finitStatus = B_IO_ERROR; + return; + } + if (swap_data(B_UINT16_TYPE, &entry.tag, 2, swp) != B_OK) { + finitStatus = B_ERROR; + return; + } + if (swap_data(B_UINT16_TYPE, &entry.fieldType, 2, swp) != B_OK) { + finitStatus = B_ERROR; + return; + } + if (swap_data(B_UINT32_TYPE, &entry.count, 4, swp) != B_OK) { + finitStatus = B_ERROR; + return; + } + + // Create a TiffField based object to store the + // TIFF entry + switch (entry.fieldType) { + case TIFF_BYTE: + case TIFF_SHORT: + case TIFF_LONG: + fpfields[i] = new TiffUintField(entry, io, swp); + break; + + default: + fpfields[i] = new TiffUnknownField(entry); + break; + } + if (!fpfields[i]) { + finitStatus = B_NO_MEMORY; + return; + } + if (fpfields[i]->InitCheck() != B_OK) { + finitStatus = fpfields[i]->InitCheck(); + return; + } + } + } + } + } +} + +TiffIfd::TiffIfd(uint32 offset, BPositionIO &io, swap_action swp) +{ + fpfields = NULL; + finitStatus = B_ERROR; + fnextIFDOffset = 0; + ffieldCount = 0; + + LoadFields(offset, io, swp); +} + +TiffIfd::~TiffIfd() +{ + for (uint16 i = 0; i < ffieldCount; i++) { + delete fpfields[i]; + fpfields[i] = NULL; + } + delete[] fpfields; + fpfields = NULL; + + ffieldCount = 0; + 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) +{ + 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; + } + } + + return B_BAD_INDEX; +} + diff --git a/src/add-ons/translators/tifftranslator/TiffIfd.h b/src/add-ons/translators/tifftranslator/TiffIfd.h new file mode 100755 index 0000000000..5f32bab84b --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffIfd.h @@ -0,0 +1,56 @@ +/*****************************************************************************/ +// TiffIfd +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffIfd.h +// +// This object is for storing a TIFF Image File Directory +// +// +// 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_H +#define TIFF_IFD_H + +#include +#include +#include "TiffField.h" +#include "TiffUintField.h" + +class TiffIfd { +public: + TiffIfd(uint32 offset, BPositionIO &io, swap_action swp); + ~TiffIfd(); + + status_t InitCheck() { return finitStatus; }; + status_t GetUintField(uint16 tag, TiffUintField *&poutField); + +private: + void LoadFields(uint32 offset, BPositionIO &io, swap_action swp); + + TiffField **fpfields; + status_t finitStatus; + uint32 fnextIFDOffset; + uint16 ffieldCount; +}; + +#endif // TIFF_IFD_H diff --git a/src/add-ons/translators/tifftranslator/TiffUintField.cpp b/src/add-ons/translators/tifftranslator/TiffUintField.cpp new file mode 100755 index 0000000000..66439a87b7 --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffUintField.cpp @@ -0,0 +1,274 @@ +/*****************************************************************************/ +// TiffUintField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffUintField.cpp +// +// This object is for storing Unsigned Integer TIFF fields +// +// +// 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 +#include +#include "TiffUintField.h" + +void +TiffUintField::LoadByte(IFDEntry &entry, BPositionIO &io, swap_action swp) +{ + // Make certain there is enough memory + // before trying to do anything else + fpByte = new uint8[entry.count]; + if (!fpByte) { + finitStatus = B_NO_MEMORY; + return; + } + + if (entry.count <= 4) { + // If all of the byte values can fit into the + // IFD entry value bytes + memcpy(fpByte, entry.bytevals, entry.count); + finitStatus = B_OK; + } else { + + // entry.count > 4, use longval to find offset for byte data + if (swap_data(B_UINT32_TYPE, &entry.longval, 4, swp) != B_OK) + finitStatus = B_ERROR; + else { + ssize_t read; + read = io.ReadAt(entry.longval, fpByte, entry.count); + if (read != static_cast(entry.count)) + finitStatus = B_IO_ERROR; + else + finitStatus = B_OK; + } + + } +} + +void +TiffUintField::LoadShort(IFDEntry &entry, BPositionIO &io, swap_action swp) +{ + // Make certain there is enough memory + // before trying to do anything else + fpShort = new uint16[entry.count]; + if (!fpShort) { + finitStatus = B_NO_MEMORY; + return; + } + + if (entry.count <= 2) { + // If all of the byte values can fit into the + // IFD entry value bytes + memcpy(fpShort, entry.shortvals, entry.count * 2); + finitStatus = B_OK; + } else { + + // entry.count > 2, use longval to find offset for short data + if (swap_data(B_UINT32_TYPE, &entry.longval, 4, swp) != B_OK) + finitStatus = B_ERROR; + else { + ssize_t read; + read = io.ReadAt(entry.longval, fpShort, entry.count * 2); + if (read != static_cast(entry.count) * 2) + finitStatus = B_IO_ERROR; + else + finitStatus = B_OK; + } + + } + + // If short values were successfully read in, swap them to + // the correct byte order + if (finitStatus == B_OK && + swap_data(B_UINT16_TYPE, fpShort, entry.count * 2, swp) != B_OK) + finitStatus = B_ERROR; +} + +void +TiffUintField::LoadLong(IFDEntry &entry, BPositionIO &io, swap_action swp) +{ + // Make certain there is enough memory + // before trying to do anything else + fpLong = new uint32[entry.count]; + if (!fpLong) { + finitStatus = B_NO_MEMORY; + return; + } + + if (entry.count == 1) { + fpLong[0] = entry.longval; + finitStatus = B_OK; + } else { + + // entry.count > 1, use longval to find offset for long data + if (swap_data(B_UINT32_TYPE, &entry.longval, 4, swp) != B_OK) + finitStatus = B_ERROR; + else { + ssize_t read; + read = io.ReadAt(entry.longval, fpLong, entry.count * 4); + if (read != static_cast(entry.count) * 4) + finitStatus = B_IO_ERROR; + else + finitStatus = B_OK; + } + + } + + // If long values were successfully read in, swap them to + // the correct byte order + if (finitStatus == B_OK && + swap_data(B_UINT32_TYPE, fpLong, entry.count * 4, swp) != B_OK) + finitStatus = B_ERROR; +} + +TiffUintField::TiffUintField(IFDEntry &entry, BPositionIO &io, swap_action swp) + : TiffField(entry) +{ + if (entry.count > 0) { + switch (entry.fieldType) { + case TIFF_BYTE: + fpByte = NULL; + LoadByte(entry, io, swp); + break; + + case TIFF_SHORT: + fpShort = NULL; + LoadShort(entry, io, swp); + break; + + case TIFF_LONG: + fpLong = NULL; + LoadLong(entry, io, swp); + break; + + default: + finitStatus = B_BAD_TYPE; + break; + } + } else + finitStatus = B_BAD_VALUE; + + printf("TiffUintField::finitStatus: %d\n", + static_cast(finitStatus)); + + // print out numbers stored by this field + if (finitStatus == B_OK) { + uint32 count = GetCount(), out = 0; + printf("TiffUintField::value: "); + for (uint32 i = 1; i && i <= count; i++) { + GetUint(out, i); + if (i > 1) + printf(", "); + printf("%d", static_cast(out)); + } + printf("\n"); + } +} + +TiffUintField::~TiffUintField() +{ + switch (GetType()) { + case TIFF_BYTE: + delete[] fpByte; + fpByte = NULL; + break; + case TIFF_SHORT: + delete[] fpShort; + fpShort = NULL; + break; + case TIFF_LONG: + delete[] fpLong; + fpLong = NULL; + break; + + default: + // if invalid type, should have never + // allocated any value, so there should + // be no value to delete + break; + } +} + +// --------------------------------------------------------------- +// GetUint +// +// Retrieves the number at the given index for this field. +// Some fields store a single number, others store an array of +// numbers. +// +// The index parameter has a default value of zero. When +// index is zero, there is special behavior: the first +// number is retrieved if this field has a count of 1. If +// the index is zero and the field's count is not 1, then +// B_BAD_INDEX will be returned. +// +// Preconditions: +// +// Parameters: out, where the desired uint is copied to +// +// index, one-based index for the desired value +// +// 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 +TiffUintField::GetUint(uint32 &out, uint32 index) +{ + if (finitStatus != B_OK) + return finitStatus; + + uint32 count = GetCount(); + if (index > count || (index == 0 && count != 1)) + return B_BAD_INDEX; + + status_t result = B_OK; + if (!index) + index = 1; + switch (GetType()) { + case TIFF_BYTE: + out = fpByte[index - 1]; + break; + + case TIFF_SHORT: + out = fpShort[index - 1]; + break; + + case TIFF_LONG: + out = fpLong[index - 1]; + break; + + default: + result = B_BAD_TYPE; + break; + } + + return result; +} diff --git a/src/add-ons/translators/tifftranslator/TiffUintField.h b/src/add-ons/translators/tifftranslator/TiffUintField.h new file mode 100755 index 0000000000..d75724f1bc --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffUintField.h @@ -0,0 +1,57 @@ +/*****************************************************************************/ +// TiffUintField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffUintField.h +// +// This object is for storing Unsigned Integer TIFF fields +// +// +// 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_UNIT_FIELD_H +#define TIFF_UNIT_FIELD_H + +#include +#include +#include "TiffField.h" + +class TiffUintField : public TiffField { +public: + TiffUintField(IFDEntry &entry, BPositionIO &io, swap_action swp); + virtual ~TiffUintField(); + + status_t GetUint(uint32 &out, uint32 index = 0); + +private: + void LoadByte(IFDEntry &entry, BPositionIO &io, swap_action swp); + void LoadShort(IFDEntry &entry, BPositionIO &io, swap_action swp); + void LoadLong(IFDEntry &entry, BPositionIO &io, swap_action swp); + + union { + uint8 *fpByte; + uint16 *fpShort; + uint32 *fpLong; + }; +}; + +#endif // #define TIFF_UNIT_FIELD_H diff --git a/src/add-ons/translators/tifftranslator/TiffUnknownField.cpp b/src/add-ons/translators/tifftranslator/TiffUnknownField.cpp new file mode 100755 index 0000000000..d8e5206b40 --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffUnknownField.cpp @@ -0,0 +1,46 @@ +/*****************************************************************************/ +// TiffUnknownField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffUnknownField.cpp +// +// This object is for storing TIFF fields that the translator doesn't know +// or doesn't care about +// +// +// 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 +#include "TiffUnknownField.h" + +TiffUnknownField::TiffUnknownField(IFDEntry &entry) + : TiffField(entry) +{ + finitStatus = B_OK; + + printf("TiffUnknownField::finitStatus: %d\n", + static_cast(finitStatus)); +} + +TiffUnknownField::~TiffUnknownField() +{ +} diff --git a/src/add-ons/translators/tifftranslator/TiffUnknownField.h b/src/add-ons/translators/tifftranslator/TiffUnknownField.h new file mode 100755 index 0000000000..b0d4905124 --- /dev/null +++ b/src/add-ons/translators/tifftranslator/TiffUnknownField.h @@ -0,0 +1,43 @@ +/*****************************************************************************/ +// TiffUnknownField +// Written by Michael Wilber, OBOS Translation Kit Team +// +// TiffUnknownField.h +// +// This object is for storing TIFF fields that the translator doesn't know +// or doesn't care about +// +// +// 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_UNKNOWN_FIELD_H +#define TIFF_UNKNOWN_FIELD_H + +#include "TiffField.h" + +class TiffUnknownField : public TiffField { +public: + TiffUnknownField(IFDEntry &entry); + virtual ~TiffUnknownField(); +}; + +#endif // TIFF_UNKNOWN_FIELD_H \ No newline at end of file