libopenraw
mrwcontainer.hpp
1 /* -*- Mode: C++ -*- */
2 /*
3  * libopenraw - mrwcontainer.h
4  *
5  * Copyright (C) 2006-2015 Hubert Figuiere
6  * Copyright (C) 2008 Bradley Broom
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 License
10  * as published by the Free Software Foundation, either version 3 of
11  * 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, see
20  * <http://www.gnu.org/licenses/>.
21  */
22 
23 #ifndef OR_INTERNALS_MRW_CONTAINER_H_
24 #define OR_INTERNALS_MRW_CONTAINER_H_
25 
26 #include <stdint.h>
27 #include <sys/types.h>
28 #include <string>
29 #include <memory>
30 #include <vector>
31 
32 #include "io/stream.hpp"
33 #include "option.hpp"
34 #include "rawcontainer.hpp"
35 
36 #include "ifdfilecontainer.hpp"
37 
38 namespace OpenRaw {
39 namespace Internals {
40 
41 class MRWContainer;
42 
43 namespace MRW {
44 
45 const int DataBlockHeaderLength = 8; /* Number of bytes in a block header. */
46 
49 class DataBlock {
50 public:
51  typedef std::shared_ptr<DataBlock> Ref;
52  typedef std::vector<Ref> RefVec;
53 
58  DataBlock(off_t start, MRWContainer *container);
59 
62  off_t offset() { return m_start; }
63 
66  off_t length() { return m_length; }
67 
70  std::string name() {
71  char id[4];
72  id[0] = m_name[1];
73  id[1] = m_name[2];
74  id[2] = m_name[3];
75  id[3] = 0;
76  return std::string(id);
77  }
78 
83 
87  Option<uint8_t> uint8_val(off_t offset);
88 
92  Option<uint16_t> uint16_val(off_t offset);
93 
94  Option<std::string> string_val(off_t offset);
95 
96  bool loaded() const { return m_loaded; }
97 
98 private:
99  /* DRM: protection from copies. */
100  DataBlock(const DataBlock &);
101  DataBlock &operator=(const DataBlock &);
102 
103  off_t m_start;
104  char m_name[4];
105  int32_t m_length;
106  MRWContainer *m_container;
107  bool m_loaded;
108 };
109 
110 /* Known offsets in PRD block.
111  */
112 enum {
113  PRD_VERSION = 0, /* 8 chars, version string */
114  PRD_SENSOR_LENGTH = 8, /* 2 bytes, Number of lines in raw data */
115  PRD_SENSOR_WIDTH = 10, /* 2 bytes, Number of pixels per line */
116  PRD_IMAGE_LENGTH = 12, /* 2 bytes, length of image after Divu processing */
117  PRD_IMAGE_WIDTH = 14, /* 2 bytes, width of image after Divu processing */
118  PRD_DATA_SIZE = 16, /* 1 byte, number of bits used to store each pixel */
119  PRD_PIXEL_SIZE = 17, /* 1 byte, number of valid bits per pixel */
120  PRD_STORAGE_TYPE = 18, /* 1 byte, storage method */
121  PRD_UNKNOWN1 = 19, /* 1 byte */
122  PRD_UNKNOWN2 = 20, /* 2 bytes */
123  PRD_BAYER_PATTERN = 22 /* 2 bytes, CFA pattern */
124 };
125 
126 enum {
127  STORAGE_TYPE_UNPACKED = 0x52, /* Unpacked storage (D5, D7xx) */
128  STORAGE_TYPE_PACKED = 0x59 /* Packed storage (A1, A2, Maxxum/Dynax) */
129 };
130 
131 enum {
132  BAYER_PATTERN_RGGB = 0x0001,
133  BAYER_PATTERN_GBRG = 0x0004 /* A200 */
134 };
135 
136 /* Known offsets in WBG block.
137  */
138 enum {
139  WBG_DENOMINATOR_R = 0, /* 1 byte, log2(denominator)-6 */
140  WBG_DENOMINATOR_G1 = 1, /* 1 byte, To get actual denominator, 1<<(val+6) */
141  WBG_DENOMINATOR_G2 = 2, /* 1 byte, */
142  WBG_DENOMINATOR_B = 3, /* 1 byte, */
143  WBG_NOMINATOR_R = 4, /* 2 bytes, */
144  WBG_NOMINATOR_G1 = 6, /* 2 bytes, */
145  WBG_NOMINATOR_G2 = 8, /* 2 bytes, */
146  WBG_NOMINATOR_B = 10 /* 2 bytes, */
147 };
148 
149 /* Known offsets in RIF block.
150  */
151 enum {
152  RIF_UNKNOWN1 = 0, /* 1 byte, */
153  RIF_SATURATION = 1, /* 1 byte, saturation setting from -3 to 3 */
154  RIF_CONTRAST = 2, /* 1 byte, contrast setting from -3 to 3 */
155  RIF_SHARPNESS =
156  3, /* 1 byte, sharpness setting from -1 (soft) to 1 (hard) */
157  RIF_WHITE_BALANCE = 4, /* 1 byte, white balance setting */
158  RIF_SUBJECT_PROGRAM = 5, /* 1 byte, subject program setting */
159  RIF_FILM_SPEED = 6, /* 1 byte, iso = 2^(value/8-1) * 3.125 */
160  RIF_COLOR_MODE = 7, /* 1 byte, color mode setting */
161  RIF_COLOR_FILTER = 56, /* 1 byte, color filter setting from -3 to 3 */
162  RIF_BANDW_FILTER =
163  57 /* 1 byte, black and white filter setting from 0 to 10 */
164 };
165 
166 enum {
167  WHITE_BALANCE_AUTO = 0,
168  WHITE_BALANCE_DAYLIGHT = 1,
169  WHITE_BALANCE_CLOUDY = 2,
170  WHITE_BALANCE_TUNGSTEN = 3,
171  WHITE_BALANCE_FLUORESCENT = 4
172 };
173 
174 enum {
175  SUBJECT_PROGRAM_NONE = 0,
176  SUBJECT_PROGRAM_PORTRAIT = 1,
177  SUBJECT_PROGRAM_TEXT = 2,
178  SUBJECT_PROGRAM_NIGHT_PORTRAIT = 3,
179  SUBJECT_PROGRAM_SUNSET = 4,
180  SUBJECT_PROGRAM_SPORTS_ACTION = 5
181 };
182 
183 enum {
184  COLOR_MODE_NORMAL = 0,
185  COLOR_MODE_BLACK_AND_WHITE = 1,
186  COLOR_MODE_VIVID_COLOR = 2, /* D7i, D7Hi */
187  COLOR_MODE_SOLARIZATION = 3, /* D7i, D7Hi */
188  COLOR_MODE_ADOBE_RGB = 4 /* D7Hi */
189 };
190 
191 /* Known tags found in the main IFD directory.
192  */
193 enum {
194  IFDTAG_WIDTH = 0x0100, /* Image width. */
195  IFDTAG_HEIGHT = 0x0101, /* Image height. */
196  IFDTAG_COMPRESS = 0x0103, /* Compression. */
197  IFDTAG_DCFVER = 0x010E, /* DCF version (string). */
198  IFDTAG_MANUF = 0x010F, /* Manufacturer (string). */
199  IFDTAG_CAMERA = 0x0110, /* Camera name (string). */
200  IFDTAG_FIRMWARE = 0x0131, /* Firmware version (string). */
201  IFDTAG_DATETIME = 0x0132, /* Date time (string). */
202  IFDTAG_EXIFOFFSET = 0x8769, /* Offset of EXIF data (long). */
203  IFDTAG_PIMOFFSET = 0xC4A5 /* Offset of PIM info (some cameras only). */
204 };
205 
206 /* Known tags found in the Manufacturer's directory. */
207 enum {
208  MRWTAG_THUMBNAIL =
209  0x0081, /* Offset to Thumbnail data (early cameras only). */
210  MRWTAG_THUMBNAIL_OFFSET = 0x0088,
211  MRWTAG_THUMBNAIL_LENGTH = 0x0089
212 };
213 }
214 
218 public:
219  MRWContainer(const IO::Stream::Ptr &file, off_t offset = 0);
221  virtual ~MRWContainer();
222 
223  MRWContainer(const MRWContainer &) = delete;
224  MRWContainer &operator=(const MRWContainer &) = delete;
225 
229  virtual IfdFileContainer::EndianType isMagicHeader(const char *p, int len) override;
230 
231  /* Known datablocks within an MRW file.
232  */
233  MRW::DataBlock::Ref mrm;
234  MRW::DataBlock::Ref prd;
235  MRW::DataBlock::Ref ttw;
236  MRW::DataBlock::Ref wbg;
237  MRW::DataBlock::Ref rif;
238 
241  off_t pixelDataOffset() {
242  /* The pixel data immediately follows the MRM datablock. */
243  return mrm->offset() + MRW::DataBlockHeaderLength + mrm->length();
244  }
245 
246 protected:
247  virtual bool locateDirsPreHook() override;
248 
249 private:
250  std::string m_version;
251 
252 };
253 }
254 }
255 
256 #endif
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
Definition: arwfile.cpp:30
DataBlock(off_t start, MRWContainer *container)
Option< uint16_t > uint16_val(off_t offset)
Option< int8_t > int8_val(off_t offset)
Option< uint8_t > uint8_val(off_t offset)