|
|
|
/*
|
|
|
|
* This file is part of Chalk
|
|
|
|
*
|
|
|
|
* Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "kis_exif_value.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kmdcodec.h>
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
void set16Bit (unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT16* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
data[0] = (unsigned char) (*value >> 8);
|
|
|
|
data[1] = (unsigned char) *value;
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
data[0] = (unsigned char) *value;
|
|
|
|
data[1] = (unsigned char) (*value >> 8);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void get16Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT16* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
*value = ((data[0] << 8) | data[1]);
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
*value = ((data[1] << 8) | data[0]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void get32Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT32* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
*value = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
*value = ((data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set32Bit(unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT32* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
data[0] = (unsigned char) (*value >> 24);
|
|
|
|
data[1] = (unsigned char) (*value >> 16);
|
|
|
|
data[2] = (unsigned char) (*value >> 8);
|
|
|
|
data[3] = (unsigned char) *value;
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
data[3] = (unsigned char) (*value >> 24);
|
|
|
|
data[2] = (unsigned char) (*value >> 16);
|
|
|
|
data[1] = (unsigned char) (*value >> 8);
|
|
|
|
data[0] = (unsigned char) *value;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void get64Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT64* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
*value = (((TQ_UINT64)data[0] << 56) | ((TQ_UINT64)data[1] << 48) | ((TQ_UINT64)data[2] << 40) | ((TQ_UINT64)data[3] << 32) | ((TQ_UINT64)data[4] << 24) | ((TQ_UINT64)data[5] << 16) | ((TQ_UINT64)data[6] << 8) | (TQ_UINT64)data[7]);
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
*value = (((TQ_UINT64)data[7] << 56) | ((TQ_UINT64)data[6] << 48) | ((TQ_UINT64)data[5] << 40) | ((TQ_UINT64)data[4] << 32) | ((TQ_UINT64)data[3] << 24) | ((TQ_UINT64)data[2] << 16) | ((TQ_UINT64)data[1] << 8) | (TQ_UINT64)data[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void set64Bit(unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT64* value)
|
|
|
|
{
|
|
|
|
switch (order) {
|
|
|
|
case ExifValue::BYTE_ORDER_MOTOROLA:
|
|
|
|
data[0] = (unsigned char) (*value >> 56);
|
|
|
|
data[1] = (unsigned char) (*value >> 48);
|
|
|
|
data[2] = (unsigned char) (*value >> 40);
|
|
|
|
data[3] = (unsigned char) (*value >> 32);
|
|
|
|
data[4] = (unsigned char) (*value >> 24);
|
|
|
|
data[5] = (unsigned char) (*value >> 16);
|
|
|
|
data[6] = (unsigned char) (*value >> 8);
|
|
|
|
data[7] = (unsigned char) *value;
|
|
|
|
break;
|
|
|
|
case ExifValue::BYTE_ORDER_INTEL:
|
|
|
|
data[7] = (unsigned char) (*value >> 56);
|
|
|
|
data[6] = (unsigned char) (*value >> 48);
|
|
|
|
data[5] = (unsigned char) (*value >> 40);
|
|
|
|
data[4] = (unsigned char) (*value >> 32);
|
|
|
|
data[3] = (unsigned char) (*value >> 24);
|
|
|
|
data[2] = (unsigned char) (*value >> 16);
|
|
|
|
data[1] = (unsigned char) (*value >> 8);
|
|
|
|
data[0] = (unsigned char) *value;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ExifValue::ExifValue(ExifType ntype, unsigned char *data, unsigned int size, int ifd, uint ncomponents, ExifValue::ByteOrder order ) : m_ifd(ifd), m_type(ntype), m_components(ncomponents), m_value(0)
|
|
|
|
{
|
|
|
|
allocData();
|
|
|
|
setValue(data, size, order);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExifValue::allocData()
|
|
|
|
{
|
|
|
|
if( type() != EXIF_TYPE_ASCII && type() != EXIF_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
m_value = new ExifNumber[components()];
|
|
|
|
} else if ( type() == EXIF_TYPE_ASCII )
|
|
|
|
{
|
|
|
|
m_value = new TQString();
|
|
|
|
} else if ( type() == EXIF_TYPE_UNDEFINED)
|
|
|
|
{
|
|
|
|
m_value = new UByteArray();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ExifValue::load(const TQDomElement& elmt)
|
|
|
|
{
|
|
|
|
TQString attr;
|
|
|
|
if( (attr = elmt.attribute("ifd")).isNull() )
|
|
|
|
return false;
|
|
|
|
m_ifd = attr.toInt();
|
|
|
|
if( (attr = elmt.attribute("components")).isNull() )
|
|
|
|
return false;
|
|
|
|
m_components = attr.toInt();
|
|
|
|
if( (attr = elmt.attribute("type")).isNull() )
|
|
|
|
return false;
|
|
|
|
m_type = (ExifValue::ExifType)attr.toInt();
|
|
|
|
allocData();
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_BYTE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_UINT8)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_UINT8) attr.toUInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_ASCII:
|
|
|
|
setAsAscii( elmt.attribute("value" ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SHORT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_UINT16)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_UINT16) attr.toUInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_LONG:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_UINT32)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_UINT32) attr.toUInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_RATIONAL:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
KisExifRational r;
|
|
|
|
if( (attr = elmt.attribute(TQString("numerator%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
r.numerator = (TQ_UINT32)0;
|
|
|
|
} else {
|
|
|
|
r.numerator = (TQ_UINT32) attr.toUInt();
|
|
|
|
}
|
|
|
|
if( (attr = elmt.attribute(TQString("denominator%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
r.denominator = (TQ_UINT32)0;
|
|
|
|
} else {
|
|
|
|
r.denominator = (TQ_UINT32) attr.toUInt();
|
|
|
|
}
|
|
|
|
setValue(i, r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SBYTE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_INT8)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_INT8) attr.toInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNDEFINED:
|
|
|
|
{
|
|
|
|
TQString instr = elmt.attribute("value");
|
|
|
|
TQByteArray out;
|
|
|
|
TQByteArray in = instr.utf8();
|
|
|
|
KCodecs::base64Decode( in, out);
|
|
|
|
out.resize(out.size() - 2 );
|
|
|
|
setAsUndefined((uchar*)out.data(), out.size() );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SSHORT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_INT16)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_INT16) attr.toInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SLONG:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (TQ_INT32)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (TQ_INT32) attr.toInt());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SRATIONAL:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
KisExifSRational r;
|
|
|
|
if( (attr = elmt.attribute(TQString("numerator%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
r.numerator = (TQ_INT32)0;
|
|
|
|
} else {
|
|
|
|
r.numerator = (TQ_INT32) attr.toInt();
|
|
|
|
}
|
|
|
|
if( (attr = elmt.attribute(TQString("denominator%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
r.denominator = (TQ_UINT32)0;
|
|
|
|
} else {
|
|
|
|
r.denominator = (TQ_UINT32) attr.toInt();
|
|
|
|
}
|
|
|
|
setValue(i, r);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_FLOAT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (float)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (float) attr.toFloat());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_DOUBLE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
|
|
|
|
{
|
|
|
|
setValue(i, (double)0);
|
|
|
|
} else {
|
|
|
|
setValue(i, (double) attr.toDouble());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNKNOW:
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDomElement ExifValue::save(TQDomDocument& doc)
|
|
|
|
{
|
|
|
|
TQDomElement elmt = doc.createElement("ExifValue");
|
|
|
|
elmt.setAttribute("ifd", ifd());
|
|
|
|
elmt.setAttribute("components", components() );
|
|
|
|
elmt.setAttribute("type", type() );
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_BYTE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asByte( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_ASCII:
|
|
|
|
elmt.setAttribute("value", asAscii() );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SHORT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asShort( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_LONG:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asLong( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_RATIONAL:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
KisExifRational r = asRational(i);
|
|
|
|
elmt.setAttribute(TQString("numerator%1").arg(i), r.numerator );
|
|
|
|
elmt.setAttribute(TQString("denominator%1").arg(i), r.denominator );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SBYTE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asSByte( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNDEFINED:
|
|
|
|
{
|
|
|
|
UByteArray value = asUndefined();
|
|
|
|
TQByteArray data;
|
|
|
|
data.setRawData((char*)value.data(), value.size());
|
|
|
|
TQByteArray encodedData;
|
|
|
|
KCodecs::base64Encode( data, encodedData );
|
|
|
|
data.resetRawData( (char*)value.data(), value.size());
|
|
|
|
elmt.setAttribute("value", TQString(encodedData));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SSHORT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asSShort( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SLONG:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asSLong( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SRATIONAL:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
KisExifSRational r = asSRational(i);
|
|
|
|
elmt.setAttribute(TQString("numerator%1").arg(i), r.numerator );
|
|
|
|
elmt.setAttribute(TQString("denominator%1").arg(i), r.denominator );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_FLOAT:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asFloat( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_DOUBLE:
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
elmt.setAttribute(TQString("value%1").arg(i), asDouble( i ) );
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNKNOW:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return elmt;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ExifValue::setValue(const unsigned char *data, unsigned int size, ExifValue::ByteOrder order)
|
|
|
|
{
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_BYTE:
|
|
|
|
if( size == components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
n.m_byte = data[i];
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_ASCII:
|
|
|
|
setAsAscii((char*) data);
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SHORT:
|
|
|
|
if( size == 2*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get16Bit( data + 2 * i, order, &n.m_short);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_LONG:
|
|
|
|
if( size == 4*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get32Bit( data + 4 * i, order, &n.m_long);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_RATIONAL:
|
|
|
|
if( size == 8*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get32Bit( data + 8 * i, order, &n.m_rational.numerator);
|
|
|
|
get32Bit( data + 8 * i + 4, order, &n.m_rational.denominator);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SBYTE:
|
|
|
|
if( size == components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
n.m_sbyte = ((TQ_INT8*)data)[i];
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNDEFINED:
|
|
|
|
setAsUndefined(data, size);
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SSHORT:
|
|
|
|
if( size == 2*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get16Bit( data + 2 * i, order, (TQ_UINT16*)&n.m_sshort);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SLONG:
|
|
|
|
if( size == 4*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get32Bit( data + 4 * i, order, (TQ_UINT32*)&n.m_slong);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SRATIONAL:
|
|
|
|
if( size == 8*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get32Bit( data + 8 * i, order, (TQ_UINT32*)&n.m_srational.numerator);
|
|
|
|
get32Bit( data + 8 * i + 4, order, (TQ_UINT32*)&n.m_srational.denominator);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_FLOAT:
|
|
|
|
if( size == 4*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get32Bit( data + 4 * i, order, (TQ_UINT32*)&n.m_float);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_DOUBLE:
|
|
|
|
if( size == 8*components() )
|
|
|
|
{
|
|
|
|
ExifNumber n;
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
get64Bit( data + 8 * i, order, (TQ_UINT64*)&n.m_double);
|
|
|
|
setAsExifNumber( i, n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_UNKNOW:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ExifValue::convertToData(unsigned char ** data, unsigned int* size, ExifValue::ByteOrder order)
|
|
|
|
{
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_BYTE:
|
|
|
|
*size = components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
(*data)[i] = asExifNumber(i).m_byte;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_ASCII:
|
|
|
|
{
|
|
|
|
TQString str = asAscii();
|
|
|
|
*size = str.length();
|
|
|
|
*data = new uchar[ *size ];
|
|
|
|
uchar* ptr = *data;
|
|
|
|
memcpy(ptr, str.ascii(), (*size)*sizeof(uchar));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
case EXIF_TYPE_SHORT:
|
|
|
|
{
|
|
|
|
*size = 2*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
TQ_UINT16 aenms = asExifNumber(i).m_short;
|
|
|
|
set16Bit( (*data) + 2 * i, order, &aenms);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case EXIF_TYPE_LONG:
|
|
|
|
{
|
|
|
|
*size = 4*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
TQ_UINT32 aenml = asExifNumber(i).m_long;
|
|
|
|
set32Bit( (*data) + 4 * i, order, &aenml);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
case EXIF_TYPE_RATIONAL:
|
|
|
|
*size = 8*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
ExifNumber n = asExifNumber(i);
|
|
|
|
set32Bit( (*data) + 8 * i, order, &n.m_rational.numerator);
|
|
|
|
set32Bit( (*data) + 8 * i + 4, order, &n.m_rational.denominator);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_SBYTE:
|
|
|
|
*size = components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
*(((TQ_INT8*)*data) + i) = asExifNumber(i).m_sbyte;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_UNDEFINED:
|
|
|
|
{
|
|
|
|
UByteArray array = asUndefined();
|
|
|
|
*size = array.size();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
memcpy( *data, array.data(), (*size)*sizeof(unsigned char));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_SSHORT:
|
|
|
|
*size = 2*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
TQ_INT16 aenmss = asExifNumber(i).m_sshort;
|
|
|
|
set16Bit( (*data) + 2 * i, order, (TQ_UINT16*)&aenmss);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_SLONG:
|
|
|
|
*size = 4*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
TQ_INT32 aenmsl = asExifNumber(i).m_slong;
|
|
|
|
set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmsl);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_SRATIONAL:
|
|
|
|
*size = 8*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
ExifNumber n = asExifNumber(i);
|
|
|
|
TQ_INT32 aenmsr_numerator = asExifNumber(i).m_srational.numerator;
|
|
|
|
TQ_INT32 aenmsr_denominator = asExifNumber(i).m_srational.denominator;
|
|
|
|
set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmsr_numerator);
|
|
|
|
set32Bit( (*data) + 4 * i + 4, order, (TQ_UINT32*)&aenmsr_denominator);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_FLOAT:
|
|
|
|
*size = 4*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
float aenmf = asExifNumber(i).m_float;
|
|
|
|
set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmf);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_DOUBLE:
|
|
|
|
*size = 8*components();
|
|
|
|
*data = new uchar[*size];
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
double aenmd = asExifNumber(i).m_double;
|
|
|
|
set64Bit( (*data) + 4 * i, order, (TQ_UINT64*)&aenmd);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
case EXIF_TYPE_UNKNOW:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ExifValue::toString()
|
|
|
|
{
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_ASCII:
|
|
|
|
return asAscii();
|
|
|
|
case EXIF_TYPE_UNDEFINED:
|
|
|
|
{
|
|
|
|
TQString undefined = "undefined";
|
|
|
|
UByteArray array = asUndefined();
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
undefined += "\\" + TQString().setNum( array[i] );
|
|
|
|
}
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
TQString str = "";
|
|
|
|
for(uint i = 0; i < components(); i++)
|
|
|
|
{
|
|
|
|
str += toString(i);
|
|
|
|
}
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ExifValue::toString(uint i)
|
|
|
|
{
|
|
|
|
switch(type())
|
|
|
|
{
|
|
|
|
case EXIF_TYPE_BYTE:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_byte );
|
|
|
|
case EXIF_TYPE_SHORT:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_short );
|
|
|
|
case EXIF_TYPE_LONG:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_long );
|
|
|
|
case EXIF_TYPE_RATIONAL:
|
|
|
|
return TQString("%1 / %2 ").arg( asExifNumber( i ).m_rational.numerator ).arg( asExifNumber( i ).m_rational.denominator );
|
|
|
|
case EXIF_TYPE_SBYTE: {
|
|
|
|
/* workaround to compiler bug on Raspbian Wheezy */
|
|
|
|
TQ_INT8 o_sbyte = asExifNumber( i ).m_sbyte;
|
|
|
|
return TQString("%1 ").arg( o_sbyte );
|
|
|
|
}
|
|
|
|
case EXIF_TYPE_SSHORT:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_sshort );
|
|
|
|
case EXIF_TYPE_SLONG:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_slong );
|
|
|
|
case EXIF_TYPE_SRATIONAL:
|
|
|
|
return TQString("%1 / %2 ").arg( asExifNumber( i ).m_srational.numerator ).arg( asExifNumber( i ).m_srational.denominator );
|
|
|
|
case EXIF_TYPE_FLOAT:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_float );
|
|
|
|
case EXIF_TYPE_DOUBLE:
|
|
|
|
return TQString("%1 ").arg( asExifNumber( i ).m_double );
|
|
|
|
default:
|
|
|
|
return "unknow ";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|