From bc54748634695aaef80a426ba02e00df1b7a66a4 Mon Sep 17 00:00:00 2001 From: Andreas Huggel Date: Thu, 22 Jul 2010 02:41:02 +0000 Subject: [PATCH] #711: Added FloatValue to deal with TIFF Float values. (Nice one! :) --- src/types.cpp | 14 ++++++++++++++ src/types.hpp | 7 +++++++ src/value.cpp | 4 +++- src/value.hpp | 27 +++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/types.cpp b/src/types.cpp index 3116136f..f3b740bf 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -235,6 +235,13 @@ namespace Exiv2 { 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(&ul); + } + long us2Data(byte* buf, uint16_t s, ByteOrder byteOrder) { if (byteOrder == littleEndian) { @@ -309,6 +316,13 @@ namespace Exiv2 { return o; } + long f2Data(byte* buf, float f, ByteOrder byteOrder) + { + assert(sizeof(float) == 4); + uint32_t ul = *reinterpret_cast(&f); + return ul2Data(buf, ul, byteOrder); + } + void hexdump(std::ostream& os, const byte* buf, long len, long offset) { const std::string::size_type pos = 8 + 16 * 3 + 2; diff --git a/src/types.hpp b/src/types.hpp index af4d8aa9..0dcfa5c4 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -366,6 +366,8 @@ namespace Exiv2 { EXIV2API int32_t getLong(const byte* buf, ByteOrder byteOrder); //! Read an 8 byte signed rational value from the data buffer 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 EXIV2API std::ostream& operator<<(std::ostream& os, const Rational& r); @@ -406,6 +408,11 @@ namespace Exiv2 { return number of bytes written. */ 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 diff --git a/src/value.cpp b/src/value.cpp index 7aa6051a..6e101e6d 100644 --- a/src/value.cpp +++ b/src/value.cpp @@ -76,7 +76,6 @@ namespace Exiv2 { case invalidTypeId: case signedByte: case unsignedByte: - case tiffFloat: case tiffDouble: value = AutoPtr(new DataValue(typeId)); break; @@ -105,6 +104,9 @@ namespace Exiv2 { case signedRational: value = AutoPtr(new ValueType); break; + case tiffFloat: + value = AutoPtr(new ValueType); + break; case string: value = AutoPtr(new StringValue); break; diff --git a/src/value.hpp b/src/value.hpp index d47c3450..e8d1248e 100644 --- a/src/value.hpp +++ b/src/value.hpp @@ -1209,6 +1209,8 @@ namespace Exiv2 { template<> inline TypeId getType() { return signedLong; } //! Specialization for a signed rational template<> inline TypeId getType() { return signedRational; } + //! Specialization for a float + template<> inline TypeId getType() { return tiffFloat; } // No default implementation: let the compiler/linker complain // template inline TypeId getType() { return invalid; } @@ -1321,6 +1323,8 @@ namespace Exiv2 { typedef ValueType LongValue; //! Signed rational value type typedef ValueType RationalValue; + //! Float value type + typedef ValueType FloatValue; // ***************************************************************************** // free functions, template and inline definitions @@ -1373,6 +1377,12 @@ namespace Exiv2 { { 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. @@ -1441,6 +1451,15 @@ namespace Exiv2 { { 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 ValueType::ValueType() @@ -1640,6 +1659,14 @@ namespace Exiv2 { ok_ = true; return Rational(value_[n].first, value_[n].second); } + // Specialization for float. + template<> + inline Rational ValueType::toRational(long n) const + { + ok_ = true; + // Warning: This is a very simple conversion, see floatToRationalCast() + return floatToRationalCast(value_[n]); + } template long ValueType::sizeDataArea() const