24 #include <sys/types.h> 29 #include <libopenraw/cameraids.h> 30 #include <libopenraw/debug.h> 32 #include "thumbnail.hpp" 33 #include "rawdata.hpp" 36 #include "io/stream.hpp" 37 #include "mrwcontainer.hpp" 39 #include "ifdentry.hpp" 40 #include "ifdfilecontainer.hpp" 41 #include "mrwfile.hpp" 43 #include "rawfile_private.hpp" 45 using namespace Debug;
50 #define OR_MAKE_MINOLTA_TYPEID(camid) \ 51 OR_MAKE_FILE_TYPEID(OR_TYPEID_VENDOR_MINOLTA,camid) 54 static const BuiltinColourMatrix s_matrices[] = {
55 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_MAXXUM_5D), 0, 0xffb,
56 { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } },
57 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_MAXXUM_7D), 0, 0xffb,
58 { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } },
59 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE5), 0, 0xf7d,
60 { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } },
61 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7), 0, 0xf7d,
62 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
63 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7I), 0, 0xf7d,
64 { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } },
65 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7HI), 0, 0xf7d,
66 { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } },
67 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A1), 0, 0xf8b,
68 { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } },
69 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A2), 0, 0xf8f,
70 { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } },
71 { OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A200), 0, 0,
72 { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } },
74 { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0, 0 } }
78 {
"21860002", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_MAXXUM_5D) },
79 {
"21810002", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_MAXXUM_7D) },
80 {
"27730001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE5) },
81 {
"27660001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7) },
82 {
"27790001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7I) },
83 {
"27780001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_DIMAGE7HI) },
84 {
"27820001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A1) },
85 {
"27200001", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A2) },
86 {
"27470002", OR_MAKE_MINOLTA_TYPEID(OR_TYPEID_MINOLTA_A200) },
90 RawFile *MRWFile::factory(
const IO::Stream::Ptr &_f)
95 MRWFile::MRWFile(
const IO::Stream::Ptr &_f)
96 :
IfdFile(_f, OR_RAWFILE_TYPE_MRW,
false)
99 _setMatrices(s_matrices);
107 IfdDir::Ref MRWFile::_locateCfaIfd()
114 IfdDir::Ref MRWFile::_locateMainIfd()
116 return m_container->setDirectory(0);
120 void MRWFile::_identifyId()
126 const IfdDir::Ref & _mainIfd = mainIfd();
128 if(_mainIfd && mc->prd) {
129 auto version = mc->prd->string_val(MRW::PRD_VERSION);
131 _setTypeId(_typeIdFromModel(
"Minolta", version.unwrap()));
133 LOGERR(
"Coudln't read Minolta version\n");
140 ::or_error MRWFile::_enumThumbnailSizes(std::vector<uint32_t> &list)
142 ::or_error err = OR_ERROR_NOT_FOUND;
143 list.push_back (640);
149 ::or_error MRWFile::_getThumbnail(uint32_t ,
Thumbnail & thumbnail)
156 dir = _locateExifIfd();
158 LOGWARN(
"EXIF dir not found\n");
159 return OR_ERROR_NOT_FOUND;
162 maker_ent = dir->getEntry(IFD::EXIF_TAG_MAKER_NOTE);
164 LOGWARN(
"maker note offset entry not found\n");
165 return OR_ERROR_NOT_FOUND;
168 off = maker_ent->offset();
170 IfdDir::Ref ref(std::make_shared<IfdDir>(
172 + MRW::DataBlockHeaderLength + off,
176 uint32_t tnail_offset = 0;
177 uint32_t tnail_len = 0;
178 thumb_ent = ref->getEntry(MRW::MRWTAG_THUMBNAIL);
180 tnail_offset = thumb_ent->offset();
181 tnail_len = thumb_ent->count();
183 auto result = ref->getValue<uint32_t>(MRW::MRWTAG_THUMBNAIL_OFFSET);
184 if (result.empty()) {
185 LOGWARN(
"thumbnail offset entry not found\n");
186 return OR_ERROR_NOT_FOUND;
188 tnail_offset = result.unwrap();
190 result = ref->getValue<uint32_t>(MRW::MRWTAG_THUMBNAIL_LENGTH);
191 if (result.empty()) {
192 LOGWARN(
"thumbnail lenght entry not found\n");
193 return OR_ERROR_NOT_FOUND;
195 tnail_len = result.unwrap();
198 LOGDBG1(
"thumbnail offset found, offset == %u count == %u\n",
199 tnail_offset, tnail_len);
200 void *p = thumbnail.allocData (tnail_len);
201 size_t fetched = m_container->fetchData(p, mc->ttw->offset()
202 + MRW::DataBlockHeaderLength
205 if (fetched != tnail_len) {
206 LOGWARN(
"Unable to fetch all thumbnail data: %lu not %u bytes\n",
210 ((
unsigned char *)p)[0] = 0xFF;
214 return OR_ERROR_NONE;
218 ::or_error MRWFile::_getRawData(
RawData & data, uint32_t options)
220 or_error ret = OR_ERROR_NONE;
224 return OR_ERROR_NOT_FOUND;
227 uint16_t y = mc->prd->uint16_val (MRW::PRD_SENSOR_LENGTH).unwrap_or(0);
228 uint16_t x = mc->prd->uint16_val (MRW::PRD_SENSOR_WIDTH).unwrap_or(0);
229 uint8_t bpc = mc->prd->uint8_val (MRW::PRD_PIXEL_SIZE).unwrap_or(0);
231 bool is_compressed = (mc->prd->uint8_val(MRW::PRD_STORAGE_TYPE).unwrap_or(0) == 0x59);
236 uint32_t finaldatalen = 2 * x * y;
238 (is_compressed ? x * y + ((x * y) >> 1) : finaldatalen);
240 if(options & OR_OPTIONS_DONT_DECOMPRESS) {
241 finaldatalen = datalen;
243 if(is_compressed && (options & OR_OPTIONS_DONT_DECOMPRESS)) {
253 RawFile::_getBuiltinLevels(_getMatrices(), typeId(),
255 data.setBlackLevel(black);
256 data.setWhiteLevel(white);
257 LOGDBG1(
"datalen = %d final datalen = %u\n", datalen, finaldatalen);
258 void *p = data.allocData(finaldatalen);
261 if(!is_compressed || (options & OR_OPTIONS_DONT_DECOMPRESS)) {
262 fetched = m_container->fetchData (p, offset, datalen);
265 Unpack unpack(x, IFD::COMPRESS_NONE);
266 size_t blocksize = unpack.block_size();
267 std::unique_ptr<uint8_t[]> block(
new uint8_t[blocksize]);
268 uint8_t * outdata = (uint8_t*)data.data();
269 size_t outsize = finaldatalen;
272 LOGDBG2(
"fetchData @offset %ld\n", offset);
273 got = m_container->fetchData (block.get(),
277 LOGDBG2(
"got %ld\n", got);
281 block.get(), got, out);
284 LOGDBG2(
"unpacked %ld bytes from %ld\n", out, got);
285 if(err != OR_ERROR_NONE) {
290 }
while((got != 0) && (fetched < datalen));
292 if (fetched < datalen) {
293 LOGWARN(
"Fetched only %ld of %u: continuing anyway.\n", fetched,
296 uint16_t bpat = mc->prd->uint16_val (MRW::PRD_BAYER_PATTERN).unwrap_or(0);
297 or_cfa_pattern cfa_pattern = OR_CFA_PATTERN_NONE;
301 cfa_pattern = OR_CFA_PATTERN_RGGB;
304 cfa_pattern = OR_CFA_PATTERN_GBRG;
309 data.setCfaPatternType(cfa_pattern);
CIFF is the container for CRW files. It is an attempt from Canon to make this a standard. I guess it failed.
or_error unpack_be12to16(uint8_t *dest, size_t destsize, const uint8_t *src, size_t size, size_t &outsize)
virtual void setDimensions(uint32_t x, uint32_t y)
void setBpc(uint32_t _bpc)
std::shared_ptr< IfdEntry > Ref
void setDataType(DataType _type)
generic IFD based raw file.
virtual void setDimensions(uint32_t x, uint32_t y) override