libopenraw
dngfile.cpp
1 /*
2  * libopenraw - dngfile.cpp
3  *
4  * Copyright (C) 2006-2017 Hubert Figuière
5  * Copyright (C) 2008 Novell, Inc.
6  *
7  * This library is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation, either version 3 of
10  * the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see
19  * <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <stddef.h>
23 
24 #include <string>
25 #include <memory>
26 
27 #include <libopenraw/cameraids.h>
28 #include <libopenraw/debug.h>
29 
30 #include "rawdata.hpp"
31 #include "trace.hpp"
32 #include "io/memstream.hpp"
33 #include "jfifcontainer.hpp"
34 #include "ljpegdecompressor.hpp"
35 #include "ifd.hpp"
36 #include "ifddir.hpp"
37 #include "ifdentry.hpp"
38 #include "dngfile.hpp"
39 
40 using namespace Debug;
41 
42 namespace OpenRaw {
43 namespace Internals {
44 
45 const IfdFile::camera_ids_t DngFile::s_def[] = {
46  { "PENTAX K10D ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
47  OR_TYPEID_PENTAX_K10D_DNG) },
48  { "PENTAX Q ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
49  OR_TYPEID_PENTAX_Q_DNG) },
50  { "PENTAX K200D ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
51  OR_TYPEID_PENTAX_K200D_DNG) },
52  { "PENTAX Q10 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
53  OR_TYPEID_PENTAX_Q10_DNG) },
54  { "PENTAX Q7 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
55  OR_TYPEID_PENTAX_Q7_DNG) },
56  { "PENTAX QS-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
57  OR_TYPEID_PENTAX_QS1_DNG) },
58  { "PENTAX K-x ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
59  OR_TYPEID_PENTAX_KX_DNG) },
60  { "PENTAX K-r ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
61  OR_TYPEID_PENTAX_KR_DNG) },
62  { "PENTAX K-01 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
63  OR_TYPEID_PENTAX_K01_DNG) },
64  { "PENTAX K-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
65  OR_TYPEID_PENTAX_K1_DNG) },
66  { "PENTAX K-30 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
67  OR_TYPEID_PENTAX_K30_DNG) },
68  { "PENTAX K-5 II s ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
69  OR_TYPEID_PENTAX_K5_IIS_DNG) },
70  { "PENTAX K-50 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
71  OR_TYPEID_PENTAX_K50_DNG) },
72  { "PENTAX K-500 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
73  OR_TYPEID_PENTAX_K500_DNG) },
74  { "PENTAX K-3 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
75  OR_TYPEID_PENTAX_K3_DNG) },
76  { "PENTAX K-3 II ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
77  OR_TYPEID_PENTAX_K3_II_DNG) },
78  { "PENTAX K-70 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
79  OR_TYPEID_PENTAX_K70_DNG) },
80  { "PENTAX K-S1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
81  OR_TYPEID_PENTAX_KS1_DNG) },
82  { "PENTAX KP ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
83  OR_TYPEID_PENTAX_KP_DNG) },
84  { "PENTAX MX-1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PENTAX,
85  OR_TYPEID_PENTAX_MX1_DNG) },
86  { "R9 - Digital Back DMR", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
87  OR_TYPEID_LEICA_DMR) },
88  { "M8 Digital Camera", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
89  OR_TYPEID_LEICA_M8) },
90  { "M9 Digital Camera", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
91  OR_TYPEID_LEICA_M9) },
92  { "M Monochrom", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
93  OR_TYPEID_LEICA_M_MONOCHROM) },
94  { "LEICA M (Typ 240)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
95  OR_TYPEID_LEICA_M_TYP240) },
96  { "LEICA M10", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
97  OR_TYPEID_LEICA_M10) },
98  { "LEICA X1 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
99  OR_TYPEID_LEICA_X1) },
100  { "LEICA X2", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
101  OR_TYPEID_LEICA_X2) },
102  { "Leica S2", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
103  OR_TYPEID_LEICA_S2) },
104  { "LEICA X VARIO (Typ 107)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
105  OR_TYPEID_LEICA_X_VARIO) },
106  { "LEICA X (Typ 113)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
107  OR_TYPEID_LEICA_X_TYP113) },
108  { "LEICA SL (Typ 601)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
109  OR_TYPEID_LEICA_SL_TYP601) },
110  { "LEICA T (Typ 701)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
111  OR_TYPEID_LEICA_T_TYP701) },
112  { "LEICA Q (Typ 116)", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
113  OR_TYPEID_LEICA_Q_TYP116) },
114  { "GR DIGITAL 2 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
115  OR_TYPEID_RICOH_GR2) },
116  { "GR ",
117  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
118  OR_TYPEID_RICOH_GR) },
119  { "GXR ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
120  OR_TYPEID_RICOH_GXR) },
121  { "GXR A16 ",
122  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GXR_A16) },
123  { "SAMSUNG GX10 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG,
124  OR_TYPEID_SAMSUNG_GX10) },
125  { "Pro 815 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG,
126  OR_TYPEID_SAMSUNG_PRO815) },
127  { "M1", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_XIAOYI,
128  OR_TYPEID_XIAOYI_M1) },
129  { "iPhone 6s Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE,
130  OR_TYPEID_APPLE_IPHONE_6SPLUS) },
131  { "iPhone 7 Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE,
132  OR_TYPEID_APPLE_IPHONE_7PLUS) },
133  { 0, OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE,
134  OR_TYPEID_ADOBE_DNG_GENERIC) }
135 };
136 
137 RawFile *DngFile::factory(const IO::Stream::Ptr &s)
138 {
139  return new DngFile(s);
140 }
141 
142 
143 DngFile::DngFile(const IO::Stream::Ptr &s)
144  : TiffEpFile(s, OR_RAWFILE_TYPE_DNG)
145 {
146  _setIdMap(s_def);
147 }
148 
149 DngFile::~DngFile()
150 {
151 }
152 
153 ::or_error DngFile::_getRawData(RawData & data, uint32_t options)
154 {
155  ::or_error ret = OR_ERROR_NONE;
156  const IfdDir::Ref & _cfaIfd = cfaIfd();
157 
158  LOGDBG1("_getRawData()\n");
159 
160  if (!_cfaIfd) {
161  LOGDBG1("cfaIfd is NULL: not found\n");
162  return OR_ERROR_NOT_FOUND;
163  }
164  ret = _getRawDataFromDir(data, _cfaIfd);
165 
166  if(ret != OR_ERROR_NONE) {
167  LOGERR("couldn't find raw data\n");
168  return ret;
169  }
170 
171  auto result = _cfaIfd->getValue<uint16_t>(IFD::EXIF_TAG_COMPRESSION);
172  if (result.ok() && (result.unwrap() == IFD::COMPRESS_LJPEG)) {
173  // if the option is not set, decompress
174  if ((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
175  IO::Stream::Ptr s(
176  std::make_shared<IO::MemStream>(data.data(),
177  data.size()));
178  s->open(); // TODO check success
179  std::unique_ptr<JfifContainer> jfif(new JfifContainer(s, 0));
180  LJpegDecompressor decomp(s.get(), jfif.get());
181  RawDataPtr dData = decomp.decompress();
182  if (dData) {
183  dData->setCfaPattern(data.cfaPattern());
184  data.swap(*dData);
185  }
186  }
187  }
188  else {
189  data.setDataType(OR_DATA_TYPE_RAW);
190  }
191  uint32_t crop_x, crop_y, crop_w, crop_h;
192  IfdEntry::Ref e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_ORIGIN);
193  if(e) {
194  crop_x = e->getIntegerArrayItem(0);
195  crop_y = e->getIntegerArrayItem(1);
196  }
197  else {
198  crop_x = crop_y = 0;
199  }
200  e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_SIZE);
201  if(e) {
202  crop_w = e->getIntegerArrayItem(0);
203  crop_h = e->getIntegerArrayItem(1);
204  }
205  else {
206  crop_w = data.width();
207  crop_h = data.height();
208  }
209  data.setRoi(crop_x, crop_y, crop_w, crop_h);
210 
211  return ret;
212 }
213 
214 void DngFile::_identifyId()
215 {
216  TiffEpFile::_identifyId();
217  // XXX what if the DNG file match the non DNG?
218  // XXX maybe we should hint of the type in the camera ID table
219  if (OR_GET_FILE_TYPEID_CAMERA(_typeId()) == 0) {
220  const IfdDir::Ref & _mainIfd = mainIfd();
221 
222  auto uniqueCameraModel =
223  _mainIfd->getValue<std::string>(IFD::DNG_TAG_UNIQUE_CAMERA_MODEL);
224  if (uniqueCameraModel.ok()) {
225  // set a generic DNG type if we found a
226  // unique camera model
227  _setTypeId(
228  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE,
229  OR_TYPEID_ADOBE_DNG_GENERIC));
230  }
231  }
232 }
233 
234 }
235 }
236 /*
237  Local Variables:
238  mode:c++
239  c-file-style:"stroustrup"
240  c-file-offsets:((innamespace . 0))
241  indent-tabs-mode:nil
242  fill-column:80
243  End:
244 */
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
virtual RawDataPtr decompress() override
size_t size() const
Definition: bitmapdata.cpp:129
void swap(RawData &with)
Definition: rawdata.cpp:245
std::shared_ptr< IfdEntry > Ref
Definition: ifdentry.hpp:165
Definition: trace.cpp:30
const CfaPattern * cfaPattern() const
Definition: rawdata.cpp:287
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
virtual ::or_error _getRawData(RawData &data, uint32_t options) override
Definition: dngfile.cpp:153