libopenraw
|
00001 /* 00002 * libopenraw - mrwcontainer.h 00003 * 00004 * Copyright (C) 2006 Hubert Figuiere 00005 * Copyright (C) 2008 Bradley Broom 00006 * 00007 * This library is free software: you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public License 00009 * as published by the Free Software Foundation, either version 3 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library. If not, see 00019 * <http://www.gnu.org/licenses/>. 00020 */ 00021 00022 00023 #ifndef _MRW_CONTAINER_H__ 00024 #define _MRW_CONTAINER_H__ 00025 00026 #include <string> 00027 #include <boost/config.hpp> 00028 #include <boost/shared_ptr.hpp> 00029 00030 #include "ifdfilecontainer.h" 00031 00032 namespace OpenRaw { 00033 namespace Internals { 00034 00035 class IOFile; 00036 00037 class MRWContainer; 00038 00039 namespace MRW { 00040 00041 const int DataBlockHeaderLength = 8; /* Number of bytes in a block header. */ 00042 00045 class DataBlock 00046 { 00047 public: 00048 typedef boost::shared_ptr<DataBlock> Ref; 00049 typedef std::vector<Ref> RefVec; 00050 00055 DataBlock(off_t start, MRWContainer * container); 00056 00059 off_t offset() 00060 { 00061 return m_start; 00062 } 00063 00066 off_t length() 00067 { 00068 return m_length; 00069 } 00070 00073 std::string name() 00074 { 00075 char id[4]; 00076 id[0] = m_name[1]; 00077 id[1] = m_name[2]; 00078 id[2] = m_name[3]; 00079 id[3] = 0; 00080 return std::string(id); 00081 } 00082 00085 int8_t int8_val (off_t offset); 00086 00089 uint8_t uint8_val (off_t offset); 00090 00093 uint16_t uint16_val (off_t offset); 00094 00095 std::string string_val(off_t offset); 00096 00097 bool loaded() const 00098 { 00099 return m_loaded; 00100 } 00101 00102 private: 00103 /* DRM: protection from copies. */ 00104 DataBlock(const DataBlock &); 00105 DataBlock & operator=(const DataBlock &); 00106 00107 off_t m_start; 00108 char m_name[4]; 00109 int32_t m_length; 00110 MRWContainer *m_container; 00111 bool m_loaded; 00112 }; 00113 00114 /* Known offsets in PRD block. 00115 */ 00116 enum { 00117 PRD_VERSION = 0, /* 8 chars, version string */ 00118 PRD_SENSOR_LENGTH = 8, /* 2 bytes, Number of lines in raw data */ 00119 PRD_SENSOR_WIDTH = 10, /* 2 bytes, Number of pixels per line */ 00120 PRD_IMAGE_LENGTH = 12, /* 2 bytes, length of image after Divu processing */ 00121 PRD_IMAGE_WIDTH = 14, /* 2 bytes, width of image after Divu processing */ 00122 PRD_DATA_SIZE = 16, /* 1 byte, number of bits used to store each pixel */ 00123 PRD_PIXEL_SIZE = 17, /* 1 byte, number of valid bits per pixel */ 00124 PRD_STORAGE_TYPE = 18, /* 1 byte, storage method */ 00125 PRD_UNKNOWN1 = 19, /* 1 byte */ 00126 PRD_UNKNOWN2 = 20, /* 2 bytes */ 00127 PRD_BAYER_PATTERN = 22 /* 2 bytes, CFA pattern */ 00128 }; 00129 00130 enum { 00131 STORAGE_TYPE_UNPACKED = 0x52, /* Unpacked storage (D5, D7xx) */ 00132 STORAGE_TYPE_PACKED = 0x59 /* Packed storage (A1, A2, Maxxum/Dynax) */ 00133 }; 00134 00135 enum { 00136 BAYER_PATTERN_RGGB = 0x0001, 00137 BAYER_PATTERN_GBRG = 0x0004 /* A200 */ 00138 }; 00139 00140 /* Known offsets in WBG block. 00141 */ 00142 enum { 00143 WBG_DENOMINATOR_R = 0, /* 1 byte, log2(denominator)-6 */ 00144 WBG_DENOMINATOR_G1 = 1, /* 1 byte, To get actual denominator, 1<<(val+6) */ 00145 WBG_DENOMINATOR_G2 = 2, /* 1 byte, */ 00146 WBG_DENOMINATOR_B = 3, /* 1 byte, */ 00147 WBG_NOMINATOR_R = 4, /* 2 bytes, */ 00148 WBG_NOMINATOR_G1 = 6, /* 2 bytes, */ 00149 WBG_NOMINATOR_G2 = 8, /* 2 bytes, */ 00150 WBG_NOMINATOR_B = 10 /* 2 bytes, */ 00151 }; 00152 00153 /* Known offsets in RIF block. 00154 */ 00155 enum { 00156 RIF_UNKNOWN1 = 0, /* 1 byte, */ 00157 RIF_SATURATION = 1, /* 1 byte, saturation setting from -3 to 3 */ 00158 RIF_CONTRAST = 2, /* 1 byte, contrast setting from -3 to 3 */ 00159 RIF_SHARPNESS = 3, /* 1 byte, sharpness setting from -1 (soft) to 1 (hard) */ 00160 RIF_WHITE_BALANCE = 4, /* 1 byte, white balance setting */ 00161 RIF_SUBJECT_PROGRAM = 5, /* 1 byte, subject program setting */ 00162 RIF_FILM_SPEED = 6, /* 1 byte, iso = 2^(value/8-1) * 3.125 */ 00163 RIF_COLOR_MODE = 7, /* 1 byte, color mode setting */ 00164 RIF_COLOR_FILTER = 56, /* 1 byte, color filter setting from -3 to 3 */ 00165 RIF_BANDW_FILTER = 57 /* 1 byte, black and white filter setting from 0 to 10 */ 00166 }; 00167 00168 enum { 00169 WHITE_BALANCE_AUTO = 0, 00170 WHITE_BALANCE_DAYLIGHT = 1, 00171 WHITE_BALANCE_CLOUDY = 2, 00172 WHITE_BALANCE_TUNGSTEN = 3, 00173 WHITE_BALANCE_FLUORESCENT = 4 00174 }; 00175 00176 enum { 00177 SUBJECT_PROGRAM_NONE = 0, 00178 SUBJECT_PROGRAM_PORTRAIT = 1, 00179 SUBJECT_PROGRAM_TEXT = 2, 00180 SUBJECT_PROGRAM_NIGHT_PORTRAIT = 3, 00181 SUBJECT_PROGRAM_SUNSET = 4, 00182 SUBJECT_PROGRAM_SPORTS_ACTION = 5 00183 }; 00184 00185 enum { 00186 COLOR_MODE_NORMAL = 0, 00187 COLOR_MODE_BLACK_AND_WHITE = 1, 00188 COLOR_MODE_VIVID_COLOR = 2, /* D7i, D7Hi */ 00189 COLOR_MODE_SOLARIZATION = 3, /* D7i, D7Hi */ 00190 COLOR_MODE_ADOBE_RGB = 4 /* D7Hi */ 00191 }; 00192 00193 00194 /* Known tags found in the main IFD directory. 00195 */ 00196 enum { 00197 IFDTAG_WIDTH = 0x0100, /* Image width. */ 00198 IFDTAG_HEIGHT = 0x0101, /* Image height. */ 00199 IFDTAG_COMPRESS = 0x0103, /* Compression. */ 00200 IFDTAG_DCFVER = 0x010E, /* DCF version (string). */ 00201 IFDTAG_MANUF = 0x010F, /* Manufacturer (string). */ 00202 IFDTAG_CAMERA = 0x0110, /* Camera name (string). */ 00203 IFDTAG_FIRMWARE = 0x0131, /* Firmware version (string). */ 00204 IFDTAG_DATETIME = 0x0132, /* Date time (string). */ 00205 IFDTAG_EXIFOFFSET = 0x8769, /* Offset of EXIF data (long). */ 00206 IFDTAG_PIMOFFSET = 0xC4A5 /* Offset of PIM info (some cameras only). */ 00207 }; 00208 00209 /* Known tags found in the Manufacturer's directory. */ 00210 enum { 00211 MRWTAG_THUMBNAIL = 0x0081, /* Offset to Thumbnail data (early cameras only). */ 00212 MRWTAG_THUMBNAIL_OFFSET = 0x0088, 00213 MRWTAG_THUMBNAIL_LENGTH = 0x0089 00214 }; 00215 00216 00217 } 00218 00221 class MRWContainer 00222 : public IFDFileContainer 00223 { 00224 public: 00225 MRWContainer(IO::Stream *file, off_t offset = 0); 00227 virtual ~MRWContainer(); 00228 00232 virtual IFDFileContainer::EndianType 00233 isMagicHeader(const char *p, int len); 00234 00235 /* Known datablocks within an MRW file. 00236 */ 00237 MRW::DataBlock::Ref mrm; 00238 MRW::DataBlock::Ref prd; 00239 MRW::DataBlock::Ref ttw; 00240 MRW::DataBlock::Ref wbg; 00241 MRW::DataBlock::Ref rif; 00242 00245 off_t pixelDataOffset() 00246 { 00247 /* The pixel data immediately follows the MRM datablock. */ 00248 return mrm->offset() + MRW::DataBlockHeaderLength + mrm->length(); 00249 } 00250 protected: 00251 virtual bool locateDirsPreHook(); 00252 private: 00253 std::string m_version; 00254 00255 /* DRM: restrict copying. */ 00256 MRWContainer(const MRWContainer &); 00257 MRWContainer & operator=(const MRWContainer &); 00258 }; 00259 00260 00261 } 00262 } 00263 00264 #endif