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