34 #include <boost/algorithm/string.hpp>
38 #include <libopenraw/cameraids.h>
39 #include <libopenraw/consts.h>
40 #include <libopenraw/debug.h>
41 #include <libopenraw/metadata.h>
43 #include "metavalue.hpp"
44 #include "rawdata.hpp"
45 #include "rawfile.hpp"
46 #include "thumbnail.hpp"
47 #include "metadata.hpp"
49 #include "arwfile.hpp"
50 #include "cr2file.hpp"
51 #include "cr3file.hpp"
52 #include "crwfile.hpp"
53 #include "dngfile.hpp"
54 #include "erffile.hpp"
55 #include "exception.hpp"
56 #include "io/file.hpp"
57 #include "io/memstream.hpp"
58 #include "io/stream.hpp"
59 #include "mrwfile.hpp"
60 #include "neffile.hpp"
61 #include "orffile.hpp"
62 #include "peffile.hpp"
63 #include "raffile.hpp"
64 #include "rawcontainer.hpp"
65 #include "rawfile_private.hpp"
66 #include "rw2file.hpp"
67 #include "tiffepfile.hpp"
69 #include "rawfilefactory.hpp"
72 using namespace Debug;
78 using Internals::RawFileFactory;
80 static std::once_flag inited;
85 std::call_once(inited, [] {
86 using namespace std::placeholders;
89 std::bind(&Internals::Cr2File::factory, _1),
92 std::bind(&Internals::NefFile::factory, _1),
95 std::bind(&Internals::NefFile::factory, _1),
98 std::bind(&Internals::ArwFile::factory, _1),
101 std::bind(&Internals::ArwFile::factory, _1),
104 std::bind(&Internals::OrfFile::factory, _1),
107 std::bind(&Internals::DngFile::factory, _1),
110 std::bind(&Internals::DngFile::factory, _1),
113 std::bind(&Internals::PEFFile::factory, _1),
116 std::bind(&Internals::CRWFile::factory, _1),
119 std::bind(&Internals::ERFFile::factory, _1),
122 std::bind(&Internals::MRWFile::factory, _1),
125 std::bind(&Internals::Rw2File::factory, _1),
128 std::bind(&Internals::Rw2File::factory, _1),
131 std::bind(&Internals::Rw2File::factory, _1),
134 std::bind(&Internals::RafFile::factory, _1),
137 std::bind(&Internals::Cr3File::factory, _1),
155 for (
auto value : m_metadata) {
167 Internals::ThumbLocations m_thumbLocations;
168 std::map<int32_t, MetaValue*> m_metadata;
180 const char** RawFile::fileExtensions()
184 return RawFileFactory::fileExtensions();
193 type = identify(filename);
197 auto err = identifyIOBuffer(f, type);
199 LOGERR(
"identifyIOBuffer returned %u\n", err);
207 LOGDBG1(
"factory size %lu\n", (LSIZE)RawFileFactory::table().size());
208 auto iter = RawFileFactory::table().find(type);
209 if (iter == RawFileFactory::table().end()) {
210 LOGWARN(
"factory not found\n");
213 if (iter->second == NULL) {
214 LOGWARN(
"factory is NULL\n");
218 return iter->second(f);
221 RawFile* RawFile::newRawFileFromMemory(
const uint8_t* buffer, uint32_t len,
227 ::or_error err = identifyBuffer(buffer, len, type);
229 LOGERR(
"error identifying buffer\n");
236 auto iter = RawFileFactory::table().find(type);
237 if (iter == RawFileFactory::table().end()) {
238 LOGWARN(
"factory not found\n");
241 if (iter->second ==
nullptr) {
242 LOGWARN(
"factory is NULL\n");
246 return iter->second(f);
251 const char* e = ::strrchr(_filename,
'.');
253 LOGDBG1(
"Extension not found\n");
256 std::string extension(e + 1);
257 if (extension.length() > 3) {
261 boost::to_lower(extension);
263 const auto& extensions = RawFileFactory::extensions();
264 auto iter = extensions.find(extension);
265 if (iter == extensions.end()) {
272 RawFile::identifyBuffer(
const uint8_t* buff,
size_t len, RawFile::Type& _type)
274 IO::Stream::Ptr stream(
new IO::MemStream(buff, len));
276 return identifyIOBuffer(stream, _type);
280 RawFile::identifyIOBuffer(IO::Stream::Ptr& stream, RawFile::Type& _type)
282 off_t len = stream->filesize();
284 constexpr
size_t buffer_size = 16;
285 uint8_t buff[buffer_size];
288 stream->read(buff, buffer_size);
294 if (memcmp(buff,
"\0MRM", 4) == 0) {
298 if (len >= 12 && (memcmp(buff + 4,
"ftypcrx ", 8) == 0)) {
302 if (len >= 14 && memcmp(buff,
"II\x1a\0\0\0HEAPCCDR", 14) == 0) {
306 if (memcmp(buff,
"IIRO", 4) == 0) {
310 if (memcmp(buff,
"IIU\0", 4) == 0) {
318 if ((memcmp(buff,
"II\x2a\0", 4) == 0) ||
319 (memcmp(buff,
"MM\0\x2a", 4) == 0)) {
322 if (memcmp(buff + 8,
"CR\x2", 3) == 0) {
328 stream->seek(0, SEEK_SET);
332 const MetaValue* dng_version =
335 LOGDBG1(
"found DNG versions\n");
340 const MetaValue* makev =
343 std::string makes = makev->getString(0);
344 if (makes.find(
"NIKON") == 0) {
347 else if (makes ==
"SEIKO EPSON CORP.") {
350 else if (makes ==
"PENTAX Corporation ") {
353 else if (makes.find(
"SONY") == 0) {
356 else if (makes ==
"Canon") {
388 RawFile::TypeId RawFile::vendorId()
392 if (makev ==
nullptr) {
395 if (makev !=
nullptr) {
396 std::string make = makev->getString(0);
399 model = modelv->getString(0);
401 return _typeIdFromMake(make, model) >> 16;
403 return OR_TYPEID_VENDOR_NONE;
409 auto iter = model_map.find(model_id);
410 if (iter != model_map.end()) {
436 LOGDBG1(
"_enumThumbnailSizes init\n");
439 LOGDBG1(
"_enumThumbnailSizes failed\n");
448 uint32_t smallest_bigger = 0xffffffff;
449 uint32_t biggest_smaller = 0;
450 uint32_t found_size = 0;
452 LOGDBG1(
"requested size %u\n", tsize);
456 for (
auto s : sizes) {
457 LOGDBG1(
"current iter is %u\n", s);
459 if (s > biggest_smaller) {
463 else if (s > tsize) {
464 if (s < smallest_bigger) {
474 if (found_size == 0) {
476 (smallest_bigger != 0xffffffff ? smallest_bigger : biggest_smaller);
479 if (found_size != 0) {
480 LOGDBG1(
"size %u found\n", found_size);
485 LOGDBG1(
"no size found\n");
498 auto iter = d->m_thumbLocations.find(size);
499 if (iter != d->m_thumbLocations.end()) {
504 auto byte_length = desc.
data->size();
505 void* p = thumbnail.allocData(byte_length);
506 ::memcpy(p, desc.
data->data(), byte_length);
509 uint32_t byte_length = desc.length;
510 uint32_t offset = desc.
offset;
512 LOGDBG1(
"Thumbnail at %u of %u bytes.\n", offset, byte_length);
514 if (byte_length != 0) {
515 void* p = thumbnail.allocData(byte_length);
518 if (real_size < byte_length) {
519 LOGWARN(
"Size mismatch for data: got %lu expected %u "
521 (LSIZE)real_size, byte_length);
533 d->m_thumbLocations[size] = std::move(desc);
538 LOGDBG1(
"getRawData()\n");
545 uint32_t matrix_size = 0;
548 auto matrix = std::make_unique<double[]>(matrix_size);
550 rawdata.setColourMatrix1(matrix.get(), matrix_size);
560 LOGDBG1(
"options are %u\n", options);
570 uint32_t orientation = 0;
576 orientation = value->getUInteger(0);
579 LOGDBG1(
"wrong type - %s\n", e.what());
594 ::or_error RawFile::getColourMatrix2(
double* matrix, uint32_t& size)
602 int32_t meta_index = 0;
621 return _getBuiltinColourMatrix(d->m_matrices,
typeId(), matrix, size);
623 uint32_t count = meta->getCount();
630 for (uint32_t i = 0; i < count; i++) {
631 matrix[i] = meta->getDouble(i);
640 return _getCalibrationIlluminant(1);
643 ExifLightsourceValue RawFile::getCalibrationIlluminant2()
645 return _getCalibrationIlluminant(2);
653 ExifLightsourceValue RawFile::_getCalibrationIlluminant(uint16_t index)
655 int32_t meta_index = 0;
658 meta_index =
META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT1;
661 meta_index =
META_NS_TIFF | DNG_TAG_CALIBRATION_ILLUMINANT2;
664 return EV_LIGHTSOURCE_UNKNOWN;
669 return (index == 1) ? EV_LIGHTSOURCE_D65 : EV_LIGHTSOURCE_UNKNOWN;
671 return (ExifLightsourceValue)meta->getUInteger(0);
680 LOGERR(
"IfdFile::_locateExifIfd() main IFD not found\n");
683 return _mainIfd->getExifIFD();
691 return std::dynamic_pointer_cast<Internals::MakerNoteDir>(_exifIfd->getMakerNoteIfd(
type()));
693 return Internals::MakerNoteDir::Ref();
736 auto iter = d->m_metadata.find(meta_index);
737 if (iter == d->m_metadata.end()) {
740 d->m_metadata[meta_index] = val;
757 const RawFile::camera_ids_t* RawFile::_lookupCameraId(
const camera_ids_t* map,
758 const std::string& value)
760 const camera_ids_t* p = map;
765 if (value == p->model) {
776 const RawFile::camera_ids_t* RawFile::lookupVendorId(
const camera_ids_t* map,
777 const std::string& value)
779 const camera_ids_t* p = map;
784 if (value.find(p->model) == 0) {
792 RawFile::TypeId RawFile::_typeIdFromModel(
const std::string& make,
793 const std::string& model)
795 const camera_ids_t* p = _lookupCameraId(d->m_cam_ids, model);
797 return _typeIdFromMake(make, model);
806 const RawFile::camera_ids_t RawFile::s_make[] = {
837 RawFile::TypeId RawFile::_typeIdFromMake(
const std::string& make,
const std::string& model)
839 const camera_ids_t* p = lookupVendorId(s_make, make);
846 if (model.find(
"PENTAX") != std::string::npos) {
853 void RawFile::_setIdMap(
const camera_ids_t* map)
858 const Internals::BuiltinColourMatrix* RawFile::_getMatrices()
const
860 return d->m_matrices;
863 void RawFile::_setMatrices(
const Internals::BuiltinColourMatrix* matrices)
865 d->m_matrices = matrices;
872 ::or_error RawFile::_getBuiltinLevels(
const Internals::BuiltinColourMatrix* m,
873 TypeId type_id, uint16_t& black,
880 if (m->camera == type_id) {
895 const Internals::BuiltinColourMatrix* m, TypeId type_id,
double* matrix,
906 if (m->camera == type_id) {
907 for (
int i = 0; i < 9; i++) {
908 matrix[i] =
static_cast<double>(m->matrix[i]) / 10000.0;
Represent some bitmap data.
void setDataType(DataType _type)
Set the data type.
virtual void setDimensions(uint32_t x, uint32_t y)
Set the pixel dimensions of the bitmap.
Memory based stream to read memory like a file IO.
std::shared_ptr< Stream > Ptr
std::shared_ptr< IfdDir > Ref
Shared ptr of an IfdDir.
size_t fetchData(void *buf, off_t offset, size_t buf_size) const
Fetch the data chunk from the file.
std::unique_ptr< BitmapData > data
Represent camera raw data.
const double * getColourMatrix1(uint32_t &size) const
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Internals::IfdDir::Ref m_cfaIfd
std::vector< uint32_t > m_sizes
Internals::IfdDir::Ref m_mainIfd
Internals::MakerNoteDir::Ref m_makerNoteIfd
Internals::IfdDir::Ref m_exifIfd
virtual ::or_error _getRawData(RawData &data, uint32_t options)=0
Get the RAW data.
virtual ::or_error _getThumbnail(uint32_t size, Thumbnail &thumbnail)
Get the thumbnail of exact size.
virtual Internals::MakerNoteDir::Ref _locateMakerNoteIfd()
Locate the MakerNote IFD.
::or_error getThumbnail(uint32_t size, Thumbnail &thumbnail)
Get the thumbnail from the raw file.
virtual Internals::IfdDir::Ref _locateCfaIfd()=0
Locate the IFD for the raw data.
TypeId typeId()
The RAW file type ID. Identify it if needed.
virtual bool vendorCameraIdLocation(Internals::IfdDir::Ref &ifd, uint16_t &index, const Internals::ModelIdMap *&model_map)
Get the vendor camera ID location.
void _setTypeId(TypeId _type_id)
Set the file type id.
Internals::IfdDir::Ref exifIfd()
Get the Exif IFD.
virtual Internals::IfdDir::Ref _locateExifIfd()
Locate the Exif IFD.
::or_error getRawData(RawData &rawdata, uint32_t options)
Get the RAW data.
uint32_t colourMatrixSize()
virtual ::or_error _getColourMatrix(uint32_t index, double *matrix, uint32_t &size)
Get the colour matrix.
virtual Internals::IfdDir::Ref _locateMainIfd()=0
Locate the main IFD.
virtual ::or_error _enumThumbnailSizes(std::vector< uint32_t > &list)=0
Enumerate the thumbnail sizes.
uint32_t getOrientation()
Get the orientation of the image, using Exif enums.
Internals::MakerNoteDir::Ref makerNoteIfd()
Get the MakerNote IFD.
::or_error getColourMatrix1(double *matrix, uint32_t &size)
Get colour matrix.
virtual Internals::RawContainer * getContainer() const =0
Get the container.
virtual ~RawFile()
Destructor.
virtual MetaValue * _getMetaValue(int32_t)=0
Implementation for getMetaValue()
virtual void _identifyId()=0
Identify the file and set the ID internally.
const std::vector< uint32_t > & listThumbnailSizes(void)
List the available thumbnail sizes.
::or_error getRenderedImage(BitmapData &bitmapdata, uint32_t options)
Get the rendered image.
Internals::IfdDir::Ref mainIfd()
Get the main IFD.
ExifLightsourceValue getCalibrationIlluminant1()
Get the calibration illuminant that match the colour matrix.
Internals::IfdDir::Ref cfaIfd()
Get the IFD containing the CFA.
TypeId _typeId() const
Just get the type id value. No identification. You might want to use typeId() in the general case.
const MetaValue * getMetaValue(int32_t meta_index)
Get a metadata value.
static RawFile::TypeId modelid_to_typeid(const std::map< uint32_t, RawFile::TypeId > &model_map, uint32_t model_id)
Helper to get the TypeId from the map.
virtual or_colour_matrix_origin getColourMatrixOrigin() const
Get the origin of the colour matrix for the RAW file.
Type type() const
Accessor for the type.
#define RAF_MAGIC
The RAF MAGIC string.
#define RAF_MAGIC_LEN
The length of the MAGIC strinng.
#define OR_MAKE_FILE_TYPEID(vendor, camera)
Make a or_rawfile_typeid with a vendor and camera.
or_rawfile_type
Types of RAW files.
or_colour_matrix_origin
Where the colour matrix comes from. Typically DNG is provided. The others are built-in.
or_error
Error codes returned by libopenraw.
@ OR_IFD_MAIN
Main (like in TIFF)
@ OR_IFD_EXIF
Exif metadata.
@ OR_RAWFILE_TYPE_UNKNOWN
@ OR_COLOUR_MATRIX_BUILTIN
@ OR_ERROR_NOT_IMPLEMENTED
std::map< uint32_t, ::or_rawfile_typeid > ModelIdMap
Global namespace for libopenraw.