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
40using namespace Debug;
41
42namespace OpenRaw {
43namespace Internals {
44
45const 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
139RawFile *DngFile::factory(const IO::Stream::Ptr &s)
140{
141 return new DngFile(s);
142}
143
144
145DngFile::DngFile(const IO::Stream::Ptr &s)
146 : TiffEpFile(s, OR_RAWFILE_TYPE_DNG)
147{
148 _setIdMap(s_def);
149}
150
151DngFile::~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
216void 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*/
void setDataType(DataType _type)
size_t size() const
virtual::or_error _getRawData(RawData &data, uint32_t options) override
Definition dngfile.cpp:155
std::shared_ptr< IfdEntry > Ref
Definition ifdentry.hpp:165
::or_error _getRawDataFromDir(RawData &data, const IfdDir::Ref &dir)
Definition ifdfile.cpp:510
const IfdDir::Ref & cfaIfd()
Definition ifdfile.cpp:332
virtual RawDataPtr decompress() override
void swap(RawData &with)
Definition rawdata.cpp:245
const CfaPattern * cfaPattern() const
Definition rawdata.cpp:287
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30