libopenraw
|
00001 /* 00002 * libopenraw - ciffcontainer.h 00003 * 00004 * Copyright (C) 2006,2008 Hubert Figuiere 00005 * 00006 * This library is free software: you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public License 00008 * as published by the Free Software Foundation, either version 3 of 00009 * the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library. If not, see 00018 * <http://www.gnu.org/licenses/>. 00019 */ 00020 00027 #ifndef _CIFFCONTAINER_H_ 00028 #define _CIFFCONTAINER_H_ 00029 00030 #include <vector> 00031 #include <boost/shared_ptr.hpp> 00032 00033 #include "rawcontainer.h" 00034 #include "trace.h" 00035 00036 namespace OpenRaw { 00037 namespace Internals { 00038 00039 class CIFFContainer; 00040 00041 namespace CIFF { 00042 00044 enum { 00045 STORAGELOC_MASK = 0xc000, 00046 FORMAT_MASK = 0x3800, 00047 TAGCODE_MASK = 0x3fff 00049 }; 00054 enum { 00055 TAG_NULLRECORD = 0x0000, 00056 TAG_FREEBYTES = 0x0001, 00057 TAG_COLORINFO1 = 0x0032, 00058 TAG_FILEDESCRIPTION = 0x0805, 00059 TAG_RAWMAKEMODEL = 0x080a, 00060 TAG_FIRMWAREVERSION = 0x080b, 00061 TAG_COMPONENTVERSION = 0x080c, 00062 TAG_ROMOPERATIONMODE = 0x080d, 00063 TAG_OWNERNAME = 0x0810, 00064 TAG_IMAGETYPE = 0x0815, 00065 TAG_ORIGINALFILENAME = 0x0816, 00066 TAG_THUMBNAILFILENAME = 0x0817, 00067 00068 TAG_TARGETIMAGETYPE = 0x100a, 00069 TAG_SHUTTERRELEASEMETHOD = 0x1010, 00070 TAG_SHUTTERRELEASETIMING = 0x1011, 00071 TAG_RELEASESETTING = 0x1016, 00072 TAG_BASEISO = 0x101c, 00073 TAG_FOCALLENGTH = 0x1029, 00074 TAG_SHOTINFO = 0x102a, 00075 TAG_COLORINFO2 = 0x102c, 00076 TAG_CAMERASETTINGS = 0x102d, 00077 TAG_SENSORINFO = 0x1031, 00078 TAG_CUSTOMFUNCTIONS = 0x1033, 00079 TAG_PICTUREINFO = 0x1038, 00080 TAG_WHITEBALANCETABLE = 0x10a9, 00081 TAG_COLORSPACE = 0x10b4, 00082 00083 TAG_IMAGESPEC = 0x1803, 00084 TAG_RECORDID = 0x1804, 00085 TAG_SELFTIMERTIME = 0x1806, 00086 TAG_TARGETDISTANCESETTING = 0x1807, 00087 TAG_SERIALNUMBER = 0x180b, 00088 TAG_CAPTUREDTIME = 0x180e, 00089 TAG_IMAGEINFO = 0x1810, 00090 TAG_FLASHINFO = 0x1813, 00091 TAG_MEASUREDEV = 0x1814, 00092 TAG_FILENUMBER = 0x1817, 00093 TAG_EXPOSUREINFO = 0x1818, 00094 TAG_DECODERTABLE = 0x1835, 00095 00096 TAG_RAWIMAGEDATA = 0x2005, 00097 TAG_JPEGIMAGE = 0x2007, 00098 TAG_JPEGTHUMBNAIL = 0x2008, 00099 00100 TAG_IMAGEDESCRIPTION = 0x2804, 00101 TAG_CAMERAOBJECT = 0x2807, 00102 TAG_SHOOTINGRECORD = 0x3002, 00103 TAG_MEASUREDINFO = 0x3003, 00104 TAG_CAMERASPECIFICATION = 0x3004, 00105 TAG_IMAGEPROPS = 0x300a, 00106 TAG_EXIFINFORMATION = 0x300b 00107 }; 00108 00109 class Heap; 00110 00111 00112 class ImageSpec 00113 { 00114 public: 00115 ImageSpec() 00116 : imageWidth(0), imageHeight(0), 00117 pixelAspectRatio(0), rotationAngle(0), 00118 componentBitDepth(0), colorBitDepth(0), 00119 colorBW(0) 00120 { 00121 } 00122 00128 bool readFrom(off_t offset, CIFFContainer *container); 00129 int32_t exifOrientation() const; 00130 00131 uint32_t imageWidth; 00132 uint32_t imageHeight; 00133 uint32_t /*float32*/pixelAspectRatio; 00134 int32_t rotationAngle; 00135 uint32_t componentBitDepth; 00136 uint32_t colorBitDepth; 00137 uint32_t colorBW; 00138 }; 00139 00140 00141 class RecordEntry 00142 { 00143 public: 00144 typedef std::vector<RecordEntry> List; 00145 00146 RecordEntry(); 00147 00152 bool readFrom(CIFFContainer *container); 00159 size_t fetchData(Heap* heap, void* buf, size_t size) const; 00164 bool isA(uint16_t _typeCode) const 00165 { 00166 Debug::Trace(DEBUG2) << "typeCode = " << typeCode << "\n"; 00167 return typeCode == (TAGCODE_MASK & _typeCode); 00168 } 00169 00170 uint16_t typeCode;/* type code of the record */ 00171 uint32_t length;/* record length */ 00172 uint32_t offset;/* offset of the record in the heap*/ 00173 }; 00174 00176 class Heap 00177 { 00178 public: 00179 typedef boost::shared_ptr<Heap> Ref; 00180 00186 Heap(off_t start, off_t length, CIFFContainer * container); 00187 00188 RecordEntry::List & records(); 00189 CIFFContainer *container() 00190 { 00191 return m_container; 00192 } 00194 off_t offset() 00195 { 00196 return m_start; 00197 } 00198 private: 00199 bool _loadRecords(); 00200 00201 Heap(const Heap &); 00202 Heap & operator=(const Heap &); 00203 00204 off_t m_start; 00205 off_t m_length; 00206 CIFFContainer *m_container; 00207 RecordEntry::List m_records; 00208 }; 00209 00210 00212 class HeapFileHeader 00213 { 00214 public: 00215 bool readFrom(CIFFContainer *); 00216 char byteOrder[2];/* 'MM' for Motorola,'II' for Intel */ 00217 uint32_t headerLength;/* length of header (in bytes) */ 00218 char type[4]; 00219 char subType[4]; 00220 uint32_t version; /* higher word: 0x0001, Lower word: 0x0002 */ 00221 //uint32_t reserved1; 00222 //uint32_t reserved2; 00223 RawContainer::EndianType endian; 00224 }; 00225 } 00226 00230 class CIFFContainer 00231 : public RawContainer 00232 { 00233 public: 00234 CIFFContainer(IO::Stream *file); 00235 virtual ~CIFFContainer(); 00236 00237 CIFF::Heap::Ref heap(); 00238 00239 const CIFF::HeapFileHeader & header() const 00240 { 00241 return m_hdr; 00242 } 00243 CIFF::Heap::Ref getImageProps(); 00244 const CIFF::RecordEntry * getRawDataRecord() const; 00245 const CIFF::ImageSpec * getImageSpec(); 00246 const CIFF::Heap::Ref getCameraProps(); 00247 private: 00248 bool _loadHeap(); 00249 EndianType _readHeader(); 00250 00251 00252 CIFFContainer(const CIFFContainer &); 00253 CIFFContainer & operator=(const CIFFContainer &); 00254 00255 friend class CIFF::HeapFileHeader; 00256 CIFF::HeapFileHeader m_hdr; 00257 CIFF::Heap::Ref m_heap; 00258 CIFF::Heap::Ref m_imageprops; 00259 bool m_hasImageSpec; 00260 CIFF::ImageSpec m_imagespec; 00261 CIFF::Heap::Ref m_cameraprops; 00262 }; 00263 00264 00265 } 00266 } 00267 00268 00269 00270 #endif