#711: Added FloatValue to deal with TIFF Float values. (Nice one! :)

v0.27.3
Andreas Huggel 15 years ago
parent 6fc96993a1
commit bc54748634

@ -235,6 +235,13 @@ namespace Exiv2 {
return std::make_pair(nominator, denominator); return std::make_pair(nominator, denominator);
} }
float getFloat(const byte* buf, ByteOrder byteOrder)
{
assert(sizeof(float) == 4);
uint32_t ul = getULong(buf, byteOrder);
return *reinterpret_cast<float*>(&ul);
}
long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder) long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder)
{ {
if (byteOrder == littleEndian) { if (byteOrder == littleEndian) {
@ -309,6 +316,13 @@ namespace Exiv2 {
return o; return o;
} }
long f2Data(byte* buf, float f, ByteOrder byteOrder)
{
assert(sizeof(float) == 4);
uint32_t ul = *reinterpret_cast<uint32_t*>(&f);
return ul2Data(buf, ul, byteOrder);
}
void hexdump(std::ostream& os, const byte* buf, long len, long offset) void hexdump(std::ostream& os, const byte* buf, long len, long offset)
{ {
const std::string::size_type pos = 8 + 16 * 3 + 2; const std::string::size_type pos = 8 + 16 * 3 + 2;

@ -366,6 +366,8 @@ namespace Exiv2 {
EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder); EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder);
//! Read an 8 byte signed rational value from the data buffer //! Read an 8 byte signed rational value from the data buffer
EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder); EXIV2API Rational getRational(const byte* buf, ByteOrder byteOrder);
//! Read a 4 byte single precision floating point value (IEEE 754 binary32) from the data buffer
EXIV2API float getFloat(const byte* buf, ByteOrder byteOrder);
//! Output operator for our fake rational //! Output operator for our fake rational
EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r); EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r);
@ -406,6 +408,11 @@ namespace Exiv2 {
return number of bytes written. return number of bytes written.
*/ */
EXIV2API long r2Data(byte* buf, Rational l, ByteOrder byteOrder); EXIV2API long r2Data(byte* buf, Rational l, ByteOrder byteOrder);
/*!
@brief Convert a single precision floating point (IEEE 754 binary32) float
to data, write the data to the buffer, return number of bytes written.
*/
EXIV2API long f2Data(byte* buf, float f, ByteOrder byteOrder);
/*! /*!
@brief Print len bytes from buf in hex and ASCII format to the given @brief Print len bytes from buf in hex and ASCII format to the given

@ -76,7 +76,6 @@ namespace Exiv2 {
case invalidTypeId: case invalidTypeId:
case signedByte: case signedByte:
case unsignedByte: case unsignedByte:
case tiffFloat:
case tiffDouble: case tiffDouble:
value = AutoPtr(new DataValue(typeId)); value = AutoPtr(new DataValue(typeId));
break; break;
@ -105,6 +104,9 @@ namespace Exiv2 {
case signedRational: case signedRational:
value = AutoPtr(new ValueType<Rational>); value = AutoPtr(new ValueType<Rational>);
break; break;
case tiffFloat:
value = AutoPtr(new ValueType<float>);
break;
case string: case string:
value = AutoPtr(new StringValue); value = AutoPtr(new StringValue);
break; break;

@ -1209,6 +1209,8 @@ namespace Exiv2 {
template<> inline TypeId getType<int32_t>() { return signedLong; } template<> inline TypeId getType<int32_t>() { return signedLong; }
//! Specialization for a signed rational //! Specialization for a signed rational
template<> inline TypeId getType<Rational>() { return signedRational; } template<> inline TypeId getType<Rational>() { return signedRational; }
//! Specialization for a float
template<> inline TypeId getType<float>() { return tiffFloat; }
// No default implementation: let the compiler/linker complain // No default implementation: let the compiler/linker complain
// template<typename T> inline TypeId getType() { return invalid; } // template<typename T> inline TypeId getType() { return invalid; }
@ -1321,6 +1323,8 @@ namespace Exiv2 {
typedef ValueType<int32_t> LongValue; typedef ValueType<int32_t> LongValue;
//! Signed rational value type //! Signed rational value type
typedef ValueType<Rational> RationalValue; typedef ValueType<Rational> RationalValue;
//! Float value type
typedef ValueType<float> FloatValue;
// ***************************************************************************** // *****************************************************************************
// free functions, template and inline definitions // free functions, template and inline definitions
@ -1373,6 +1377,12 @@ namespace Exiv2 {
{ {
return getRational(buf, byteOrder); return getRational(buf, byteOrder);
} }
// Specialization for a 4 byte float value.
template<>
inline float getValue(const byte* buf, ByteOrder byteOrder)
{
return getFloat(buf, byteOrder);
}
/*! /*!
@brief Convert a value of type T to data, write the data to the data buffer. @brief Convert a value of type T to data, write the data to the data buffer.
@ -1441,6 +1451,15 @@ namespace Exiv2 {
{ {
return r2Data(buf, t, byteOrder); return r2Data(buf, t, byteOrder);
} }
/*!
@brief Specialization to write a float to the data buffer.
Return the number of bytes written.
*/
template<>
inline long toData(byte* buf, float t, ByteOrder byteOrder)
{
return f2Data(buf, t, byteOrder);
}
template<typename T> template<typename T>
ValueType<T>::ValueType() ValueType<T>::ValueType()
@ -1640,6 +1659,14 @@ namespace Exiv2 {
ok_ = true; ok_ = true;
return Rational(value_[n].first, value_[n].second); return Rational(value_[n].first, value_[n].second);
} }
// Specialization for float.
template<>
inline Rational ValueType<float>::toRational(long n) const
{
ok_ = true;
// Warning: This is a very simple conversion, see floatToRationalCast()
return floatToRationalCast(value_[n]);
}
template<typename T> template<typename T>
long ValueType<T>::sizeDataArea() const long ValueType<T>::sizeDataArea() const

Loading…
Cancel
Save