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  { "LEICA CL", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA,
115  OR_TYPEID_LEICA_CL) },
116  { "GR DIGITAL 2 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
117  OR_TYPEID_RICOH_GR2) },
118  { "GR ",
119  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
120  OR_TYPEID_RICOH_GR) },
121  { "GXR ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH,
122  OR_TYPEID_RICOH_GXR) },
123  { "GXR A16 ",
124  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_RICOH, OR_TYPEID_RICOH_GXR_A16) },
125  { "SAMSUNG GX10 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG,
126  OR_TYPEID_SAMSUNG_GX10) },
127  { "Pro 815 ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_SAMSUNG,
128  OR_TYPEID_SAMSUNG_PRO815) },
129  { "M1", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_XIAOYI,
130  OR_TYPEID_XIAOYI_M1) },
131  { "iPhone 6s Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE,
132  OR_TYPEID_APPLE_IPHONE_6SPLUS) },
133  { "iPhone 7 Plus", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_APPLE,
134  OR_TYPEID_APPLE_IPHONE_7PLUS) },
135  { 0, OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE,
136  OR_TYPEID_ADOBE_DNG_GENERIC) }
137 };
138 
139 RawFile *DngFile::factory(const IO::Stream::Ptr &s)
140 {
141  return new DngFile(s);
142 }
143 
144 
145 DngFile::DngFile(const IO::Stream::Ptr &s)
146  : TiffEpFile(s, OR_RAWFILE_TYPE_DNG)
147 {
148  _setIdMap(s_def);
149 }
150 
151 DngFile::~DngFile()
152 {
153 }
154 
155 ::or_error DngFile::_getRawData(RawData & data, uint32_t options)
156 {
157  ::or_error ret = OR_ERROR_NONE;
158  const IfdDir::Ref & _cfaIfd = cfaIfd();
159 
160  LOGDBG1("_getRawData()\n");
161 
162  if (!_cfaIfd) {
163  LOGDBG1("cfaIfd is NULL: not found\n");
164  return OR_ERROR_NOT_FOUND;
165  }
166  ret = _getRawDataFromDir(data, _cfaIfd);
167 
168  if(ret != OR_ERROR_NONE) {
169  LOGERR("couldn't find raw data\n");
170  return ret;
171  }
172 
173  auto result = _cfaIfd->getValue<uint16_t>(IFD::EXIF_TAG_COMPRESSION);
174  if (result && (result.value() == IFD::COMPRESS_LJPEG)) {
175  // if the option is not set, decompress
176  if ((options & OR_OPTIONS_DONT_DECOMPRESS) == 0) {
177  IO::Stream::Ptr s(
178  std::make_shared<IO::MemStream>(data.data(),
179  data.size()));
180  s->open(); // TODO check success
181  std::unique_ptr<JfifContainer> jfif(new JfifContainer(s, 0));
182  LJpegDecompressor decomp(s.get(), jfif.get());
183  RawDataPtr dData = decomp.decompress();
184  if (dData) {
185  dData->setCfaPattern(data.cfaPattern());
186  data.swap(*dData);
187  }
188  }
189  }
190  else {
191  data.setDataType(OR_DATA_TYPE_RAW);
192  }
193  uint32_t crop_x, crop_y, crop_w, crop_h;
194  IfdEntry::Ref e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_ORIGIN);
195  if(e) {
196  crop_x = e->getIntegerArrayItem(0);
197  crop_y = e->getIntegerArrayItem(1);
198  }
199  else {
200  crop_x = crop_y = 0;
201  }
202  e = _cfaIfd->getEntry(IFD::DNG_TAG_DEFAULT_CROP_SIZE);
203  if(e) {
204  crop_w = e->getIntegerArrayItem(0);
205  crop_h = e->getIntegerArrayItem(1);
206  }
207  else {
208  crop_w = data.width();
209  crop_h = data.height();
210  }
211  data.setRoi(crop_x, crop_y, crop_w, crop_h);
212 
213  return ret;
214 }
215 
216 void DngFile::_identifyId()
217 {
218  TiffEpFile::_identifyId();
219  // XXX what if the DNG file match the non DNG?
220  // XXX maybe we should hint of the type in the camera ID table
221  if (OR_GET_FILE_TYPEID_CAMERA(_typeId()) == 0) {
222  const IfdDir::Ref & _mainIfd = mainIfd();
223 
224  auto uniqueCameraModel =
225  _mainIfd->getValue<std::string>(IFD::DNG_TAG_UNIQUE_CAMERA_MODEL);
226  if (uniqueCameraModel) {
227  // set a generic DNG type if we found a
228  // unique camera model
229  _setTypeId(
230  OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_ADOBE,
231  OR_TYPEID_ADOBE_DNG_GENERIC));
232  }
233  }
234 }
235 
236 }
237 }
238 /*
239  Local Variables:
240  mode:c++
241  c-file-style:"stroustrup"
242  c-file-offsets:((innamespace . 0))
243  indent-tabs-mode:nil
244  fill-column:80
245  End:
246 */
OpenRaw::Internals::LJpegDecompressor
Definition: ljpegdecompressor.hpp:48
OpenRaw::Internals::IfdFile::cfaIfd
const IfdDir::Ref & cfaIfd()
Definition: ifdfile.cpp:332
OpenRaw::RawFile::_typeId
TypeId _typeId() const
Definition: rawfile.cpp:343
OpenRaw::Internals::DngFile::_getRawData
virtual ::or_error _getRawData(RawData &data, uint32_t options) override
Definition: dngfile.cpp:155
OpenRaw::BitmapData::size
size_t size() const
Definition: bitmapdata.cpp:129
OpenRaw
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition: arwfile.cpp:30
OpenRaw::Internals::JfifContainer
Definition: jfifcontainer.hpp:51
OpenRaw::RawFile::_setTypeId
void _setTypeId(TypeId _type_id)
Definition: rawfile.cpp:348
OpenRaw::BitmapData::setDataType
void setDataType(DataType _type)
Definition: bitmapdata.cpp:100
OpenRaw::RawData::cfaPattern
const CfaPattern * cfaPattern() const
Definition: rawdata.cpp:287
OpenRaw::Internals::IfdEntry::Ref
std::shared_ptr< IfdEntry > Ref
Definition: ifdentry.hpp:165
OpenRaw::RawData
Definition: rawdata.hpp:35
OpenRaw::Internals::LJpegDecompressor::decompress
virtual RawDataPtr decompress() override
Definition: ljpegdecompressor.cpp:1534
OpenRaw::RawData::swap
void swap(RawData &with)
Definition: rawdata.cpp:245
OpenRaw::Internals::IfdFile::_getRawDataFromDir
::or_error _getRawDataFromDir(RawData &data, const IfdDir::Ref &dir)
Definition: ifdfile.cpp:510