1 /*
2     RawSpeed - RAW file decoder.
3 
4     Copyright (C) 2009-2014 Klaus Post
5     Copyright (C) 2015 Pedro Côrte-Real
6     Copyright (C) 2017 Axel Waggershauser
7 
8     This library is free software; you can redistribute it and/or
9     modify it under the terms of the GNU Lesser General Public
10     License as published by the Free Software Foundation; either
11     version 2 of the License, or (at your option) any later version.
12 
13     This library is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16     Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with this library; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22 
23 #pragma once
24 
25 #include "io/ByteStream.h" // for ByteStream
26 #include "tiff/TiffTag.h"  // for TiffTag
27 #include <array>           // for array
28 #include <cstdint>         // for uint32_t, uint16_t, uint8_t, int16_t, int...
29 #include <string>          // for string
30 #include <vector>          // for vector
31 
32 namespace rawspeed {
33 
34 class DataBuffer;
35 
36 class TiffIFD;
37 
38 /*
39  * Tag data type information.
40  *
41  * Note: RATIONALs are the ratio of two 32-bit integer values.
42  */
43 enum TiffDataType {
44   TIFF_NOTYPE    = 0, /* placeholder */
45   TIFF_BYTE      = 1, /* 8-bit unsigned integer */
46   TIFF_ASCII     = 2, /* 8-bit bytes w/ last byte null */
47   TIFF_SHORT     = 3, /* 16-bit unsigned integer */
48   TIFF_LONG      = 4, /* 32-bit unsigned integer */
49   TIFF_RATIONAL  = 5, /* 64-bit unsigned fraction */
50   TIFF_SBYTE     = 6, /* !8-bit signed integer */
51   TIFF_UNDEFINED = 7, /* !8-bit untyped data */
52   TIFF_SSHORT    = 8, /* !16-bit signed integer */
53   TIFF_SLONG     = 9, /* !32-bit signed integer */
54   TIFF_SRATIONAL = 10, /* !64-bit signed fraction */
55   TIFF_FLOAT     = 11, /* !32-bit IEEE floating point */
56   TIFF_DOUBLE    = 12, /* !64-bit IEEE floating point */
57   TIFF_OFFSET    = 13, /* 32-bit unsigned offset used for IFD and other offsets */
58 };
59 
60 class TiffEntry
61 {
62   TiffIFD* parent;
63   ByteStream data;
64 
65   friend class TiffIFD;
66 
67   template <typename T, T (TiffEntry::*getter)(uint32_t index) const>
getArray(uint32_t count_)68   std::vector<T> getArray(uint32_t count_) const {
69     std::vector<T> res(count_);
70     for (uint32_t i = 0; i < count_; ++i)
71       res[i] = (this->*getter)(i);
72     return res;
73   }
74 
75 public:
76   TiffTag tag;
77   TiffDataType type;
78   uint32_t count;
79 
80   TiffEntry(TiffIFD* parent, TiffTag tag, TiffDataType type, uint32_t count,
81             ByteStream&& data);
82   TiffEntry(TiffIFD* parent, ByteStream* bs);
83 
84   bool __attribute__((pure)) isFloat() const;
85   bool __attribute__((pure)) isInt() const;
86   bool __attribute__((pure)) isString() const;
87   uint8_t getByte(uint32_t index = 0) const;
88   uint32_t getU32(uint32_t index = 0) const;
89   int32_t getI32(uint32_t index = 0) const;
90   uint16_t getU16(uint32_t index = 0) const;
91   int16_t getI16(uint32_t index = 0) const;
92   float getFloat(uint32_t index = 0) const;
93   std::string getString() const;
94 
getU16Array(uint32_t count_)95   inline std::vector<uint16_t> getU16Array(uint32_t count_) const {
96     return getArray<uint16_t, &TiffEntry::getU16>(count_);
97   }
98 
getU32Array(uint32_t count_)99   inline std::vector<uint32_t> getU32Array(uint32_t count_) const {
100     return getArray<uint32_t, &TiffEntry::getU32>(count_);
101   }
102 
getFloatArray(uint32_t count_)103   inline std::vector<float> getFloatArray(uint32_t count_) const {
104     return getArray<float, &TiffEntry::getFloat>(count_);
105   }
106 
getData()107   ByteStream& getData() { return data; }
getData(uint32_t size)108   const uint8_t* getData(uint32_t size) { return data.getData(size); }
109 
110   const DataBuffer& getRootIfdData() const;
111 
112 protected:
113   static const std::array<uint32_t, 14> datashifts;
114 };
115 
116 } // namespace rawspeed
117