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
38namespace OpenRaw {
39namespace Internals {
40
41class MRWContainer;
42
43namespace MRW {
44
45const int DataBlockHeaderLength = 8; /* Number of bytes in a block header. */
46
49class DataBlock {
50public:
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
88
93
94 Option<std::string> string_val(off_t offset);
95
96 bool loaded() const { return m_loaded; }
97
98private:
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 */
112enum {
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
126enum {
127 STORAGE_TYPE_UNPACKED = 0x52, /* Unpacked storage (D5, D7xx) */
128 STORAGE_TYPE_PACKED = 0x59 /* Packed storage (A1, A2, Maxxum/Dynax) */
129};
130
131enum {
132 BAYER_PATTERN_RGGB = 0x0001,
133 BAYER_PATTERN_GBRG = 0x0004 /* A200 */
134};
135
136/* Known offsets in WBG block.
137 */
138enum {
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 */
151enum {
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
166enum {
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
174enum {
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
183enum {
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 */
193enum {
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. */
207enum {
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
218public:
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
242 /* The pixel data immediately follows the MRM datablock. */
243 return mrm->offset() + MRW::DataBlockHeaderLength + mrm->length();
244 }
245
246protected:
247 virtual bool locateDirsPreHook() override;
248
249private:
250 std::string m_version;
251
252};
253}
254}
255
256#endif
virtual bool locateDirsPreHook() override
virtual IfdFileContainer::EndianType isMagicHeader(const char *p, int len) override
Option< uint8_t > uint8_val(off_t offset)
Option< int8_t > int8_val(off_t offset)
Option< uint16_t > uint16_val(off_t offset)
DataBlock(off_t start, MRWContainer *container)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30