Making field_t to match BigTIFF's specification and reading it properly.

There are also adjustments for IFD to match BigTIFF
v0.27.3
Michał Walenciak 8 years ago
parent 7d0009d6bd
commit 018eced12d

@ -48,49 +48,46 @@ enum TypeId {
bool isStringType(uint16_t type) bool isStringType(uint16_t type)
{ {
return type == asciiString return type == asciiString
|| type == unsignedByte || type == unsignedByte
|| type == signedByte || type == signedByte
|| type == undefined || type == undefined;
;
} }
bool isShortType(uint16_t type) { bool isShortType(uint16_t type)
return type == unsignedShort {
|| type == signedShort return type == unsignedShort
; || type == signedShort;
} }
bool isLongType(uint16_t type) { bool isLongType(uint16_t type)
return type == unsignedLong {
|| type == signedLong return type == unsignedLong
; || type == signedLong;
} }
bool isRationalType(uint16_t type) { bool isRationalType(uint16_t type)
return type == unsignedRational {
|| type == signedRational return type == unsignedRational
; || type == signedRational;
} }
bool is2ByteType(uint16_t type) bool is2ByteType(uint16_t type)
{ {
return isShortType(type); return isShortType(type);
} }
bool is4ByteType(uint16_t type) bool is4ByteType(uint16_t type)
{ {
return isLongType(type) return isLongType(type)
|| type == tiffFloat || type == tiffFloat
|| type == tiffIfd || type == tiffIfd;
;
} }
bool is8ByteType(uint16_t type) bool is8ByteType(uint16_t type)
{ {
return isRationalType(type) return isRationalType(type)
|| type == tiffDouble || type == tiffDouble;
;
} }
constexpr bool isBigEndianPlatform() constexpr bool isBigEndianPlatform()
@ -231,9 +228,9 @@ static const char* typeName(uint16_t tag)
typedef struct { typedef struct {
uint16_t tagID; uint16_t tagID;
uint16_t tagType ; uint16_t tagType;
uint32_t count; uint64_t count;
uint32_t offset; uint64_t offset;
} field_t; } field_t;
void printIFD(Exiv2::BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, uint32_t offset, bool bSwap, int depth) void printIFD(Exiv2::BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option, uint32_t offset, bool bSwap, int depth)
@ -250,49 +247,53 @@ void printIFD(Exiv2::BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption
// Read top of directory // Read top of directory
io.seek(offset, Exiv2::BasicIo::beg); io.seek(offset, Exiv2::BasicIo::beg);
uint16_t dir; uint64_t entries_raw;
io.read(reinterpret_cast<Exiv2::byte *>(&dir), 2); io.read(reinterpret_cast<Exiv2::byte *>(&entries_raw), 8);
uint16_t dirLength = conditional_byte_swap_4_array<16>(&dir, 0, bSwap); const uint16_t entries = conditional_byte_swap_4_array<64>(&entries_raw, 0, bSwap);
bool tooBig = dirLength > 500; const bool tooBig = entries > 500;
if ( bFirst && bPrint ) { if ( bFirst && bPrint )
{
out << indent(depth) << Exiv2::Internal::stringFormat("STRUCTURE OF TIFF FILE") << io.path() << std::endl; out << indent(depth) << Exiv2::Internal::stringFormat("STRUCTURE OF TIFF FILE") << io.path() << std::endl;
if ( tooBig ) out << indent(depth) << "dirLength = " << dirLength << std::endl; if (tooBig)
out << indent(depth) << "entries = " << entries << std::endl;
} }
if (tooBig) break;
if (tooBig)
break;
// Read the dictionary // Read the dictionary
for ( int i = 0 ; i < dirLength ; i ++ ) { for ( int i = 0; i < entries; i ++ )
if ( bFirst && bPrint ) { {
out << indent(depth) if ( bFirst && bPrint )
<< " address | tag | " out << indent(depth)
<< " type | count | offset | value\n"; << " address | tag | "
} << " type | count | offset | value\n";
bFirst = false; bFirst = false;
field_t field; field_t field;
io.read(reinterpret_cast<Exiv2::byte*>(&field), sizeof(field)); io.read(reinterpret_cast<Exiv2::byte*>(&field), sizeof(field));
uint16_t tag = conditional_byte_swap_4_array<16>(&field.tagID, 0, bSwap); const uint16_t tag = conditional_byte_swap_4_array<16>(&field.tagID, 0, bSwap);
uint16_t type = conditional_byte_swap_4_array<16>(&field.tagType, 2, bSwap); const uint16_t type = conditional_byte_swap_4_array<16>(&field.tagType, 2, bSwap);
uint32_t count = conditional_byte_swap_4_array<32>(&field.count, 4, bSwap); const uint32_t count = conditional_byte_swap_4_array<64>(&field.count, 4, bSwap);
uint32_t offset = conditional_byte_swap_4_array<32>(&field.offset, 8, bSwap); const uint32_t offset = conditional_byte_swap_4_array<64>(&field.offset, 12, bSwap);
std::string sp = "" ; // output spacer std::string sp = "" ; // output spacer
//prepare to print the value //prepare to print the value
uint32_t kount = isStringType(type) ? (count > 32 ? 32 : count) // restrict long arrays const uint32_t kount = isStringType(type)? (count > 32 ? 32 : count) // restrict long arrays
: count > 5 ? 5 : count > 5 ? 5
: count : count
; ;
uint32_t pad = isStringType(type) ? 1 : 0; const uint32_t pad = isStringType(type) ? 1 : 0;
uint32_t size = isStringType(type) ? 1 const uint32_t size = isStringType(type) ? 1
: is2ByteType(type) ? 2 : is2ByteType(type) ? 2
: is4ByteType(type) ? 4 : is4ByteType(type) ? 4
: is8ByteType(type) ? 8 : is8ByteType(type) ? 8
: 1 : 1;
;
Exiv2::DataBuf buf(size*count + pad); // allocate a buffer Exiv2::DataBuf buf(size*count + pad); // allocate a buffer
Exiv2::DataBuf dir(size*count + pad); // TODO: fix me, I'm object out of nowhere Exiv2::DataBuf dir(size*count + pad); // TODO: fix me, I'm object out of nowhere
@ -378,8 +379,9 @@ void printIFD(Exiv2::BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption
} }
} }
} }
//io.read(&dir.pData_, 4); TODO: fix me uint64_t next_dir_offset_raw;
start = tooBig ? 0 : conditional_byte_swap_4_array<32>(&dir, 0, bSwap); io.read(reinterpret_cast<Exiv2::byte*>(&next_dir_offset_raw), 8);
start = tooBig ? 0 : conditional_byte_swap_4_array<64>(&next_dir_offset_raw, 0, bSwap);
out.flush(); out.flush();
} while (start) ; } while (start) ;

Loading…
Cancel
Save