libopenraw
rawfile.cpp
1/*
2 * libopenraw - rawfile.cpp
3 *
4 * Copyright (C) 2008 Novell, Inc.
5 * Copyright (C) 2006-2016 Hubert Figuiere
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
23#include <stddef.h>
24#include <stdint.h>
25
26#include <cstring>
27#include <map>
28#include <string>
29#include <functional>
30#include <memory>
31#include <utility>
32#include <vector>
33
34#include <boost/algorithm/string.hpp>
35
36#include "trace.hpp"
37
38#include <libopenraw/metadata.h>
39#include <libopenraw/cameraids.h>
40#include <libopenraw/consts.h>
41#include <libopenraw/debug.h>
42
43#include "rawfile.hpp"
44#include "rawdata.hpp"
45#include "thumbnail.hpp"
46#include "metavalue.hpp"
47
48#include "io/stream.hpp"
49#include "io/file.hpp"
50#include "io/memstream.hpp"
51#include "rawcontainer.hpp"
52#include "tiffepfile.hpp"
53#include "cr2file.hpp"
54#include "neffile.hpp"
55#include "orffile.hpp"
56#include "arwfile.hpp"
57#include "peffile.hpp"
58#include "crwfile.hpp"
59#include "erffile.hpp"
60#include "dngfile.hpp"
61#include "mrwfile.hpp"
62#include "rw2file.hpp"
63#include "raffile.hpp"
64#include "exception.hpp"
65#include "rawfile_private.hpp"
66
67#include "rawfilefactory.hpp"
68
69using std::string;
70using namespace Debug;
71
72namespace OpenRaw {
73
74class BitmapData;
75
77
78void init(void)
79{
80 using namespace std::placeholders;
81
82 static RawFileFactory fctcr2(OR_RAWFILE_TYPE_CR2,
83 std::bind(&Internals::Cr2File::factory, _1),
84 "cr2");
85 static RawFileFactory fctnef(OR_RAWFILE_TYPE_NEF,
86 std::bind(&Internals::NefFile::factory, _1),
87 "nef");
88 static RawFileFactory fctnrw(OR_RAWFILE_TYPE_NRW,
89 std::bind(&Internals::NefFile::factory, _1),
90 "nrw");
91 static RawFileFactory fctarw(OR_RAWFILE_TYPE_ARW,
92 std::bind(&Internals::ArwFile::factory, _1),
93 "arw");
94 static RawFileFactory fctorf(OR_RAWFILE_TYPE_ORF,
95 std::bind(&Internals::OrfFile::factory, _1),
96 "orf");
97 static RawFileFactory fctdng(OR_RAWFILE_TYPE_DNG,
98 std::bind(&Internals::DngFile::factory, _1),
99 "dng");
100 static RawFileFactory fctpef(OR_RAWFILE_TYPE_PEF,
101 std::bind(&Internals::PEFFile::factory, _1),
102 "pef");
103 static RawFileFactory fctcrw(OR_RAWFILE_TYPE_CRW,
104 std::bind(&Internals::CRWFile::factory, _1),
105 "crw");
106 static RawFileFactory fcterf(OR_RAWFILE_TYPE_ERF,
107 std::bind(&Internals::ERFFile::factory, _1),
108 "erf");
109 static RawFileFactory fctmrw(OR_RAWFILE_TYPE_MRW,
110 std::bind(&Internals::MRWFile::factory, _1),
111 "mrw");
112 static RawFileFactory fctraw(OR_RAWFILE_TYPE_RW2,
113 std::bind(&Internals::Rw2File::factory, _1),
114 "raw");
115 static RawFileFactory fctrw2(OR_RAWFILE_TYPE_RW2,
116 std::bind(&Internals::Rw2File::factory, _1),
117 "rw2");
118 static RawFileFactory fctrwl(OR_RAWFILE_TYPE_RW2,
119 std::bind(&Internals::Rw2File::factory, _1),
120 "rwl");
121 static RawFileFactory fctraf(OR_RAWFILE_TYPE_RAF,
122 std::bind(&Internals::RafFile::factory, _1),
123 "raf");
124}
125
127{
128public:
129 Private(Type t)
130 : m_type(t),
131 m_type_id(OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NONE, OR_TYPEID_UNKNOWN)),
132 m_sizes(),
133 m_cam_ids(NULL),
134 m_matrices(NULL)
135 {
136 }
137 ~Private()
138 {
139 for(auto value : m_metadata)
140 {
141 if(value.second) {
142 delete value.second;
143 }
144 }
145 }
147 Type m_type;
149 TypeId m_type_id;
151 std::vector<uint32_t> m_sizes;
152 Internals::ThumbLocations m_thumbLocations;
153 std::map<int32_t, MetaValue*> m_metadata;
154 const camera_ids_t *m_cam_ids;
155 const Internals::BuiltinColourMatrix* m_matrices;
156};
157
158
160{
161 init();
162
164}
165
166
167RawFile *RawFile::newRawFile(const char*_filename, RawFile::Type _typeHint)
168{
169 init();
170
171 Type type;
172 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
173 type = identify(_filename);
174 }
175 else {
176 type = _typeHint;
177 }
178 LOGDBG1("factory size %ld\n", RawFileFactory::table().size());
179 auto iter = RawFileFactory::table().find(type);
180 if (iter == RawFileFactory::table().end()) {
181 LOGWARN("factory not found\n");
182 return NULL;
183 }
184 if (iter->second == NULL) {
185 LOGWARN("factory is NULL\n");
186 return NULL;
187 }
188 IO::Stream::Ptr f(new IO::File(_filename));
189 return iter->second(f);
190}
191
192RawFile *RawFile::newRawFileFromMemory(const uint8_t *buffer,
193 uint32_t len,
194 RawFile::Type _typeHint)
195{
196 init();
197 Type type;
198 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
199 ::or_error err = identifyBuffer(buffer, len, type);
200 if(err != OR_ERROR_NONE) {
201 LOGERR("error identifying buffer\n");
202 return NULL;
203 }
204 }
205 else {
206 type = _typeHint;
207 }
208 auto iter = RawFileFactory::table().find(type);
209 if (iter == RawFileFactory::table().end()) {
210 LOGWARN("factory not found\n");
211 return NULL;
212 }
213 if (iter->second == nullptr) {
214 LOGWARN("factory is NULL\n");
215 return NULL;
216 }
217 IO::Stream::Ptr f(new IO::MemStream((void*)buffer, len));
218 return iter->second(f);
219}
220
221
222RawFile::Type RawFile::identify(const char*_filename)
223{
224 const char *e = ::strrchr(_filename, '.');
225 if (e == NULL) {
226 LOGDBG1("Extension not found\n");
227 return OR_RAWFILE_TYPE_UNKNOWN;
228 }
229 std::string extension(e + 1);
230 if (extension.length() > 3) {
231 return OR_RAWFILE_TYPE_UNKNOWN;
232 }
233
234 boost::to_lower(extension);
235
236 RawFileFactory::Extensions & extensions = RawFileFactory::extensions();
237 auto iter = extensions.find(extension);
238 if (iter == extensions.end())
239 {
240 return OR_RAWFILE_TYPE_UNKNOWN;
241 }
242 return iter->second;
243}
244
245::or_error RawFile::identifyBuffer(const uint8_t* buff, size_t len,
246 RawFile::Type &_type)
247{
248 _type = OR_RAWFILE_TYPE_UNKNOWN;
249 if(len <= 4) {
250 return OR_ERROR_BUF_TOO_SMALL;
251 }
252 if(memcmp(buff, "\0MRM", 4) == 0) {
253 _type = OR_RAWFILE_TYPE_MRW;
254 return OR_ERROR_NONE;
255 }
256 if(memcmp(buff, "II\x1a\0\0\0HEAPCCDR", 14) == 0) {
257 _type = OR_RAWFILE_TYPE_CRW;
258 return OR_ERROR_NONE;
259 }
260 if(memcmp(buff, "IIRO", 4) == 0) {
261 _type = OR_RAWFILE_TYPE_ORF;
262 return OR_ERROR_NONE;
263 }
264 if(memcmp(buff, "IIU\0", 4) == 0) {
265 _type = OR_RAWFILE_TYPE_RW2;
266 return OR_ERROR_NONE;
267 }
268 if(memcmp(buff, RAF_MAGIC, RAF_MAGIC_LEN) == 0) {
269 _type = OR_RAWFILE_TYPE_RAF;
270 return OR_ERROR_NONE;
271 }
272 if((memcmp(buff, "II\x2a\0", 4) == 0)
273 || (memcmp(buff, "MM\0\x2a", 4) == 0)) {
274 // TIFF based format
275 if(len >=12 ) {
276 if(memcmp(buff + 8, "CR\x2", 3) == 0) {
277 _type = OR_RAWFILE_TYPE_CR2;
278 return OR_ERROR_NONE;
279 }
280 }
281 if(len >= 8) {
282 IO::Stream::Ptr s(new IO::MemStream((void*)buff, len));
283 std::unique_ptr<Internals::TiffEpFile> f(new Internals::TiffEpFile(s, OR_RAWFILE_TYPE_TIFF));
284
285 // Take into account DNG by checking the DNGVersion tag
286 const MetaValue *dng_version = f->getMetaValue(META_NS_TIFF | TIFF_TAG_DNG_VERSION);
287 if(dng_version) {
288 LOGDBG1("found DNG versions\n");
289 _type = OR_RAWFILE_TYPE_DNG;
290 return OR_ERROR_NONE;
291 }
292
293 const MetaValue *makev = f->getMetaValue(META_NS_TIFF | EXIF_TAG_MAKE);
294 if(makev){
295 std::string makes = makev->getString(0);
296 if(makes == "NIKON CORPORATION") {
297 _type = OR_RAWFILE_TYPE_NEF;
298 }
299 else if(makes == "SEIKO EPSON CORP."){
300 _type = OR_RAWFILE_TYPE_ERF;
301 }
302 else if(makes == "PENTAX Corporation ") {
303 _type = OR_RAWFILE_TYPE_PEF;
304 }
305 else if(makes == "SONY ") {
306 _type = OR_RAWFILE_TYPE_ARW;
307 }
308 else if(makes == "Canon") {
309 _type = OR_RAWFILE_TYPE_CR2;
310 }
311 }
312 }
313
314 }
315 return OR_ERROR_NONE;
316}
317
318RawFile::RawFile(RawFile::Type _type)
319 : d(new Private(_type))
320{
321}
322
323
325{
326 delete d;
327}
328
329
330RawFile::Type RawFile::type() const
331{
332 return d->m_type;
333}
334
335RawFile::TypeId RawFile::typeId()
336{
337 if(d->m_type_id == 0) {
338 _identifyId();
339 }
340 return d->m_type_id;
341}
342
343RawFile::TypeId RawFile::_typeId() const
344{
345 return d->m_type_id;
346}
347
348void RawFile::_setTypeId(RawFile::TypeId _type_id)
349{
350 d->m_type_id = _type_id;
351}
352
353const std::vector<uint32_t> & RawFile::listThumbnailSizes(void)
354{
355 if (d->m_sizes.empty()) {
356 LOGDBG1("_enumThumbnailSizes init\n");
357 ::or_error ret = _enumThumbnailSizes(d->m_sizes);
358 if (ret != OR_ERROR_NONE) {
359 LOGDBG1("_enumThumbnailSizes failed\n");
360 }
361 }
362 return d->m_sizes;
363}
364
365
366::or_error RawFile::getThumbnail(uint32_t tsize, Thumbnail & thumbnail)
367{
368 ::or_error ret = OR_ERROR_NOT_FOUND;
369 uint32_t smallest_bigger = 0xffffffff;
370 uint32_t biggest_smaller = 0;
371 uint32_t found_size = 0;
372
373 LOGDBG1("requested size %u\n", tsize);
374
375 auto sizes(listThumbnailSizes());
376
377 for (auto s : sizes) {
378 LOGDBG1("current iter is %u\n", s);
379 if (s < tsize) {
380 if (s > biggest_smaller) {
381 biggest_smaller = s;
382 }
383 }
384 else if(s > tsize) {
385 if(s < smallest_bigger) {
386 smallest_bigger = s;
387 }
388 }
389 else { // s == tsize
390 found_size = tsize;
391 break;
392 }
393 }
394
395 if (found_size == 0) {
396 found_size = (smallest_bigger != 0xffffffff ?
397 smallest_bigger : biggest_smaller);
398 }
399
400 if (found_size != 0) {
401 LOGDBG1("size %u found\n", found_size);
402 ret = _getThumbnail(found_size, thumbnail);
403 }
404 else {
405 // no size found, let's fail gracefuly
406 LOGDBG1("no size found\n");
407 ret = OR_ERROR_NOT_FOUND;
408 }
409
410 return ret;
411}
412
416::or_error RawFile::_getThumbnail(uint32_t size, Thumbnail & thumbnail)
417{
418 ::or_error ret = OR_ERROR_NOT_FOUND;
419 auto iter = d->m_thumbLocations.find(size);
420 if(iter != d->m_thumbLocations.end())
421 {
422 const Internals::ThumbDesc & desc = iter->second;
423 thumbnail.setDataType(desc.type);
424 uint32_t byte_length= desc.length;
425 uint32_t offset = desc.offset;
426
427 LOGDBG1("Thumbnail at %u of %u bytes.\n", offset, byte_length);
428
429 if (byte_length != 0) {
430 void *p = thumbnail.allocData(byte_length);
431 size_t real_size = getContainer()->fetchData(p, offset,
432 byte_length);
433 if (real_size < byte_length) {
434 LOGWARN("Size mismatch for data: got %lu expected %u ignoring.\n",
435 real_size, byte_length);
436 }
437
438 thumbnail.setDimensions(desc.x, desc.y);
439 ret = OR_ERROR_NONE;
440 }
441 }
442
443 return ret;
444}
445
446void RawFile::_addThumbnail(uint32_t size, const Internals::ThumbDesc& desc)
447{
448 d->m_thumbLocations[size] = desc;
449}
450
451::or_error RawFile::getRawData(RawData & rawdata, uint32_t options)
452{
453 LOGDBG1("getRawData()\n");
454 ::or_error ret = _getRawData(rawdata, options);
455 if (ret != OR_ERROR_NONE) {
456 return ret;
457 }
458
459 // if the colour matrix isn't copied already, do it now.
460 uint32_t matrix_size = 0;
461 if (!rawdata.getColourMatrix1(matrix_size) || !matrix_size) {
462 matrix_size = colourMatrixSize();
463 double *matrix = new double[matrix_size];
464 if (getColourMatrix1(matrix, matrix_size) == OR_ERROR_NONE) {
465 rawdata.setColourMatrix1(matrix, matrix_size);
466 }
467 delete [] matrix;
468 }
469
470 return ret;
471}
472
473::or_error RawFile::getRenderedImage(BitmapData & bitmapdata, uint32_t options)
474{
475 RawData rawdata;
476 LOGDBG1("options are %u\n", options);
477 ::or_error ret = getRawData(rawdata, options);
478 if(ret == OR_ERROR_NONE) {
479 ret = rawdata.getRenderedImage(bitmapdata, options);
480 }
481 return ret;
482}
483
484
486{
487 int32_t idx = 0;
488 const MetaValue * value = getMetaValue(META_NS_TIFF
489 | EXIF_TAG_ORIENTATION);
490 if(value == NULL) {
491 return 0;
492 }
493 try {
494 idx = value->getInteger(0);
495 }
496 catch(const Internals::BadTypeException & e) {
497 LOGDBG1("wrong type - %s\n", e.what());
498 }
499 return idx;
500}
501
503{
504 return 9;
505}
506
507::or_error RawFile::getColourMatrix1(double* matrix, uint32_t & size)
508{
509 return _getColourMatrix(1, matrix, size);
510}
511
512::or_error RawFile::getColourMatrix2(double* matrix, uint32_t & size)
513{
514 return _getColourMatrix(2, matrix, size);
515}
516
517::or_error RawFile::_getColourMatrix(uint32_t index, double* matrix, uint32_t & size)
518{
519 int32_t meta_index = 0;
520 switch(index) {
521 case 1:
522 meta_index = META_NS_TIFF | DNG_TAG_COLORMATRIX1;
523 break;
524 case 2:
525 meta_index = META_NS_TIFF | DNG_TAG_COLORMATRIX2;
526 break;
527 default:
528 size = 0;
529 return OR_ERROR_INVALID_PARAM;
530 }
531 const MetaValue* meta = getMetaValue(meta_index);
532
533 if(!meta) {
534 if (index != 1) {
535 size = 0;
536 return OR_ERROR_INVALID_PARAM;
537 }
538 return _getBuiltinColourMatrix(d->m_matrices, typeId(), matrix, size);
539 }
540 uint32_t count = meta->getCount();
541 if(size < count) {
542 // return the expected size
543 size = count;
544 return OR_ERROR_BUF_TOO_SMALL;
545 }
546
547 for(uint32_t i = 0; i < count; i++) {
548 matrix[i] = meta->getDouble(i);
549 }
550 size = count;
551
552 return OR_ERROR_NONE;
553}
554
556{
557 return _getCalibrationIlluminant(1);
558}
559
560ExifLightsourceValue RawFile::getCalibrationIlluminant2()
561{
562 return _getCalibrationIlluminant(2);
563}
564
565ExifLightsourceValue RawFile::_getCalibrationIlluminant(uint16_t index)
566{
567 int32_t meta_index = 0;
568 switch(index) {
569 case 1:
570 meta_index = META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT1;
571 break;
572 case 2:
573 meta_index = META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT2;
574 break;
575 default:
576 return EV_LIGHTSOURCE_UNKNOWN;
577 }
578 const MetaValue* meta = getMetaValue(meta_index);
579
580 if(!meta) {
581 return (index == 1) ? EV_LIGHTSOURCE_D65 : EV_LIGHTSOURCE_UNKNOWN;
582 }
583 return (ExifLightsourceValue)meta->getInteger(0);
584}
585
586const MetaValue *RawFile::getMetaValue(int32_t meta_index)
587{
588 MetaValue *val = NULL;
589 auto iter = d->m_metadata.find(meta_index);
590 if(iter == d->m_metadata.end()) {
591 val = _getMetaValue(meta_index);
592 if(val != NULL) {
593 d->m_metadata[meta_index] = val;
594 }
595 }
596 else {
597 val = iter->second;
598 }
599 return val;
600}
601
602
604RawFile::_lookupCameraId(const camera_ids_t * map, const std::string& value)
605{
606 const camera_ids_t * p = map;
607 if(!p) {
608 return NULL;
609 }
610 while(p->model) {
611 if(value == p->model) {
612 return p;
613 }
614 p++;
615 }
616 return NULL;
617}
618
619RawFile::TypeId RawFile::_typeIdFromModel(const std::string & make,
620 const std::string & model)
621{
622 const camera_ids_t * p = _lookupCameraId(d->m_cam_ids, model);
623 if (!p) {
624 return _typeIdFromMake(make);
625 }
626 return p->type_id;
627}
628
629const RawFile::camera_ids_t RawFile::s_make[] = {
630 { "Canon", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON, 0) },
631 { "NIKON CORPORATION", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 0) },
632 { "LEICA CAMERA AG ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, 0) },
633 { "Leica Camera AG", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, 0) },
634 { "Panasonic", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PANASONIC, 0) },
635 // Hardcoded
636 { "Minolta", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_MINOLTA, 0) },
637 { "FujiFilm", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_FUJIFILM, 0) },
638 { NULL, 0 }
639};
640
641
642RawFile::TypeId
643RawFile::_typeIdFromMake(const std::string& make)
644{
645 const camera_ids_t * p = _lookupCameraId(s_make, make);
646 if (!p) {
647 return 0;
648 }
649 return p->type_id;
650}
651
652void RawFile::_setIdMap(const camera_ids_t *map)
653{
654 d->m_cam_ids = map;
655}
656
658RawFile::_getMatrices() const
659{
660 return d->m_matrices;
661}
662
663void RawFile::_setMatrices(const Internals::BuiltinColourMatrix* matrices)
664{
665 d->m_matrices = matrices;
666}
667
668::or_error
669RawFile::_getBuiltinLevels(const Internals::BuiltinColourMatrix* m,
670 TypeId type_id,
671 uint16_t & black, uint16_t & white)
672{
673 if(!m) {
674 return OR_ERROR_NOT_FOUND;
675 }
676 while(m->camera) {
677 if(m->camera == type_id) {
678 black = m->black;
679 white = m->white;
680 return OR_ERROR_NONE;
681 }
682 ++m;
683 }
684 return OR_ERROR_NOT_FOUND;
685}
686
687::or_error
688RawFile::_getBuiltinColourMatrix(const Internals::BuiltinColourMatrix* m,
689 TypeId type_id,
690 double* matrix,
691 uint32_t & size)
692{
693 if(!m) {
694 return OR_ERROR_NOT_FOUND;
695 }
696 if(size < 9) {
697 return OR_ERROR_BUF_TOO_SMALL;
698 }
699
700 while(m->camera) {
701 if(m->camera == type_id) {
702 for(int i = 0; i < 9; i++) {
703 matrix[i] = static_cast<double>(m->matrix[i]) / 10000.0;
704 }
705 size = 9;
706 return OR_ERROR_NONE;
707 }
708 ++m;
709 }
710 size = 0;
711 return OR_ERROR_NOT_FOUND;
712}
713
714}
715
716/*
717 Local Variables:
718 mode:c++
719 c-file-style:"stroustrup"
720 c-file-offsets:((innamespace . 0))
721 indent-tabs-mode:nil
722 fill-column:80
723 End:
724*/
725
void setDataType(DataType _type)
virtual void setDimensions(uint32_t x, uint32_t y)
size_t fetchData(void *buf, off_t offset, size_t buf_size)
const double * getColourMatrix1(uint32_t &size) const
Definition rawdata.cpp:211
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Definition rawdata.cpp:125
static const char ** fileExtensions()
static Extensions & extensions()
std::vector< uint32_t > m_sizes
Definition rawfile.cpp:151
virtual::or_error _enumThumbnailSizes(std::vector< uint32_t > &list)=0
virtual::or_error _getThumbnail(uint32_t size, Thumbnail &thumbnail)
Definition rawfile.cpp:416
::or_error getThumbnail(uint32_t size, Thumbnail &thumbnail)
Definition rawfile.cpp:366
TypeId typeId()
Definition rawfile.cpp:335
void _setTypeId(TypeId _type_id)
Definition rawfile.cpp:348
int32_t getOrientation()
Definition rawfile.cpp:485
::or_error getRawData(RawData &rawdata, uint32_t options)
Definition rawfile.cpp:451
uint32_t colourMatrixSize()
Definition rawfile.cpp:502
virtual::or_error _getColourMatrix(uint32_t index, double *matrix, uint32_t &size)
Definition rawfile.cpp:517
::or_error getColourMatrix1(double *matrix, uint32_t &size)
Definition rawfile.cpp:507
virtual ~RawFile()
Definition rawfile.cpp:324
virtual Internals::RawContainer * getContainer() const =0
static RawFile * newRawFile(const char *_filename, Type _typeHint=OR_RAWFILE_TYPE_UNKNOWN)
Definition rawfile.cpp:167
const std::vector< uint32_t > & listThumbnailSizes(void)
Definition rawfile.cpp:353
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Definition rawfile.cpp:473
ExifLightsourceValue getCalibrationIlluminant1()
Definition rawfile.cpp:555
virtual::or_error _getRawData(RawData &data, uint32_t options)=0
static const char ** fileExtensions()
Definition rawfile.cpp:159
TypeId _typeId() const
Definition rawfile.cpp:343
static RawFile * newRawFileFromMemory(const uint8_t *buffer, uint32_t len, Type _typeHint=OR_RAWFILE_TYPE_UNKNOWN)
Definition rawfile.cpp:192
Type type() const
Definition rawfile.cpp:330
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard....
Definition arwfile.cpp:30