34 #include <boost/algorithm/string.hpp> 38 #include <libopenraw/metadata.h> 39 #include <libopenraw/cameraids.h> 40 #include <libopenraw/consts.h> 41 #include <libopenraw/debug.h> 43 #include "rawfile.hpp" 44 #include "rawdata.hpp" 45 #include "thumbnail.hpp" 46 #include "metavalue.hpp" 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" 67 #include "rawfilefactory.hpp" 70 using namespace Debug;
76 using Internals::RawFileFactory;
80 using namespace std::placeholders;
82 static RawFileFactory fctcr2(OR_RAWFILE_TYPE_CR2,
83 std::bind(&Internals::Cr2File::factory, _1),
85 static RawFileFactory fctnef(OR_RAWFILE_TYPE_NEF,
86 std::bind(&Internals::NefFile::factory, _1),
88 static RawFileFactory fctnrw(OR_RAWFILE_TYPE_NRW,
89 std::bind(&Internals::NefFile::factory, _1),
91 static RawFileFactory fctarw(OR_RAWFILE_TYPE_ARW,
92 std::bind(&Internals::ArwFile::factory, _1),
94 static RawFileFactory fctorf(OR_RAWFILE_TYPE_ORF,
95 std::bind(&Internals::OrfFile::factory, _1),
97 static RawFileFactory fctdng(OR_RAWFILE_TYPE_DNG,
98 std::bind(&Internals::DngFile::factory, _1),
100 static RawFileFactory fctpef(OR_RAWFILE_TYPE_PEF,
101 std::bind(&Internals::PEFFile::factory, _1),
103 static RawFileFactory fctcrw(OR_RAWFILE_TYPE_CRW,
104 std::bind(&Internals::CRWFile::factory, _1),
106 static RawFileFactory fcterf(OR_RAWFILE_TYPE_ERF,
107 std::bind(&Internals::ERFFile::factory, _1),
109 static RawFileFactory fctmrw(OR_RAWFILE_TYPE_MRW,
110 std::bind(&Internals::MRWFile::factory, _1),
112 static RawFileFactory fctraw(OR_RAWFILE_TYPE_RW2,
113 std::bind(&Internals::Rw2File::factory, _1),
115 static RawFileFactory fctrw2(OR_RAWFILE_TYPE_RW2,
116 std::bind(&Internals::Rw2File::factory, _1),
118 static RawFileFactory fctraf(OR_RAWFILE_TYPE_RAF,
119 std::bind(&Internals::RafFile::factory, _1),
128 m_type_id(OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NONE, OR_TYPEID_UNKNOWN)),
136 for(
auto value : m_metadata)
149 Internals::ThumbLocations m_thumbLocations;
150 std::map<int32_t, MetaValue*> m_metadata;
156 const char **RawFile::fileExtensions()
160 return RawFileFactory::fileExtensions();
164 RawFile *RawFile::newRawFile(
const char*_filename, RawFile::Type _typeHint)
169 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
170 type = identify(_filename);
175 LOGDBG1(
"factory size %ld\n", RawFileFactory::table().size());
176 auto iter = RawFileFactory::table().find(type);
177 if (iter == RawFileFactory::table().end()) {
178 LOGWARN(
"factory not found\n");
181 if (iter->second == NULL) {
182 LOGWARN(
"factory is NULL\n");
185 IO::Stream::Ptr f(
new IO::File(_filename));
186 return iter->second(f);
189 RawFile *RawFile::newRawFileFromMemory(
const uint8_t *buffer,
191 RawFile::Type _typeHint)
195 if (_typeHint == OR_RAWFILE_TYPE_UNKNOWN) {
196 ::or_error err = identifyBuffer(buffer, len, type);
197 if(err != OR_ERROR_NONE) {
198 LOGERR(
"error identifying buffer\n");
205 auto iter = RawFileFactory::table().find(type);
206 if (iter == RawFileFactory::table().end()) {
207 LOGWARN(
"factory not found\n");
210 if (iter->second ==
nullptr) {
211 LOGWARN(
"factory is NULL\n");
215 return iter->second(f);
219 RawFile::Type RawFile::identify(
const char*_filename)
221 const char *e = ::strrchr(_filename,
'.');
223 LOGDBG1(
"Extension not found\n");
224 return OR_RAWFILE_TYPE_UNKNOWN;
226 std::string extension(e + 1);
227 if (extension.length() > 3) {
228 return OR_RAWFILE_TYPE_UNKNOWN;
231 boost::to_lower(extension);
233 RawFileFactory::Extensions & extensions = RawFileFactory::extensions();
234 auto iter = extensions.find(extension);
235 if (iter == extensions.end())
237 return OR_RAWFILE_TYPE_UNKNOWN;
242 ::or_error RawFile::identifyBuffer(
const uint8_t* buff,
size_t len,
243 RawFile::Type &_type)
245 _type = OR_RAWFILE_TYPE_UNKNOWN;
247 return OR_ERROR_BUF_TOO_SMALL;
249 if(memcmp(buff,
"\0MRM", 4) == 0) {
250 _type = OR_RAWFILE_TYPE_MRW;
251 return OR_ERROR_NONE;
253 if(memcmp(buff,
"II\x1a\0\0\0HEAPCCDR", 14) == 0) {
254 _type = OR_RAWFILE_TYPE_CRW;
255 return OR_ERROR_NONE;
257 if(memcmp(buff,
"IIRO", 4) == 0) {
258 _type = OR_RAWFILE_TYPE_ORF;
259 return OR_ERROR_NONE;
261 if(memcmp(buff,
"IIU\0", 4) == 0) {
262 _type = OR_RAWFILE_TYPE_RW2;
263 return OR_ERROR_NONE;
265 if(memcmp(buff, RAF_MAGIC, RAF_MAGIC_LEN) == 0) {
266 _type = OR_RAWFILE_TYPE_RAF;
267 return OR_ERROR_NONE;
269 if((memcmp(buff,
"II\x2a\0", 4) == 0)
270 || (memcmp(buff,
"MM\0\x2a", 4) == 0)) {
273 if(memcmp(buff + 8,
"CR\x2", 3) == 0) {
274 _type = OR_RAWFILE_TYPE_CR2;
275 return OR_ERROR_NONE;
283 const MetaValue *dng_version = f->getMetaValue(META_NS_TIFF | TIFF_TAG_DNG_VERSION);
285 LOGDBG1(
"found DNG versions\n");
286 _type = OR_RAWFILE_TYPE_DNG;
287 return OR_ERROR_NONE;
290 const MetaValue *makev = f->getMetaValue(META_NS_TIFF | EXIF_TAG_MAKE);
292 std::string makes = makev->getString(0);
293 if(makes ==
"NIKON CORPORATION") {
294 _type = OR_RAWFILE_TYPE_NEF;
296 else if(makes ==
"SEIKO EPSON CORP."){
297 _type = OR_RAWFILE_TYPE_ERF;
299 else if(makes ==
"PENTAX Corporation ") {
300 _type = OR_RAWFILE_TYPE_PEF;
302 else if(makes ==
"SONY ") {
303 _type = OR_RAWFILE_TYPE_ARW;
305 else if(makes ==
"Canon") {
306 _type = OR_RAWFILE_TYPE_CR2;
312 return OR_ERROR_NONE;
315 RawFile::RawFile(RawFile::Type _type)
353 LOGDBG1(
"_enumThumbnailSizes init\n");
355 if (ret != OR_ERROR_NONE) {
356 LOGDBG1(
"_enumThumbnailSizes failed\n");
365 ::or_error ret = OR_ERROR_NOT_FOUND;
366 uint32_t smallest_bigger = 0xffffffff;
367 uint32_t biggest_smaller = 0;
368 uint32_t found_size = 0;
370 LOGDBG1(
"requested size %u\n", tsize);
374 for (
auto s : sizes) {
375 LOGDBG1(
"current iter is %u\n", s);
377 if (s > biggest_smaller) {
382 if(s < smallest_bigger) {
392 if (found_size == 0) {
393 found_size = (smallest_bigger != 0xffffffff ?
394 smallest_bigger : biggest_smaller);
397 if (found_size != 0) {
398 LOGDBG1(
"size %u found\n", found_size);
403 LOGDBG1(
"no size found\n");
404 ret = OR_ERROR_NOT_FOUND;
415 ::or_error ret = OR_ERROR_NOT_FOUND;
416 auto iter = d->m_thumbLocations.find(size);
417 if(iter != d->m_thumbLocations.end())
421 uint32_t byte_length= desc.length;
422 uint32_t offset = desc.
offset;
424 LOGDBG1(
"Thumbnail at %u of %u bytes.\n", offset, byte_length);
426 if (byte_length != 0) {
427 void *p = thumbnail.allocData(byte_length);
430 if (real_size < byte_length) {
431 LOGWARN(
"Size mismatch for data: got %lu expected %u ignoring.\n",
432 real_size, byte_length);
445 d->m_thumbLocations[size] = desc;
450 LOGDBG1(
"getRawData()\n");
452 if (ret != OR_ERROR_NONE) {
457 uint32_t matrix_size = 0;
460 double *matrix =
new double[matrix_size];
462 rawdata.setColourMatrix1(matrix, matrix_size);
473 LOGDBG1(
"options are %u\n", options);
474 ::or_error ret =
getRawData(rawdata, options);
475 if(ret == OR_ERROR_NONE) {
485 const MetaValue * value = getMetaValue(META_NS_TIFF
486 | EXIF_TAG_ORIENTATION);
491 idx = value->getInteger(0);
494 LOGDBG1(
"wrong type - %s\n", e.what());
509 ::or_error RawFile::getColourMatrix2(
double* matrix, uint32_t & size)
516 int32_t meta_index = 0;
519 meta_index = META_NS_TIFF | DNG_TAG_COLORMATRIX1;
522 meta_index = META_NS_TIFF | DNG_TAG_COLORMATRIX2;
526 return OR_ERROR_INVALID_PARAM;
528 const MetaValue* meta = getMetaValue(meta_index);
533 return OR_ERROR_INVALID_PARAM;
535 return _getBuiltinColourMatrix(d->m_matrices,
typeId(), matrix, size);
537 uint32_t count = meta->getCount();
541 return OR_ERROR_BUF_TOO_SMALL;
544 for(uint32_t i = 0; i < count; i++) {
545 matrix[i] = meta->getDouble(i);
549 return OR_ERROR_NONE;
554 return _getCalibrationIlluminant(1);
557 ExifLightsourceValue RawFile::getCalibrationIlluminant2()
559 return _getCalibrationIlluminant(2);
562 ExifLightsourceValue RawFile::_getCalibrationIlluminant(uint16_t index)
564 int32_t meta_index = 0;
567 meta_index = META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT1;
570 meta_index = META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT2;
573 return EV_LIGHTSOURCE_UNKNOWN;
575 const MetaValue* meta = getMetaValue(meta_index);
578 return (index == 1) ? EV_LIGHTSOURCE_D65 : EV_LIGHTSOURCE_UNKNOWN;
580 return (ExifLightsourceValue)meta->getInteger(0);
583 const MetaValue *RawFile::getMetaValue(int32_t meta_index)
586 auto iter = d->m_metadata.find(meta_index);
587 if(iter == d->m_metadata.end()) {
588 val = _getMetaValue(meta_index);
590 d->m_metadata[meta_index] = val;
601 RawFile::_lookupCameraId(
const camera_ids_t * map,
const std::string& value)
608 if(value == p->model) {
616 RawFile::TypeId RawFile::_typeIdFromModel(
const std::string & make,
617 const std::string & model)
619 const camera_ids_t * p = _lookupCameraId(d->m_cam_ids, model);
621 return _typeIdFromMake(make);
627 {
"Canon", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON, 0) },
628 {
"NIKON CORPORATION", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_NIKON, 0) },
629 {
"LEICA CAMERA AG ", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, 0) },
630 {
"Leica Camera AG", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_LEICA, 0) },
631 {
"Panasonic", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_PANASONIC, 0) },
633 {
"Minolta", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_MINOLTA, 0) },
634 {
"FujiFilm", OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_FUJIFILM, 0) },
640 RawFile::_typeIdFromMake(
const std::string& make)
655 RawFile::_getMatrices()
const 657 return d->m_matrices;
662 d->m_matrices = matrices;
668 uint16_t & black, uint16_t & white)
671 return OR_ERROR_NOT_FOUND;
674 if(m->camera == type_id) {
677 return OR_ERROR_NONE;
681 return OR_ERROR_NOT_FOUND;
691 return OR_ERROR_NOT_FOUND;
694 return OR_ERROR_BUF_TOO_SMALL;
698 if(m->camera == type_id) {
699 for(
int i = 0; i < 9; i++) {
700 matrix[i] =
static_cast<double>(m->matrix[i]) / 10000.0;
703 return OR_ERROR_NONE;
708 return OR_ERROR_NOT_FOUND;
size_t fetchData(void *buf, off_t offset, size_t buf_size)
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
::or_error getThumbnail(uint32_t size, Thumbnail &thumbnail)
::or_error getRawData(RawData &rawdata, uint32_t options)
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
ExifLightsourceValue getCalibrationIlluminant1()
virtual ::or_error _getRawData(RawData &data, uint32_t options)=0
void _setTypeId(TypeId _type_id)
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list)=0
virtual ::or_error _getColourMatrix(uint32_t index, double *matrix, uint32_t &size)
::or_error getColourMatrix1(double *matrix, uint32_t &size)
virtual void setDimensions(uint32_t x, uint32_t y)
virtual Internals::RawContainer * getContainer() const =0
const std::vector< uint32_t > & listThumbnailSizes(void)
void setDataType(DataType _type)
std::vector< uint32_t > m_sizes
uint32_t colourMatrixSize()
virtual ::or_error _getThumbnail(uint32_t size, Thumbnail &thumbnail)
const double * getColourMatrix1(uint32_t &size) const