Merge pull request #70 from Kicer86/bigtiff
Initial support for BigTiffs. Print only.
This commit is contained in:
commit
0153784ae3
16
include/exiv2/bigtiffimage.hpp
Normal file
16
include/exiv2/bigtiffimage.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
#include "basicio.hpp"
|
||||
#include "image.hpp"
|
||||
|
||||
namespace Exiv2
|
||||
{
|
||||
|
||||
namespace ImageType
|
||||
{
|
||||
const int bigtiff = 22;
|
||||
}
|
||||
|
||||
Image::AutoPtr newBigTiffInstance(BasicIo::AutoPtr, bool);
|
||||
bool isBigTiffType(BasicIo &, bool);
|
||||
|
||||
}
|
||||
@ -345,6 +345,7 @@ namespace Exiv2 {
|
||||
bool isStringType(uint16_t type);
|
||||
bool isShortType(uint16_t type);
|
||||
bool isLongType(uint16_t type);
|
||||
bool isLongLongType(uint16_t type);
|
||||
bool isRationalType(uint16_t type);
|
||||
bool is2ByteType(uint16_t type);
|
||||
bool is4ByteType(uint16_t type);
|
||||
@ -352,10 +353,12 @@ namespace Exiv2 {
|
||||
bool isPrintXMP(uint16_t type, Exiv2::PrintStructureOption option);
|
||||
bool isPrintICC(uint16_t type, Exiv2::PrintStructureOption option);
|
||||
|
||||
uint32_t byteSwap(uint32_t value,bool bSwap);
|
||||
uint16_t byteSwap(uint16_t value,bool bSwap);
|
||||
uint16_t byteSwap2(DataBuf& buf,size_t offset,bool bSwap);
|
||||
uint32_t byteSwap4(DataBuf& buf,size_t offset,bool bSwap);
|
||||
uint64_t byteSwap(uint64_t value,bool bSwap) const;
|
||||
uint32_t byteSwap(uint32_t value,bool bSwap) const;
|
||||
uint16_t byteSwap(uint16_t value,bool bSwap) const;
|
||||
uint16_t byteSwap2(const DataBuf& buf,size_t offset,bool bSwap) const;
|
||||
uint32_t byteSwap4(const DataBuf& buf,size_t offset,bool bSwap) const;
|
||||
uint64_t byteSwap8(const DataBuf& buf,size_t offset,bool bSwap) const;
|
||||
|
||||
//@}
|
||||
|
||||
@ -493,6 +496,12 @@ namespace Exiv2 {
|
||||
int pixelHeight_; //!< image pixel height
|
||||
NativePreviewList nativePreviews_; //!< list of native previews
|
||||
|
||||
//! Return tag name for given tag id.
|
||||
const std::string& tagName(uint16_t tag);
|
||||
|
||||
//! Return tag type for given tag id.
|
||||
const char* typeName(uint16_t tag) const;
|
||||
|
||||
private:
|
||||
//! @name NOT implemented
|
||||
//@{
|
||||
@ -502,9 +511,6 @@ namespace Exiv2 {
|
||||
Image& operator=(const Image& rhs);
|
||||
//@}
|
||||
|
||||
//! Return tag name for given tag id.
|
||||
const std::string& tagName(uint16_t tag);
|
||||
|
||||
// DATA
|
||||
int imageType_; //!< Image type
|
||||
uint16_t supportedMetadata_; //!< Bitmap with all supported metadata types
|
||||
|
||||
@ -137,6 +137,9 @@ namespace Exiv2 {
|
||||
tiffFloat =11, //!< TIFF FLOAT type, single precision (4-byte) IEEE format.
|
||||
tiffDouble =12, //!< TIFF DOUBLE type, double precision (8-byte) IEEE format.
|
||||
tiffIfd =13, //!< TIFF IFD type, 32-bit (4-byte) unsigned integer.
|
||||
unsignedLongLong =16, //!< Exif LONG LONG type, 64-bit (8-byte) unsigned integer.
|
||||
signedLongLong =17, //!< Exif LONG LONG type, 64-bit (8-byte) signed integer.
|
||||
tiffIfd8 =18, //!< TIFF IFD type, 64-bit (8-byte) unsigned integer.
|
||||
string =0x10000, //!< IPTC string type.
|
||||
date =0x10001, //!< IPTC date type.
|
||||
time =0x10002, //!< IPTC time type.
|
||||
@ -266,6 +269,8 @@ namespace Exiv2 {
|
||||
EXIV2API uint16_t getUShort(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 4 byte unsigned long value from the data buffer
|
||||
EXIV2API uint32_t getULong(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 8 byte unsigned long value from the data buffer
|
||||
EXIV2API uint64_t getULongLong(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read an 8 byte unsigned rational value from the data buffer
|
||||
EXIV2API URational getURational(const byte* buf, ByteOrder byteOrder);
|
||||
//! Read a 2 byte signed short value from the data buffer
|
||||
|
||||
@ -84,6 +84,7 @@ set( LIBEXIV2_HDR ../include/exiv2/asfvideo.hpp
|
||||
# Add library C++ source files to this list
|
||||
set( LIBEXIV2_SRC asfvideo.cpp
|
||||
basicio.cpp
|
||||
bigtiffimage.cpp
|
||||
bmpimage.cpp
|
||||
canonmn.cpp
|
||||
casiomn.cpp
|
||||
|
||||
412
src/bigtiffimage.cpp
Normal file
412
src/bigtiffimage.cpp
Normal file
@ -0,0 +1,412 @@
|
||||
|
||||
#include "bigtiffimage.hpp"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "exif.hpp"
|
||||
#include "image_int.hpp"
|
||||
|
||||
|
||||
namespace Exiv2
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
struct Header
|
||||
{
|
||||
enum Format
|
||||
{
|
||||
StandardTiff,
|
||||
BigTiff,
|
||||
};
|
||||
|
||||
Header(): byteOrder_(invalidByteOrder), version_(-1), data_size_(0), dir_offset_(0) {}
|
||||
Header(const ByteOrder& order, int v, int size, uint64_t offset):
|
||||
byteOrder_(order),
|
||||
version_(v),
|
||||
data_size_(size),
|
||||
dir_offset_(offset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
return version_ != -1;
|
||||
}
|
||||
|
||||
ByteOrder byteOrder() const
|
||||
{
|
||||
assert(isValid());
|
||||
return byteOrder_;
|
||||
}
|
||||
|
||||
int version() const
|
||||
{
|
||||
assert(isValid());
|
||||
return version_;
|
||||
}
|
||||
|
||||
Format format() const
|
||||
{
|
||||
assert(isValid());
|
||||
return version_ == 0x2A? StandardTiff: BigTiff;
|
||||
}
|
||||
|
||||
int dataSize() const
|
||||
{
|
||||
assert(isValid());
|
||||
return data_size_;
|
||||
}
|
||||
|
||||
uint64_t dirOffset() const
|
||||
{
|
||||
assert(isValid());
|
||||
return dir_offset_;
|
||||
}
|
||||
|
||||
private:
|
||||
ByteOrder byteOrder_;
|
||||
int version_; // 42 or 43 - regular tiff or big tiff
|
||||
int data_size_; // 4 or 8
|
||||
uint64_t dir_offset_;
|
||||
};
|
||||
|
||||
Header readHeader(BasicIo& io)
|
||||
{
|
||||
byte header[2];
|
||||
io.read(header, 2);
|
||||
|
||||
ByteOrder byteOrder = invalidByteOrder;
|
||||
if (header[0] == 'I' && header[1] == 'I')
|
||||
byteOrder = littleEndian;
|
||||
else if (header[0] == 'M' && header[1] == 'M')
|
||||
byteOrder = bigEndian;
|
||||
|
||||
if (byteOrder == invalidByteOrder)
|
||||
return Header();
|
||||
|
||||
byte version[2];
|
||||
io.read(version, 2);
|
||||
|
||||
const uint16_t magic = getUShort(version, byteOrder);
|
||||
|
||||
if (magic != 0x2A && magic != 0x2B)
|
||||
return Header();
|
||||
|
||||
Header result;
|
||||
|
||||
if (magic == 0x2A)
|
||||
{
|
||||
byte buffer[4];
|
||||
io.read(buffer, 4);
|
||||
|
||||
const uint32_t offset = getULong(buffer, byteOrder);
|
||||
result = Header(byteOrder, magic, 4, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
byte buffer[8];
|
||||
io.read(buffer, 2);
|
||||
const int size = getUShort(buffer, byteOrder);
|
||||
assert(size == 8);
|
||||
|
||||
io.read(buffer, 2); // null
|
||||
|
||||
io.read(buffer, 8);
|
||||
const uint64_t offset = getULongLong(buffer, byteOrder);
|
||||
|
||||
result = Header(byteOrder, magic, size, offset);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
class BigTiffImage: public Image
|
||||
{
|
||||
public:
|
||||
BigTiffImage(BasicIo::AutoPtr io):
|
||||
Image(ImageType::bigtiff, mdExif, io),
|
||||
header_(),
|
||||
dataSize_(0),
|
||||
doSwap_(false)
|
||||
{
|
||||
header_ = readHeader(Image::io());
|
||||
assert(header_.isValid());
|
||||
|
||||
doSwap_ = (isLittleEndianPlatform() && header_.byteOrder() == bigEndian)
|
||||
|| (isBigEndianPlatform() && header_.byteOrder() == littleEndian);
|
||||
|
||||
dataSize_ = header_.format() == Header::StandardTiff? 4 : 8;
|
||||
}
|
||||
|
||||
virtual ~BigTiffImage() {}
|
||||
|
||||
// overrides
|
||||
void readMetadata()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void writeMetadata()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string mimeType() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void printStructure(std::ostream& os, PrintStructureOption option, int depth)
|
||||
{
|
||||
printIFD(os, option, header_.dirOffset(), depth - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
Header header_;
|
||||
int dataSize_;
|
||||
bool doSwap_;
|
||||
|
||||
void printIFD(std::ostream& out, PrintStructureOption option, uint64_t dir_offset, int depth)
|
||||
{
|
||||
BasicIo& io = Image::io();
|
||||
|
||||
depth++;
|
||||
bool bFirst = true;
|
||||
|
||||
// buffer
|
||||
bool bPrint = true;
|
||||
|
||||
do
|
||||
{
|
||||
// Read top of directory
|
||||
io.seek(dir_offset, BasicIo::beg);
|
||||
|
||||
const uint64_t entries = readData(header_.format() == Header::StandardTiff? 2: 8);
|
||||
const bool tooBig = entries > 500;
|
||||
|
||||
if ( bFirst && bPrint )
|
||||
{
|
||||
out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE ") << io.path() << std::endl;
|
||||
if (tooBig)
|
||||
out << Internal::indent(depth) << "entries = " << entries << std::endl;
|
||||
}
|
||||
|
||||
if (tooBig)
|
||||
break;
|
||||
|
||||
// Read the dictionary
|
||||
for ( uint64_t i = 0; i < entries; i ++ )
|
||||
{
|
||||
if ( bFirst && bPrint )
|
||||
out << Internal::indent(depth)
|
||||
<< " address | tag | "
|
||||
<< " type | count | offset | value\n";
|
||||
|
||||
bFirst = false;
|
||||
|
||||
const uint16_t tag = readData(2);
|
||||
const uint16_t type = readData(2);
|
||||
const uint64_t count = readData(dataSize_);
|
||||
const DataBuf data = io.read(dataSize_); // Read data as raw value. what should be done about it will be decided depending on type
|
||||
|
||||
std::string sp = "" ; // output spacer
|
||||
|
||||
//prepare to print the value
|
||||
// TODO: figure out what's going on with kount
|
||||
const uint64_t kount = isStringType(type)? (count > 32 ? 32 : count) // restrict long arrays
|
||||
: count > 5 ? 5
|
||||
: count
|
||||
;
|
||||
const uint32_t pad = isStringType(type) ? 1 : 0;
|
||||
const uint32_t size = isStringType(type) ? 1
|
||||
: is2ByteType(type) ? 2
|
||||
: is4ByteType(type) ? 4
|
||||
: is8ByteType(type) ? 8
|
||||
: 1;
|
||||
|
||||
DataBuf buf(size * count + pad);
|
||||
|
||||
const uint64_t offset = header_.format() == Header::StandardTiff?
|
||||
byteSwap4(data, 0, doSwap_):
|
||||
byteSwap8(data, 0, doSwap_);
|
||||
|
||||
// big data? Use 'data' as pointer to real data
|
||||
const bool usePointer = count*size > dataSize_;
|
||||
|
||||
if ( usePointer ) // read into buffer
|
||||
{
|
||||
size_t restore = io.tell(); // save
|
||||
io.seek(offset, BasicIo::beg); // position
|
||||
io.read(buf.pData_, count * size); // read
|
||||
io.seek(restore, BasicIo::beg); // restore
|
||||
}
|
||||
else // use 'data' as data :)
|
||||
std::memcpy(buf.pData_, data.pData_, count * size); // copy data
|
||||
|
||||
if ( bPrint )
|
||||
{
|
||||
const int entrySize = header_.format() == Header::StandardTiff? 12: 20;
|
||||
const uint64_t address = dir_offset + 2 + i * entrySize;
|
||||
const std::string offsetString = usePointer?
|
||||
Internal::stringFormat("%10u", offset):
|
||||
"";
|
||||
|
||||
out << Internal::indent(depth)
|
||||
<< Internal::stringFormat("%8u | %#06x %-25s |%10s |%9u |%10s | ",
|
||||
address, tag, tagName(tag).c_str(), typeName(type), count, offsetString.c_str());
|
||||
|
||||
if ( isShortType(type) )
|
||||
{
|
||||
for ( size_t k = 0 ; k < kount ; k++ )
|
||||
{
|
||||
out << sp << byteSwap2(buf, k*size, doSwap_);
|
||||
sp = " ";
|
||||
}
|
||||
}
|
||||
else if ( isLongType(type) )
|
||||
{
|
||||
for ( size_t k = 0 ; k < kount ; k++ )
|
||||
{
|
||||
out << sp << byteSwap4(buf, k*size, doSwap_);
|
||||
sp = " ";
|
||||
}
|
||||
}
|
||||
else if ( isLongLongType(type) )
|
||||
{
|
||||
for ( size_t k = 0 ; k < kount ; k++ )
|
||||
{
|
||||
out << sp << byteSwap8(buf, k*size, doSwap_);
|
||||
sp = " ";
|
||||
}
|
||||
}
|
||||
else if ( isRationalType(type) )
|
||||
{
|
||||
for ( size_t k = 0 ; k < kount ; k++ )
|
||||
{
|
||||
uint32_t a = byteSwap4(buf, k*size+0, doSwap_);
|
||||
uint32_t b = byteSwap4(buf, k*size+4, doSwap_);
|
||||
out << sp << a << "/" << b;
|
||||
sp = " ";
|
||||
}
|
||||
}
|
||||
else if ( isStringType(type) )
|
||||
out << sp << Internal::binaryToString(buf, kount);
|
||||
|
||||
sp = kount == count ? "" : " ...";
|
||||
out << sp << std::endl;
|
||||
|
||||
if ( option == kpsRecursive &&
|
||||
(tag == 0x8769 /* ExifTag */ || tag == 0x014a/*SubIFDs*/ || type == tiffIfd || type == tiffIfd8) )
|
||||
{
|
||||
for ( size_t k = 0 ; k < count ; k++ )
|
||||
{
|
||||
const size_t restore = io.tell();
|
||||
const uint64_t ifdOffset = type == tiffIfd8?
|
||||
byteSwap8(buf, k*size, doSwap_):
|
||||
byteSwap4(buf, k*size, doSwap_);
|
||||
|
||||
std::cerr << "tag = " << Internal::stringFormat("%#x",tag) << std::endl;
|
||||
printIFD(out, option, ifdOffset, depth);
|
||||
io.seek(restore, BasicIo::beg);
|
||||
}
|
||||
}
|
||||
else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ )
|
||||
{
|
||||
const size_t restore = io.tell(); // save
|
||||
io.seek(offset, BasicIo::beg); // position
|
||||
byte* bytes=new byte[count] ; // allocate memory
|
||||
io.read(bytes,count) ; // read
|
||||
io.seek(restore, BasicIo::beg); // restore
|
||||
IptcData::printStructure(out,bytes,count,depth);
|
||||
delete[] bytes; // free
|
||||
}
|
||||
else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10)
|
||||
{
|
||||
size_t restore = io.tell(); // save
|
||||
|
||||
uint32_t jump= 10 ;
|
||||
byte bytes[20] ;
|
||||
const char* chars = (const char*) &bytes[0] ;
|
||||
io.seek(dir_offset, BasicIo::beg); // position
|
||||
io.read(bytes,jump ) ; // read
|
||||
bytes[jump]=0 ;
|
||||
if ( ::strcmp("Nikon",chars) == 0 )
|
||||
{
|
||||
// tag is an embedded tiff
|
||||
byte* bytes=new byte[count-jump] ; // allocate memory
|
||||
io.read(bytes,count-jump) ; // read
|
||||
MemIo memIo(bytes,count-jump) ; // create a file
|
||||
std::cerr << "Nikon makernote" << std::endl;
|
||||
// printTiffStructure(memIo,out,option,depth); TODO: fix it
|
||||
delete[] bytes ; // free
|
||||
}
|
||||
else
|
||||
{
|
||||
// tag is an IFD
|
||||
io.seek(0, BasicIo::beg); // position
|
||||
std::cerr << "makernote" << std::endl;
|
||||
printIFD(out,option,offset,depth);
|
||||
}
|
||||
|
||||
io.seek(restore,BasicIo::beg); // restore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const uint64_t nextDirOffset = readData(dataSize_);
|
||||
|
||||
dir_offset = tooBig ? 0 : nextDirOffset;
|
||||
out.flush();
|
||||
} while (dir_offset != 0);
|
||||
|
||||
if ( bPrint )
|
||||
out << Internal::indent(depth) << "END " << io.path() << std::endl;
|
||||
|
||||
depth--;
|
||||
}
|
||||
|
||||
uint64_t readData(int size) const
|
||||
{
|
||||
const DataBuf data = Image::io().read(size);
|
||||
assert(data.size_ != 0);
|
||||
|
||||
uint64_t result = 0;
|
||||
|
||||
if (size == 1)
|
||||
{}
|
||||
else if (size == 2)
|
||||
result = byteSwap2(data, 0, doSwap_);
|
||||
else if (size == 4)
|
||||
result = byteSwap4(data, 0, doSwap_);
|
||||
else if (size == 8)
|
||||
result = byteSwap8(data, 0, doSwap_);
|
||||
else
|
||||
assert(!"unexpected size");
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Image::AutoPtr newBigTiffInstance(BasicIo::AutoPtr io, bool)
|
||||
{
|
||||
return Image::AutoPtr(new BigTiffImage(io));
|
||||
}
|
||||
|
||||
|
||||
bool isBigTiffType(BasicIo& io, bool advance)
|
||||
{
|
||||
const long pos = io.tell();
|
||||
const Header header = readHeader(io);
|
||||
const bool valid = header.isValid();
|
||||
|
||||
if (valid == false || advance == false)
|
||||
io.seek(pos, BasicIo::beg);
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
}
|
||||
@ -47,6 +47,7 @@ EXIV2_RCSID("@(#) $Id$")
|
||||
#include "tiffimage_int.hpp"
|
||||
#include "tiffcomposite_int.hpp"
|
||||
#include "tiffvisitor_int.hpp"
|
||||
#include "bigtiffimage.hpp"
|
||||
#include "webpimage.hpp"
|
||||
#include "orfimage.hpp"
|
||||
#include "gifimage.hpp"
|
||||
@ -112,6 +113,7 @@ namespace {
|
||||
{ ImageType::crw, newCrwInstance, isCrwType, amReadWrite, amNone, amNone, amReadWrite },
|
||||
{ ImageType::mrw, newMrwInstance, isMrwType, amRead, amRead, amRead, amNone },
|
||||
{ ImageType::tiff, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
||||
{ ImageType::bigtiff, newBigTiffInstance, isBigTiffType, amRead, amRead, amRead, amNone },
|
||||
{ ImageType::webp, newWebPInstance, isWebPType, amReadWrite, amNone, amReadWrite, amNone },
|
||||
{ ImageType::dng, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
||||
{ ImageType::nef, newTiffInstance, isTiffType, amReadWrite, amReadWrite, amReadWrite, amNone },
|
||||
@ -195,6 +197,11 @@ namespace Exiv2 {
|
||||
|| type == Exiv2::signedLong
|
||||
;
|
||||
}
|
||||
bool Image::isLongLongType(uint16_t type) {
|
||||
return type == Exiv2::unsignedLongLong
|
||||
|| type == Exiv2::signedLongLong
|
||||
;
|
||||
}
|
||||
bool Image::isRationalType(uint16_t type) {
|
||||
return type == Exiv2::unsignedRational
|
||||
|| type == Exiv2::signedRational
|
||||
@ -237,7 +244,19 @@ namespace Exiv2 {
|
||||
}
|
||||
bool Image::isLittleEndianPlatform() { return !isBigEndianPlatform(); }
|
||||
|
||||
uint32_t Image::byteSwap(uint32_t value,bool bSwap)
|
||||
uint64_t Image::byteSwap(uint64_t value,bool bSwap) const
|
||||
{
|
||||
uint64_t result = 0;
|
||||
byte* source_value = reinterpret_cast<byte *>(&value);
|
||||
byte* destination_value = reinterpret_cast<byte *>(&result);
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
destination_value[i] = source_value[8 - i - 1];
|
||||
|
||||
return bSwap ? result : value;
|
||||
}
|
||||
|
||||
uint32_t Image::byteSwap(uint32_t value,bool bSwap) const
|
||||
{
|
||||
uint32_t result = 0;
|
||||
result |= (value & 0x000000FF) << 24;
|
||||
@ -247,7 +266,7 @@ namespace Exiv2 {
|
||||
return bSwap ? result : value;
|
||||
}
|
||||
|
||||
uint16_t Image::byteSwap(uint16_t value,bool bSwap)
|
||||
uint16_t Image::byteSwap(uint16_t value,bool bSwap) const
|
||||
{
|
||||
uint16_t result = 0;
|
||||
result |= (value & 0x00FF) << 8;
|
||||
@ -255,7 +274,7 @@ namespace Exiv2 {
|
||||
return bSwap ? result : value;
|
||||
}
|
||||
|
||||
uint16_t Image::byteSwap2(DataBuf& buf,size_t offset,bool bSwap)
|
||||
uint16_t Image::byteSwap2(const DataBuf& buf,size_t offset,bool bSwap) const
|
||||
{
|
||||
uint16_t v;
|
||||
char* p = (char*) &v;
|
||||
@ -264,7 +283,7 @@ namespace Exiv2 {
|
||||
return Image::byteSwap(v,bSwap);
|
||||
}
|
||||
|
||||
uint32_t Image::byteSwap4(DataBuf& buf,size_t offset,bool bSwap)
|
||||
uint32_t Image::byteSwap4(const DataBuf& buf,size_t offset,bool bSwap) const
|
||||
{
|
||||
uint32_t v;
|
||||
char* p = (char*) &v;
|
||||
@ -275,7 +294,18 @@ namespace Exiv2 {
|
||||
return Image::byteSwap(v,bSwap);
|
||||
}
|
||||
|
||||
static const char* typeName(uint16_t tag)
|
||||
uint64_t Image::byteSwap8(const DataBuf& buf,size_t offset,bool bSwap) const
|
||||
{
|
||||
uint64_t v;
|
||||
byte* p = reinterpret_cast<byte *>(&v);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
p[i] = buf.pData_[offset + i];
|
||||
|
||||
return Image::byteSwap(v,bSwap);
|
||||
}
|
||||
|
||||
const char* Image::typeName(uint16_t tag) const
|
||||
{
|
||||
//! List of TIFF image tags
|
||||
const char* result = NULL;
|
||||
|
||||
@ -252,6 +252,22 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t getULongLong(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
if (byteOrder == littleEndian) {
|
||||
return (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48
|
||||
| (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32
|
||||
| (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16
|
||||
| (uint64_t)buf[1] << 8 | (uint64_t)buf[0];
|
||||
}
|
||||
else {
|
||||
return (uint64_t)buf[0] << 56 | (uint64_t)buf[1] << 48
|
||||
| (uint64_t)buf[2] << 40 | (uint64_t)buf[3] << 32
|
||||
| (uint64_t)buf[4] << 24 | (uint64_t)buf[5] << 16
|
||||
| (uint64_t)buf[6] << 8 | (uint64_t)buf[7];
|
||||
}
|
||||
}
|
||||
|
||||
URational getURational(const byte* buf, ByteOrder byteOrder)
|
||||
{
|
||||
uint32_t nominator = getULong(buf, byteOrder);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user