30 #include <libopenraw/debug.h>
31 #include <libopenraw/metadata.h>
32 #include <libopenraw/cameraids.h>
34 #include "rawdata.hpp"
35 #include "metavalue.hpp"
36 #include "mosaicinfo.hpp"
37 #include "rawfile.hpp"
39 #include "io/streamclone.hpp"
40 #include "io/memstream.hpp"
41 #include "crwfile.hpp"
42 #include "ciffcontainer.hpp"
43 #include "jfifcontainer.hpp"
44 #include "crwdecompressor.hpp"
45 #include "rawfile_private.hpp"
47 #include "ciff/ciffifd.hpp"
49 using namespace Debug;
57 #define OR_MAKE_CANON_TYPEID(camid) \
58 OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_CANON,camid)
61 static const BuiltinColourMatrix s_matrices[] = {
62 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D30), 0, 0,
63 { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } },
64 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D60), 0, 0xfa0,
65 { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } },
66 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_10D), 0, 0xfa0,
67 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
68 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_300D), 0, 0xfa0,
69 { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } },
72 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G2), 0, 0,
73 { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } },
74 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3), 0, 0,
75 { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } },
76 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5), 0, 0,
77 { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } },
78 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G6), 0, 0,
79 { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } },
80 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO1), 0, 0,
81 { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } },
82 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S30), 0, 0,
83 { 10566, -3652, -1129, -6552, 14662, 2006, -2197, 2581, 7670 } },
84 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S40), 0, 0,
85 { 8510, -2487, -940, -6869, 14231, 2900, -2318, 2829, 9013 } },
86 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S45), 0, 0,
87 { 8163, -2333, -955, -6682, 14174, 2751, -2077, 2597, 8041 } },
88 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S50), 0, 0,
89 { 8882, -2571, -863, -6348, 14234, 2288, -1516, 2172, 6569 } },
90 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S60), 0, 0,
91 { 8795, -2482, -797, -7804, 15403, 2573, -1422, 1996, 7082 } },
92 { OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S70), 0, 0,
93 { 9976, -3810, -832, -7115, 14463, 2906, -901, 989, 7889 } },
94 { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
97 const RawFile::camera_ids_t CRWFile::s_def[] = {
98 {
"Canon EOS D30" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D30) },
99 {
"Canon EOS D60" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_D60) },
100 {
"Canon EOS 10D" , OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_10D) },
101 {
"Canon EOS DIGITAL REBEL", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_DIGITAL_REBEL) },
102 {
"Canon EOS 300D DIGITAL", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_300D) },
103 {
"Canon PowerShot G1", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G1) },
104 {
"Canon PowerShot G2", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G2) },
105 {
"Canon PowerShot G3", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G3) },
106 {
"Canon PowerShot G5", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G5) },
107 {
"Canon PowerShot G6", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_G6) },
110 {
"Canon PowerShot Pro1", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO1) },
111 {
"Canon PowerShot Pro70", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO70) },
112 {
"Canon PowerShot Pro90 IS", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_PRO90) },
113 {
"Canon PowerShot S30", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S30) },
114 {
"Canon PowerShot S40", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S40) },
115 {
"Canon PowerShot S45", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S45) },
116 {
"Canon PowerShot S50", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S50) },
117 {
"Canon PowerShot S60", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S60) },
118 {
"Canon PowerShot S70", OR_MAKE_CANON_TYPEID(OR_TYPEID_CANON_S70) },
122 RawFile *CRWFile::factory(
const IO::Stream::Ptr &s)
124 return new CRWFile(s);
127 CRWFile::CRWFile(
const IO::Stream::Ptr &s)
130 m_container(new CIFFContainer(m_io)),
134 _setMatrices(s_matrices);
142 ::or_error CRWFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
146 HeapRef heap = m_container->heap();
152 RecordEntries::const_iterator iter;
153 iter = records.find(TAG_JPEGIMAGE);
154 if (iter != records.end()) {
155 LOGDBG2(
"JPEG @%u\n", iter->second.offset());
157 uint32_t offset = heap->offset() + iter->second.offset();
159 auto jfif = std::make_unique<JfifContainer>(s, 0);
161 jfif->getDimensions(m_x, m_y);
162 LOGDBG1(
"JPEG dimensions x=%d y=%d\n", m_x, m_y);
163 uint32_t dim = std::max(m_x,m_y);
181 const ImageSpec * img_spec = m_container->getImageSpec();
190 HeapRef exifProps = m_container->getExifInfo();
192 LOGERR(
"Couldn't find the exif info table.\n");
196 auto iter = exifPropsRecs.find(TAG_DECODERTABLE);
197 if (iter == exifPropsRecs.end()) {
198 LOGERR(
"Couldn't find the decoder table.\n");
201 LOGDBG2(
"length = %d\n", iter->second.length());
202 LOGDBG2(
"offset = %lld\n", (
long long int)(exifProps->offset() + iter->second.offset()));
203 auto file = m_container->file();
204 file->seek(exifProps->offset() + iter->second.offset(), SEEK_SET);
206 auto result = m_container->readUInt32(file, m_container->endian());
208 LOGERR(
"Couldn't find decoder table\n");
212 uint32_t decoderTable = result.value();
213 LOGDBG2(
"decoder table = %u\n", decoderTable);
216 iter = exifPropsRecs.find(TAG_SENSORINFO);
217 if (iter == exifPropsRecs.end()) {
218 LOGERR(
"Couldn't find the sensor info.\n");
221 LOGDBG2(
"length = %u\n", iter->second.length());
222 LOGDBG2(
"offset = %lld\n", (
long long int)(exifProps->offset() + iter->second.offset()));
226 file->seek(exifProps->offset() + iter->second.offset(), SEEK_SET);
228 std::vector<uint16_t> sensor_info;
229 auto count_read = m_container->readUInt16Array(file, sensor_info, 9);
230 if (count_read != 9) {
231 LOGERR(
"SensorInfo short read %lu.\n", (LSIZE)count_read);
234 LOGDBG1(
"read sensor info %lu\n", (LSIZE)count_read);
235 auto cfa_x = sensor_info[1];
236 auto cfa_y = sensor_info[2];
237 LOGDBG2(
"cfa, x %u, y %u\n", cfa_x, cfa_y);
241 LOGERR(
"SensorInfo: couldn't get active area.\n");
245 const RecordEntry *entry = m_container->getRawDataRecord();
248 LOGDBG2(
"RAW @%lld\n", (
long long int)(heap->offset() + entry->
offset()));
249 size_t byte_size = entry->
length();
250 void *buf = data.allocData(byte_size);
251 size_t real_size = entry->
fetchData(heap.get(), buf, byte_size);
252 if (real_size != byte_size) {
253 LOGWARN(
"wrong size\n");
256 data.setCfaPatternType(OR_CFA_PATTERN_RGGB);
261 auto s = std::make_unique<IO::MemStream>((
const uint8_t*)data.data(), data.
size());
266 decomp.setOutputDimensions(cfa_x, cfa_y);
267 decomp.setDecoderTable(decoderTable);
270 LOGDBG1(
"Out size is %dx%d\n", dData->width(), dData->height());
272 dData->setPhotometricInterpretation(data.getPhotometricInterpretation());
276 data.setActiveArea((*active_area)[0], (*active_area)[1],
277 (*active_area)[2], (*active_area)[3]);
285 const ImageSpec * img_spec = m_container->getImageSpec();
294 if (index == EXIF_TAG_MAKE && !m_make.empty()) {
296 }
else if (index == EXIF_TAG_MODEL && !m_model.empty()) {
303 auto propsRecs = heap->records();
304 auto iter = propsRecs.find(TAG_RAWMAKEMODEL);
305 if (iter == propsRecs.end()) {
306 LOGERR(
"Couldn't find the image info.\n");
309 size_t sz = iter->second.length();
313 iter->second.fetchData(heap.get(),
319 m_make = std::string(buf, p - buf);
323 if (index == EXIF_TAG_MODEL) {
325 }
else if (index == EXIF_TAG_MAKE) {
328 LOGDBG1(
"Make %s\n", m_make.c_str());
329 LOGDBG1(
"Model %s\n", m_model.c_str());
344 case EXIF_TAG_ORIENTATION:
346 auto orientation = getOrientation();
348 val =
new MetaValue(orientation.value());
355 auto tag = getMakeOrModel(index);
367 LOGERR(
"Unknown Meta Namespace\n");
376 auto ifd = std::make_shared<CiffMainIfd>(*
this, *m_container);
383 auto ifd = std::make_shared<CiffExifIfd>(*
this, *m_container);
388 void CRWFile::_identifyId()
395 model = v->getString(0);
400 make = v->getString(0);
403 _setTypeId(_typeIdFromModel(make, model));
void setDataType(DataType _type)
Set the data type.
size_t size() const
Get the size of the data.
cloned stream. Allow reading from a different offset
std::shared_ptr< Stream > Ptr
ImageSpec struct from CIFF.
int32_t exifOrientation() const
A record entry from a CIFF Heap.
size_t fetchData(Heap *heap, void *buf, size_t size) const
Heap heap(Heap &h, const CIFFContainer *container) const
virtual RawDataPtr decompress() override
std::shared_ptr< IfdDir > Ref
Shared ptr of an IfdDir.
Generic interface for the RAW file container.
::or_cfa_pattern patternType() const
Represent camera raw data.
const MosaicInfo * mosaicInfo() const
virtual void setDimensions(uint32_t x, uint32_t y) override
Set the pixel dimensions of the bitmap.
Tag class to help create an empty Option.
An option type inspired by Rust.
Option< std::array< uint32_t, 4 > > canon_parse_sensorinfo(const std::vector< uint16_t > &sensor_info)
Parse the sensor info from a buffer of uint16_t.
std::shared_ptr< Heap > HeapRef
Shared ptr to Heap.
or_error
Error codes returned by libopenraw.
@ OR_DATA_TYPE_COMPRESSED_RAW
@ OR_OPTIONS_DONT_DECOMPRESS
std::map< uint16_t, RecordEntry > RecordEntries
Global namespace for libopenraw.