Still doesn't quite do anything yet, but now I have code to identify TIFF images and read TIFF fields

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3048 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber 2003-03-31 03:23:34 +00:00
parent 812870fc43
commit 1116d6c72b
11 changed files with 1099 additions and 6 deletions

View File

@ -1,5 +1,13 @@
SubDir OBOS_TOP src add-ons translators tifftranslator ; 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 ; LinkSharedOSLibs TIFFTranslator : be translation ;

View File

@ -33,6 +33,7 @@
#include <stdio.h> #include <stdio.h>
#include "TIFFTranslator.h" #include "TIFFTranslator.h"
#include "TIFFView.h" #include "TIFFView.h"
#include "TiffIfd.h"
// The input formats that this translator supports. // The input formats that this translator supports.
translation_format gInputFormats[] = { translation_format gInputFormats[] = {
@ -258,6 +259,201 @@ TIFFTranslator::OutputFormats(int32 *out_count) const
return NULL; 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<uint8 *> (&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<int>(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 // Identify
// //
@ -307,8 +503,64 @@ TIFFTranslator::Identify(BPositionIO *inSource,
if (outType != B_TRANSLATOR_BITMAP && outType != B_TIFF_FORMAT) if (outType != B_TRANSLATOR_BITMAP && outType != B_TIFF_FORMAT)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
return B_NO_TRANSLATOR; // Convert the magic numbers to the various byte orders so that
// translator isn't implemented yet // 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: // 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 status_t
TIFFTranslator::MakeConfigurationView(BMessage *ioExtension, BView **outView, 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), TIFFView *view = new TIFFView(BRect(0, 0, 225, 175),
"TIFFTranslator Settings", B_FOLLOW_ALL, B_WILL_DRAW); "TIFFTranslator Settings", B_FOLLOW_ALL, B_WILL_DRAW);
if (!view)
return B_NO_MEMORY;
*outView = view; *outView = view;
*outExtent = view->Bounds(); *outExtent = view->Bounds();

View File

@ -45,4 +45,4 @@ public:
// Posts a quit message so that the application closes properly // Posts a quit message so that the application closes properly
}; };
#endif #endif // #define TIFFWINDOW_H

View File

@ -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 <Errors.h>
#include <stdio.h>
#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<int>(fcount));
}

View File

@ -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 <SupportDefs.h>
// 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

View File

@ -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 <stdio.h>
#include <string.h>
#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<TiffUintField *>(pfield);
if (puintField) {
poutField = puintField;
return B_OK;
} else
return B_BAD_TYPE;
}
}
return B_BAD_INDEX;
}

View File

@ -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 <ByteOrder.h>
#include <DataIO.h>
#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

View File

@ -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 <stdio.h>
#include <string.h>
#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<ssize_t>(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<ssize_t>(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<ssize_t>(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<int>(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<unsigned>(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;
}

View File

@ -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 <DataIO.h>
#include <ByteOrder.h>
#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

View File

@ -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 <stdio.h>
#include "TiffUnknownField.h"
TiffUnknownField::TiffUnknownField(IFDEntry &entry)
: TiffField(entry)
{
finitStatus = B_OK;
printf("TiffUnknownField::finitStatus: %d\n",
static_cast<int>(finitStatus));
}
TiffUnknownField::~TiffUnknownField()
{
}

View File

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