File indexing completed on 2025-01-05 03:57:08
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 0005 LibRaw is free software; you can redistribute it and/or modify 0006 it under the terms of the one of two licenses as you choose: 0007 0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0009 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0010 0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0012 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0013 0014 */ 0015 0016 #include "../../internal/libraw_cxx_defs.h" 0017 #include "../../internal/libraw_cameraids.h" 0018 0019 #ifndef LIBRAW_NO_IOSTREAMS_DATASTREAM 0020 int LibRaw::open_file(const char *fname, INT64 max_buf_size) 0021 { 0022 int big = 0; 0023 if (max_buf_size == LIBRAW_OPEN_BIGFILE) 0024 big = 1; 0025 else if (max_buf_size == LIBRAW_OPEN_FILE) 0026 big = 0; 0027 else 0028 { 0029 #ifndef LIBRAW_WIN32_CALLS 0030 struct stat st; 0031 if (stat(fname, &st)) 0032 return LIBRAW_IO_ERROR; 0033 big = (st.st_size > max_buf_size) ? 1 : 0; 0034 #else 0035 struct _stati64 st; 0036 if (_stati64(fname, &st)) 0037 return LIBRAW_IO_ERROR; 0038 big = (st.st_size > max_buf_size) ? 1 : 0; 0039 #endif 0040 } 0041 0042 LibRaw_abstract_datastream *stream; 0043 try 0044 { 0045 if (big) 0046 stream = new LibRaw_bigfile_datastream(fname); 0047 else 0048 stream = new LibRaw_file_datastream(fname); 0049 } 0050 0051 catch (const std::bad_alloc& ) 0052 { 0053 recycle(); 0054 return LIBRAW_UNSUFFICIENT_MEMORY; 0055 } 0056 if (!stream->valid()) 0057 { 0058 delete stream; 0059 return LIBRAW_IO_ERROR; 0060 } 0061 ID.input_internal = 0; // preserve from deletion on error 0062 int ret = open_datastream(stream); 0063 if (ret == LIBRAW_SUCCESS) 0064 { 0065 ID.input_internal = 1; // flag to delete datastream on recycle 0066 } 0067 else 0068 { 0069 delete stream; 0070 ID.input_internal = 0; 0071 } 0072 return ret; 0073 } 0074 0075 #if defined(WIN32) || defined(_WIN32) 0076 #ifndef LIBRAW_WIN32_UNICODEPATHS 0077 int LibRaw::open_file(const wchar_t *, INT64) 0078 { 0079 return LIBRAW_NOT_IMPLEMENTED; 0080 } 0081 #else 0082 int LibRaw::open_file(const wchar_t *fname, INT64 max_buf_size) 0083 { 0084 int big = 0; 0085 if (max_buf_size == LIBRAW_OPEN_BIGFILE) 0086 big = 1; 0087 else if (max_buf_size == LIBRAW_OPEN_FILE) 0088 big = 0; 0089 else 0090 { 0091 struct _stati64 st; 0092 if (_wstati64(fname, &st)) 0093 return LIBRAW_IO_ERROR; 0094 big = (st.st_size > max_buf_size) ? 1 : 0; 0095 } 0096 0097 LibRaw_abstract_datastream *stream; 0098 try 0099 { 0100 if (big) 0101 stream = new LibRaw_bigfile_datastream(fname); 0102 else 0103 stream = new LibRaw_file_datastream(fname); 0104 } 0105 0106 catch (const std::bad_alloc&) 0107 { 0108 recycle(); 0109 return LIBRAW_UNSUFFICIENT_MEMORY; 0110 } 0111 if (!stream->valid()) 0112 { 0113 delete stream; 0114 return LIBRAW_IO_ERROR; 0115 } 0116 ID.input_internal = 0; // preserve from deletion on error 0117 int ret = open_datastream(stream); 0118 if (ret == LIBRAW_SUCCESS) 0119 { 0120 ID.input_internal = 1; // flag to delete datastream on recycle 0121 } 0122 else 0123 { 0124 delete stream; 0125 ID.input_internal = 0; 0126 } 0127 return ret; 0128 } 0129 #endif 0130 #endif 0131 0132 #else /* LIBRAW_NO_IOSTREAMS_DATASTREAM*/ 0133 0134 int LibRaw::libraw_openfile_tail(LibRaw_abstract_datastream *stream) 0135 { 0136 if (!stream->valid()) 0137 { 0138 delete stream; 0139 return LIBRAW_IO_ERROR; 0140 } 0141 ID.input_internal = 0; // preserve from deletion on error 0142 int ret = open_datastream(stream); 0143 if (ret == LIBRAW_SUCCESS) 0144 { 0145 ID.input_internal = 1; // flag to delete datastream on recycle 0146 } 0147 else 0148 { 0149 delete stream; 0150 ID.input_internal = 0; 0151 } 0152 return ret; 0153 } 0154 0155 int LibRaw::open_file(const char *fname) 0156 { 0157 LibRaw_abstract_datastream *stream; 0158 try 0159 { 0160 #ifdef LIBRAW_WIN32_CALLS 0161 stream = new LibRaw_bigfile_buffered_datastream(fname); 0162 #else 0163 stream = new LibRaw_bigfile_datastream(fname); 0164 #endif 0165 } 0166 catch (const std::bad_alloc&) 0167 { 0168 recycle(); 0169 return LIBRAW_UNSUFFICIENT_MEMORY; 0170 } 0171 if ((stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE)) 0172 { 0173 delete stream; 0174 return LIBRAW_TOO_BIG; 0175 } 0176 return libraw_openfile_tail(stream); 0177 } 0178 0179 #if defined(WIN32) || defined(_WIN32) 0180 #ifndef LIBRAW_WIN32_UNICODEPATHS 0181 int LibRaw::open_file(const wchar_t *) 0182 { 0183 return LIBRAW_NOT_IMPLEMENTED; 0184 } 0185 #else 0186 int LibRaw::open_file(const wchar_t *fname) 0187 { 0188 LibRaw_abstract_datastream *stream; 0189 try 0190 { 0191 #ifdef LIBRAW_WIN32_CALLS 0192 stream = new LibRaw_bigfile_buffered_datastream(fname); 0193 #else 0194 stream = new LibRaw_bigfile_datastream(fname); 0195 #endif 0196 } 0197 catch (const std::bad_alloc&) 0198 { 0199 recycle(); 0200 return LIBRAW_UNSUFFICIENT_MEMORY; 0201 } 0202 if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) 0203 { 0204 delete stream; 0205 return LIBRAW_TOO_BIG; 0206 } 0207 0208 return libraw_openfile_tail(stream); 0209 } 0210 #endif 0211 #endif 0212 0213 #endif 0214 0215 int LibRaw::open_buffer(const void *buffer, size_t size) 0216 { 0217 // this stream will close on recycle() 0218 if (!buffer || buffer == (const void *)-1) 0219 return LIBRAW_IO_ERROR; 0220 0221 if ((size > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (size > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) 0222 return LIBRAW_TOO_BIG; 0223 0224 LibRaw_buffer_datastream *stream; 0225 try 0226 { 0227 stream = new LibRaw_buffer_datastream(buffer, size); 0228 } 0229 catch (const std::bad_alloc& ) 0230 { 0231 recycle(); 0232 return LIBRAW_UNSUFFICIENT_MEMORY; 0233 } 0234 if (!stream->valid()) 0235 { 0236 delete stream; 0237 return LIBRAW_IO_ERROR; 0238 } 0239 ID.input_internal = 0; // preserve from deletion on error 0240 int ret = open_datastream(stream); 0241 if (ret == LIBRAW_SUCCESS) 0242 { 0243 ID.input_internal = 1; // flag to delete datastream on recycle 0244 } 0245 else 0246 { 0247 delete stream; 0248 ID.input_internal = 0; 0249 } 0250 return ret; 0251 } 0252 0253 int LibRaw::open_bayer(const unsigned char *buffer, unsigned datalen, 0254 ushort _raw_width, ushort _raw_height, 0255 ushort _left_margin, ushort _top_margin, 0256 ushort _right_margin, ushort _bottom_margin, 0257 unsigned char procflags, unsigned char bayer_pattern, 0258 unsigned unused_bits, unsigned otherflags, 0259 unsigned black_level) 0260 { 0261 // this stream will close on recycle() 0262 if (!buffer || buffer == (const void *)-1) 0263 return LIBRAW_IO_ERROR; 0264 0265 LibRaw_buffer_datastream *stream; 0266 try 0267 { 0268 stream = new LibRaw_buffer_datastream(buffer, datalen); 0269 } 0270 catch (const std::bad_alloc& ) 0271 { 0272 recycle(); 0273 return LIBRAW_UNSUFFICIENT_MEMORY; 0274 } 0275 if (!stream->valid()) 0276 { 0277 delete stream; 0278 return LIBRAW_IO_ERROR; 0279 } 0280 ID.input = stream; 0281 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); 0282 // From identify 0283 initdata(); 0284 strcpy(imgdata.idata.make, "BayerDump"); 0285 snprintf(imgdata.idata.model, sizeof(imgdata.idata.model) - 1, 0286 "%u x %u pixels", _raw_width, _raw_height); 0287 S.flip = procflags >> 2; 0288 libraw_internal_data.internal_output_params.zero_is_bad = procflags & 2; 0289 libraw_internal_data.unpacker_data.data_offset = 0; 0290 S.raw_width = _raw_width; 0291 S.raw_height = _raw_height; 0292 S.left_margin = _left_margin; 0293 S.top_margin = _top_margin; 0294 S.width = S.raw_width - S.left_margin - _right_margin; 0295 S.height = S.raw_height - S.top_margin - _bottom_margin; 0296 0297 imgdata.idata.filters = 0x1010101 * bayer_pattern; 0298 imgdata.idata.colors = 0299 4 - !((imgdata.idata.filters & imgdata.idata.filters >> 1) & 0x5555); 0300 libraw_internal_data.unpacker_data.load_flags = otherflags; 0301 switch (libraw_internal_data.unpacker_data.tiff_bps = 0302 (datalen)*8 / (S.raw_width * S.raw_height)) 0303 { 0304 case 8: 0305 load_raw = &LibRaw::eight_bit_load_raw; 0306 break; 0307 case 10: 0308 if ((datalen) / S.raw_height * 3u >= S.raw_width * 4u) 0309 { 0310 load_raw = &LibRaw::android_loose_load_raw; 0311 break; 0312 } 0313 else if (libraw_internal_data.unpacker_data.load_flags & 1) 0314 { 0315 load_raw = &LibRaw::android_tight_load_raw; 0316 break; 0317 } 0318 case 12: 0319 libraw_internal_data.unpacker_data.load_flags |= 128; 0320 load_raw = &LibRaw::packed_load_raw; 0321 break; 0322 case 16: 0323 libraw_internal_data.unpacker_data.order = 0324 0x4949 | 0x404 * (libraw_internal_data.unpacker_data.load_flags & 1); 0325 libraw_internal_data.unpacker_data.tiff_bps -= 0326 libraw_internal_data.unpacker_data.load_flags >> 4; 0327 libraw_internal_data.unpacker_data.tiff_bps -= 0328 libraw_internal_data.unpacker_data.load_flags = 0329 libraw_internal_data.unpacker_data.load_flags >> 1 & 7; 0330 load_raw = &LibRaw::unpacked_load_raw; 0331 } 0332 C.maximum = 0333 (1 << libraw_internal_data.unpacker_data.tiff_bps) - (1 << unused_bits); 0334 C.black = black_level; 0335 S.iwidth = S.width; 0336 S.iheight = S.height; 0337 imgdata.idata.colors = 3; 0338 imgdata.idata.filters |= ((imgdata.idata.filters >> 2 & 0x22222222) | 0339 (imgdata.idata.filters << 2 & 0x88888888)) & 0340 imgdata.idata.filters << 1; 0341 0342 imgdata.idata.raw_count = 1; 0343 for (int i = 0; i < 4; i++) 0344 imgdata.color.pre_mul[i] = 1.0; 0345 0346 strcpy(imgdata.idata.cdesc, "RGBG"); 0347 0348 ID.input_internal = 1; 0349 SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); 0350 return LIBRAW_SUCCESS; 0351 } 0352 0353 struct foveon_data_t 0354 { 0355 const char *make; 0356 const char *model; 0357 const int raw_width, raw_height; 0358 const int white; 0359 const int left_margin, top_margin; 0360 const int width, height; 0361 } foveon_data[] = { 0362 {"Sigma", "SD9", 2304, 1531, 12000, 20, 8, 2266, 1510}, 0363 {"Sigma", "SD9", 1152, 763, 12000, 10, 2, 1132, 755}, 0364 {"Sigma", "SD10", 2304, 1531, 12000, 20, 8, 2266, 1510}, 0365 {"Sigma", "SD10", 1152, 763, 12000, 10, 2, 1132, 755}, 0366 {"Sigma", "SD14", 2688, 1792, 14000, 18, 12, 2651, 1767}, 0367 {"Sigma", "SD14", 2688, 896, 14000, 18, 6, 2651, 883}, // 2/3 0368 {"Sigma", "SD14", 1344, 896, 14000, 9, 6, 1326, 883}, // 1/2 0369 {"Sigma", "SD15", 2688, 1792, 2900, 18, 12, 2651, 1767}, 0370 {"Sigma", "SD15", 2688, 896, 2900, 18, 6, 2651, 883}, // 2/3 ? 0371 {"Sigma", "SD15", 1344, 896, 2900, 9, 6, 1326, 883}, // 1/2 ? 0372 {"Sigma", "DP1", 2688, 1792, 2100, 18, 12, 2651, 1767}, 0373 {"Sigma", "DP1", 2688, 896, 2100, 18, 6, 2651, 883}, // 2/3 ? 0374 {"Sigma", "DP1", 1344, 896, 2100, 9, 6, 1326, 883}, // 1/2 ? 0375 {"Sigma", "DP1S", 2688, 1792, 2200, 18, 12, 2651, 1767}, 0376 {"Sigma", "DP1S", 2688, 896, 2200, 18, 6, 2651, 883}, // 2/3 0377 {"Sigma", "DP1S", 1344, 896, 2200, 9, 6, 1326, 883}, // 1/2 0378 {"Sigma", "DP1X", 2688, 1792, 3560, 18, 12, 2651, 1767}, 0379 {"Sigma", "DP1X", 2688, 896, 3560, 18, 6, 2651, 883}, // 2/3 0380 {"Sigma", "DP1X", 1344, 896, 3560, 9, 6, 1326, 883}, // 1/2 0381 {"Sigma", "DP2", 2688, 1792, 2326, 13, 16, 2651, 1767}, 0382 {"Sigma", "DP2", 2688, 896, 2326, 13, 8, 2651, 883}, // 2/3 ?? 0383 {"Sigma", "DP2", 1344, 896, 2326, 7, 8, 1325, 883}, // 1/2 ?? 0384 {"Sigma", "DP2S", 2688, 1792, 2300, 18, 12, 2651, 1767}, 0385 {"Sigma", "DP2S", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 0386 {"Sigma", "DP2S", 1344, 896, 2300, 9, 6, 1326, 883}, // 1/2 0387 {"Sigma", "DP2X", 2688, 1792, 2300, 18, 12, 2651, 1767}, 0388 {"Sigma", "DP2X", 2688, 896, 2300, 18, 6, 2651, 883}, // 2/3 0389 {"Sigma", "DP2X", 1344, 896, 2300, 9, 6, 1325, 883}, // 1/2 0390 {"Sigma", "SD1", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size 0391 {"Sigma", "SD1", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size 0392 {"Sigma", "SD1", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size 0393 {"Sigma", "SD1 Merrill", 4928, 3264, 3900, 12, 52, 4807, 3205}, // Full size 0394 {"Sigma", "SD1 Merrill", 4928, 1632, 3900, 12, 26, 4807, 1603}, // 2/3 size 0395 {"Sigma", "SD1 Merrill", 2464, 1632, 3900, 6, 26, 2403, 1603}, // 1/2 size 0396 {"Sigma", "DP1 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, 0397 {"Sigma", "DP1 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size 0398 {"Sigma", "DP1 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size 0399 {"Sigma", "DP2 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, 0400 {"Sigma", "DP2 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size 0401 {"Sigma", "DP2 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size 0402 {"Sigma", "DP3 Merrill", 4928, 3264, 3900, 12, 0, 4807, 3205}, 0403 {"Sigma", "DP3 Merrill", 2464, 1632, 3900, 12, 0, 2403, 1603}, // 1/2 size 0404 {"Sigma", "DP3 Merrill", 4928, 1632, 3900, 12, 0, 4807, 1603}, // 2/3 size 0405 {"Polaroid", "x530", 1440, 1088, 2700, 10, 13, 1419, 1059}, 0406 // dp2 Q 0407 {"Sigma", "dp3 Quattro", 5888, 3776, 16383, 204, 76, 5446, 0408 3624}, // full size, new fw ?? 0409 {"Sigma", "dp3 Quattro", 5888, 3672, 16383, 204, 24, 5446, 0410 3624}, // full size 0411 {"Sigma", "dp3 Quattro", 2944, 1836, 16383, 102, 12, 2723, 0412 1812}, // half size 0413 {"Sigma", "dp3 Quattro", 2944, 1888, 16383, 102, 38, 2723, 0414 1812}, // half size, new fw?? 0415 0416 {"Sigma", "dp2 Quattro", 5888, 3776, 16383, 204, 76, 5446, 0417 3624}, // full size, new fw 0418 {"Sigma", "dp2 Quattro", 5888, 3672, 16383, 204, 24, 5446, 0419 3624}, // full size 0420 {"Sigma", "dp2 Quattro", 2944, 1836, 16383, 102, 12, 2723, 0421 1812}, // half size 0422 {"Sigma", "dp2 Quattro", 2944, 1888, 16383, 102, 38, 2723, 0423 1812}, // half size, new fw 0424 0425 {"Sigma", "dp1 Quattro", 5888, 3776, 16383, 204, 76, 5446, 0426 3624}, // full size, new fw?? 0427 {"Sigma", "dp1 Quattro", 5888, 3672, 16383, 204, 24, 5446, 0428 3624}, // full size 0429 {"Sigma", "dp1 Quattro", 2944, 1836, 16383, 102, 12, 2723, 0430 1812}, // half size 0431 {"Sigma", "dp1 Quattro", 2944, 1888, 16383, 102, 38, 2723, 0432 1812}, // half size, new fw 0433 0434 {"Sigma", "dp0 Quattro", 5888, 3776, 16383, 204, 76, 5446, 0435 3624}, // full size, new fw?? 0436 {"Sigma", "dp0 Quattro", 5888, 3672, 16383, 204, 24, 5446, 0437 3624}, // full size 0438 {"Sigma", "dp0 Quattro", 2944, 1836, 16383, 102, 12, 2723, 0439 1812}, // half size 0440 {"Sigma", "dp0 Quattro", 2944, 1888, 16383, 102, 38, 2723, 0441 1812}, // half size, new fw 0442 // Sigma sd Quattro 0443 {"Sigma", "sd Quattro", 5888, 3776, 16383, 204, 76, 5446, 0444 3624}, // full size 0445 {"Sigma", "sd Quattro", 2944, 1888, 16383, 102, 38, 2723, 0446 1812}, // half size 0447 // Sd Quattro H 0448 {"Sigma", "sd Quattro H", 6656, 4480, 4000, 224, 160, 6208, 0449 4160}, // full size 0450 {"Sigma", "sd Quattro H", 3328, 2240, 4000, 112, 80, 3104, 0451 2080}, // half size 0452 {"Sigma", "sd Quattro H", 5504, 3680, 4000, 0, 4, 5496, 3668}, // full size 0453 {"Sigma", "sd Quattro H", 2752, 1840, 4000, 0, 2, 2748, 1834}, // half size 0454 }; 0455 const int foveon_count = sizeof(foveon_data) / sizeof(foveon_data[0]); 0456 0457 int LibRaw::open_datastream(LibRaw_abstract_datastream *stream) 0458 { 0459 0460 if (!stream) 0461 return ENOENT; 0462 if (!stream->valid()) 0463 return LIBRAW_IO_ERROR; 0464 if ((stream->size() > (INT64)LIBRAW_MAX_DNG_RAW_FILE_SIZE) && (stream->size() > (INT64)LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)) 0465 return LIBRAW_TOO_BIG; 0466 0467 recycle(); 0468 if (callbacks.pre_identify_cb) 0469 { 0470 int r = (callbacks.pre_identify_cb)(this); 0471 if (r == 1) 0472 goto final; 0473 } 0474 0475 try 0476 { 0477 ID.input = stream; 0478 SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN); 0479 0480 identify(); 0481 0482 // Fuji layout files: either DNG or unpacked_load_raw should be used 0483 if (libraw_internal_data.internal_output_params.fuji_width || libraw_internal_data.unpacker_data.fuji_layout) 0484 { 0485 if (!imgdata.idata.dng_version && load_raw != &LibRaw::unpacked_load_raw 0486 && load_raw != &LibRaw::unpacked_load_raw_FujiDBP 0487 && load_raw != &LibRaw::unpacked_load_raw_fuji_f700s20 0488 ) 0489 return LIBRAW_FILE_UNSUPPORTED; 0490 } 0491 0492 // promote the old single thumbnail to the thumbs_list if not present already 0493 if (imgdata.thumbs_list.thumbcount < LIBRAW_THUMBNAIL_MAXCOUNT) 0494 { 0495 bool already = false; 0496 if(imgdata.thumbnail.tlength || libraw_internal_data.internal_data.toffset) 0497 for(int i = 0; i < imgdata.thumbs_list.thumbcount; i++) 0498 if (imgdata.thumbs_list.thumblist[i].toffset == libraw_internal_data.internal_data.toffset 0499 && imgdata.thumbs_list.thumblist[i].tlength == imgdata.thumbnail.tlength) 0500 { 0501 already = true; 0502 break; 0503 } 0504 if (!already) 0505 { 0506 int idx = imgdata.thumbs_list.thumbcount; 0507 imgdata.thumbs_list.thumblist[idx].toffset = libraw_internal_data.internal_data.toffset; 0508 imgdata.thumbs_list.thumblist[idx].tlength = imgdata.thumbnail.tlength; 0509 imgdata.thumbs_list.thumblist[idx].tflip = 0xffff; 0510 imgdata.thumbs_list.thumblist[idx].tformat = libraw_internal_data.unpacker_data.thumb_format; 0511 imgdata.thumbs_list.thumblist[idx].tmisc = libraw_internal_data.unpacker_data.thumb_misc; 0512 // promote if set 0513 imgdata.thumbs_list.thumblist[idx].twidth = imgdata.thumbnail.twidth; 0514 imgdata.thumbs_list.thumblist[idx].theight = imgdata.thumbnail.theight; 0515 imgdata.thumbs_list.thumbcount++; 0516 } 0517 } 0518 0519 0520 imgdata.lens.Lens[sizeof(imgdata.lens.Lens) - 1] = 0; // make sure lens is 0-terminated 0521 0522 if (callbacks.post_identify_cb) 0523 (callbacks.post_identify_cb)(this); 0524 0525 #define isRIC imgdata.sizes.raw_inset_crops[0] 0526 0527 if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) 0528 && (!strcmp(imgdata.idata.normalized_model, "S3Pro") 0529 || !strcmp(imgdata.idata.normalized_model, "S5Pro") 0530 || !strcmp(imgdata.idata.normalized_model, "S2Pro"))) 0531 { 0532 isRIC.cleft = isRIC.ctop = 0xffff; 0533 isRIC.cwidth = isRIC.cheight = 0; 0534 } 0535 // Wipe out canon incorrect in-camera crop 0536 if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Canon) 0537 && isRIC.cleft == 0 && isRIC.ctop == 0 // non symmetric! 0538 && isRIC.cwidth < (imgdata.sizes.raw_width * 4 / 5)) // less than 80% of sensor width 0539 { 0540 isRIC.cleft = isRIC.ctop = 0xffff; 0541 isRIC.cwidth = isRIC.cheight = 0; 0542 } 0543 0544 // Wipe out non-standard WB 0545 if (!imgdata.idata.dng_version && 0546 (makeIs(LIBRAW_CAMERAMAKER_Sony) && !strcmp(imgdata.idata.normalized_model, "DSC-F828")) 0547 && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PROVIDE_NONSTANDARD_WB)) 0548 { 0549 for (int i = 0; i < 4; i++) imgdata.color.cam_mul[i] = (i == 1); 0550 memset(imgdata.color.WB_Coeffs, 0, sizeof(imgdata.color.WB_Coeffs)); 0551 memset(imgdata.color.WBCT_Coeffs, 0, sizeof(imgdata.color.WBCT_Coeffs)); 0552 } 0553 0554 if (load_raw == &LibRaw::nikon_load_raw) 0555 nikon_read_curve(); 0556 0557 if (load_raw == &LibRaw::lossless_jpeg_load_raw && 0558 MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && 0559 /* Not normalized models here, it is intentional */ 0560 (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || // if we want something different for B&W cameras, 0561 !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) // it's better to compare with CamIDs 0562 { 0563 imgdata.color.black = 0; 0564 imgdata.color.maximum = 4501; 0565 memset(imgdata.color.cblack, 0, sizeof(imgdata.color.cblack)); 0566 memset(imgdata.sizes.mask, 0, sizeof(imgdata.sizes.mask)); 0567 imgdata.sizes.mask[0][3] = 1; // to skip mask re-calc 0568 libraw_internal_data.unpacker_data.load_flags |= 512; 0569 } 0570 0571 if (load_raw == &LibRaw::panasonic_load_raw) 0572 { 0573 if (libraw_internal_data.unpacker_data.pana_encoding == 6 || 0574 libraw_internal_data.unpacker_data.pana_encoding == 7) 0575 { 0576 for (int i = 0; i < 3; i++) 0577 imgdata.color.cblack[i] = 0578 libraw_internal_data.internal_data.pana_black[i]; 0579 imgdata.color.cblack[3] = imgdata.color.cblack[1]; 0580 imgdata.color.cblack[4] = imgdata.color.cblack[5] = 0; 0581 imgdata.color.black = 0; 0582 imgdata.color.maximum = 0583 MAX(imgdata.color.linear_max[0], 0584 MAX(imgdata.color.linear_max[1], imgdata.color.linear_max[2])); 0585 } 0586 0587 if (libraw_internal_data.unpacker_data.pana_encoding == 6) 0588 { 0589 int rowbytes11 = imgdata.sizes.raw_width / 11 * 16; 0590 int rowbytes14 = imgdata.sizes.raw_width / 14 * 16; 0591 INT64 ds = INT64(libraw_internal_data.unpacker_data.data_size); 0592 if (!ds) 0593 ds = libraw_internal_data.internal_data.input->size() - libraw_internal_data.unpacker_data.data_offset; 0594 if ((imgdata.sizes.raw_width % 11) == 0 && 0595 (INT64(imgdata.sizes.raw_height) * rowbytes11 == ds)) 0596 load_raw = &LibRaw::panasonicC6_load_raw; 0597 else if ((imgdata.sizes.raw_width % 14) == 0 && 0598 (INT64(imgdata.sizes.raw_height) * rowbytes14 == ds)) 0599 load_raw = &LibRaw::panasonicC6_load_raw; 0600 else 0601 imgdata.idata.raw_count = 0; // incorrect size 0602 } 0603 else if (libraw_internal_data.unpacker_data.pana_encoding == 7) 0604 { 0605 int pixperblock = 0606 libraw_internal_data.unpacker_data.pana_bpp == 14 ? 9 : 10; 0607 int rowbytes = imgdata.sizes.raw_width / pixperblock * 16; 0608 if ((imgdata.sizes.raw_width % pixperblock) == 0 && 0609 (INT64(imgdata.sizes.raw_height) * rowbytes == 0610 INT64(libraw_internal_data.unpacker_data.data_size))) 0611 load_raw = &LibRaw::panasonicC7_load_raw; 0612 else 0613 imgdata.idata.raw_count = 0; // incorrect size 0614 } 0615 } 0616 0617 #define NIKON_14BIT_SIZE(rw, rh) \ 0618 (((unsigned)(ceilf((float)(rw * 7 / 4) / 16.0)) * 16) * rh) 0619 0620 // Ugly hack, replace with proper data/line size for different 0621 // cameras/format when available 0622 if (makeIs(LIBRAW_CAMERAMAKER_Nikon) 0623 && (!strncasecmp(imgdata.idata.model, "Z", 1) || !strcasecmp(imgdata.idata.model,"D6")) 0624 && NIKON_14BIT_SIZE(imgdata.sizes.raw_width, imgdata.sizes.raw_height) == 0625 libraw_internal_data.unpacker_data.data_size) 0626 { 0627 load_raw = &LibRaw::nikon_14bit_load_raw; 0628 } 0629 #undef NIKON_14BIT_SIZE 0630 0631 // Linear max from 14-bit camera, but on 12-bit data? 0632 if (makeIs(LIBRAW_CAMERAMAKER_Sony) && 0633 imgdata.color.maximum > 0 && 0634 imgdata.color.linear_max[0] > (long)imgdata.color.maximum && 0635 imgdata.color.linear_max[0] <= (long)imgdata.color.maximum * 4) 0636 for (int c = 0; c < 4; c++) 0637 imgdata.color.linear_max[c] /= 4; 0638 0639 if (makeIs(LIBRAW_CAMERAMAKER_Canon)) 0640 { 0641 if (MN.canon.DefaultCropAbsolute.l != -1) // tag 0x00e0 SensorInfo was parsed 0642 { 0643 if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) 0644 { // tag 0x009a AspectInfo was parsed 0645 isRIC.cleft += MN.canon.DefaultCropAbsolute.l; 0646 isRIC.ctop += MN.canon.DefaultCropAbsolute.t; 0647 } 0648 else 0649 { 0650 isRIC.cleft = MN.canon.DefaultCropAbsolute.l; 0651 isRIC.ctop = MN.canon.DefaultCropAbsolute.t; 0652 isRIC.cwidth = MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; 0653 isRIC.cheight = MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; 0654 } 0655 } 0656 else 0657 { 0658 if (imgdata.sizes.raw_aspect != LIBRAW_IMAGE_ASPECT_UNKNOWN) 0659 { 0660 } 0661 else 0662 { // Canon PowerShot S2 IS 0663 } 0664 } 0665 #undef isRIC 0666 if (imgdata.color.raw_bps < 14 && !imgdata.idata.dng_version && load_raw != &LibRaw::canon_sraw_load_raw) 0667 { 0668 int xmax = (1 << imgdata.color.raw_bps) - 1; 0669 if (MN.canon.SpecularWhiteLevel > xmax) // Adjust 14-bit metadata to real bps 0670 { 0671 int div = 1 << (14 - imgdata.color.raw_bps); 0672 for (int c = 0; c < 4; c++) imgdata.color.linear_max[c] /= div; 0673 for (int c = 0; c < 4; c++) MN.canon.ChannelBlackLevel[c] /= div; 0674 MN.canon.AverageBlackLevel /= div; 0675 MN.canon.SpecularWhiteLevel /= div; 0676 MN.canon.NormalWhiteLevel /= div; 0677 } 0678 } 0679 } 0680 0681 if (makeIs(LIBRAW_CAMERAMAKER_Canon) && 0682 (load_raw == &LibRaw::canon_sraw_load_raw) && 0683 imgdata.sizes.raw_width > 0) 0684 { 0685 float ratio = 0686 float(imgdata.sizes.raw_height) / float(imgdata.sizes.raw_width); 0687 if ((ratio < 0.57 || ratio > 0.75) && 0688 MN.canon.SensorHeight > 1 && 0689 MN.canon.SensorWidth > 1) 0690 { 0691 imgdata.sizes.raw_width = MN.canon.SensorWidth; 0692 imgdata.sizes.left_margin = MN.canon.DefaultCropAbsolute.l; 0693 imgdata.sizes.iwidth = imgdata.sizes.width = 0694 MN.canon.DefaultCropAbsolute.r - MN.canon.DefaultCropAbsolute.l + 1; 0695 imgdata.sizes.raw_height = MN.canon.SensorHeight; 0696 imgdata.sizes.top_margin = MN.canon.DefaultCropAbsolute.t; 0697 imgdata.sizes.iheight = imgdata.sizes.height = 0698 MN.canon.DefaultCropAbsolute.b - MN.canon.DefaultCropAbsolute.t + 1; 0699 libraw_internal_data.unpacker_data.load_flags |= 0700 256; // reset width/height in canon_sraw_load_raw() 0701 imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; 0702 } 0703 else if (imgdata.sizes.raw_width == 4032 && 0704 imgdata.sizes.raw_height == 3402 && 0705 !strcasecmp(imgdata.idata.model, "EOS 80D")) // 80D hardcoded 0706 { 0707 imgdata.sizes.raw_width = 4536; 0708 imgdata.sizes.left_margin = 28; 0709 imgdata.sizes.iwidth = imgdata.sizes.width = 0710 imgdata.sizes.raw_width - imgdata.sizes.left_margin; 0711 imgdata.sizes.raw_height = 3024; 0712 imgdata.sizes.top_margin = 8; 0713 imgdata.sizes.iheight = imgdata.sizes.height = 0714 imgdata.sizes.raw_height - imgdata.sizes.top_margin; 0715 libraw_internal_data.unpacker_data.load_flags |= 256; 0716 imgdata.sizes.raw_pitch = 8 * imgdata.sizes.raw_width; 0717 } 0718 } 0719 0720 #ifdef USE_DNGSDK 0721 if (imgdata.idata.dng_version 0722 &&libraw_internal_data.unpacker_data.tiff_compress == 34892 0723 && libraw_internal_data.unpacker_data.tiff_bps == 8 0724 && libraw_internal_data.unpacker_data.tiff_samples == 3 0725 && load_raw == &LibRaw::lossy_dng_load_raw) 0726 { 0727 // Data should be linearized by DNG SDK 0728 C.black = 0; 0729 memset(C.cblack, 0, sizeof(C.cblack)); 0730 } 0731 #endif 0732 0733 // XTrans Compressed? 0734 if (!imgdata.idata.dng_version && 0735 makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && 0736 (load_raw == &LibRaw::unpacked_load_raw)) 0737 { 0738 if (imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 2ul) != 0739 libraw_internal_data.unpacker_data.data_size) 0740 { 0741 if ((imgdata.sizes.raw_width * (imgdata.sizes.raw_height * 7ul)) / 4 == 0742 libraw_internal_data.unpacker_data.data_size) 0743 load_raw = &LibRaw::fuji_14bit_load_raw; 0744 else 0745 parse_fuji_compressed_header(); 0746 } 0747 else if (!strcmp(imgdata.idata.normalized_model, "X-H2S") 0748 && libraw_internal_data.internal_data.input->size() 0749 < (libraw_internal_data.unpacker_data.data_size + libraw_internal_data.unpacker_data.data_offset)) 0750 { 0751 parse_fuji_compressed_header(); // try to use compressed header: X-H2S may record wrong data size 0752 } 0753 } 0754 // set raw_inset_crops[1] via raw_aspect 0755 if (imgdata.sizes.raw_aspect >= LIBRAW_IMAGE_ASPECT_MINIMAL_REAL_ASPECT_VALUE 0756 && imgdata.sizes.raw_aspect <= LIBRAW_IMAGE_ASPECT_MAXIMAL_REAL_ASPECT_VALUE 0757 /* crops[0] is valid*/ 0758 && (imgdata.sizes.raw_inset_crops[0].cleft < 0xffff) 0759 && (imgdata.sizes.raw_inset_crops[0].cleft + imgdata.sizes.raw_inset_crops[0].cwidth <= imgdata.sizes.raw_width) 0760 && (imgdata.sizes.raw_inset_crops[0].ctop < 0xffff) 0761 && (imgdata.sizes.raw_inset_crops[0].ctop + imgdata.sizes.raw_inset_crops[0].cheight <= imgdata.sizes.raw_height) 0762 && imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cheight >0 0763 /* crops[1] is not set*/ 0764 && (imgdata.sizes.raw_inset_crops[1].cleft == 0xffff) 0765 && (imgdata.sizes.raw_inset_crops[1].ctop == 0xffff) 0766 ) 0767 { 0768 float c0_ratio = float(imgdata.sizes.raw_inset_crops[0].cwidth) / float(imgdata.sizes.raw_inset_crops[0].cheight); 0769 float c1_ratio = float(imgdata.sizes.raw_aspect) / 1000.f; 0770 if (c0_ratio / c1_ratio < 0.98 || c0_ratio / c1_ratio > 1.02) // set crops[1] 0771 { 0772 if (c1_ratio > c0_ratio) // requested image is wider, cut from top/bottom 0773 { 0774 int newheight = int(imgdata.sizes.raw_inset_crops[0].cwidth / c1_ratio); 0775 int dtop = (imgdata.sizes.raw_inset_crops[0].cheight - newheight) / 2; 0776 imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dtop; 0777 imgdata.sizes.raw_inset_crops[1].cheight = newheight; 0778 imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft; 0779 imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[0].cwidth; 0780 } 0781 else 0782 { 0783 int newwidth = int(imgdata.sizes.raw_inset_crops[0].cheight * c1_ratio); 0784 int dleft = (imgdata.sizes.raw_inset_crops[0].cwidth - newwidth) / 2; 0785 imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dleft; 0786 imgdata.sizes.raw_inset_crops[1].cwidth = newwidth; 0787 imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop; 0788 imgdata.sizes.raw_inset_crops[1].cheight = imgdata.sizes.raw_inset_crops[0].cheight; 0789 } 0790 } 0791 } 0792 0793 int adjust_margins = 0; 0794 if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && (imgdata.idata.filters == 9)) 0795 { 0796 // Adjust top/left margins for X-Trans 0797 int newtm = imgdata.sizes.top_margin % 6 0798 ? (imgdata.sizes.top_margin / 6 + 1) * 6 0799 : imgdata.sizes.top_margin; 0800 int newlm = imgdata.sizes.left_margin % 6 0801 ? (imgdata.sizes.left_margin / 6 + 1) * 6 0802 : imgdata.sizes.left_margin; 0803 if (newtm != imgdata.sizes.top_margin || 0804 newlm != imgdata.sizes.left_margin) 0805 { 0806 imgdata.sizes.height -= (newtm - imgdata.sizes.top_margin); 0807 imgdata.sizes.top_margin = newtm; 0808 imgdata.sizes.width -= (newlm - imgdata.sizes.left_margin); 0809 imgdata.sizes.left_margin = newlm; 0810 for (int c1 = 0; c1 < 6; c1++) 0811 for (int c2 = 0; c2 < 6; c2++) 0812 imgdata.idata.xtrans[c1][c2] = imgdata.idata.xtrans_abs[c1][c2]; 0813 } 0814 adjust_margins = 6; 0815 } 0816 else if (!libraw_internal_data.internal_output_params.fuji_width 0817 && imgdata.idata.filters >= 1000) 0818 { 0819 if ((imgdata.sizes.top_margin % 2) || (imgdata.sizes.left_margin % 2)) 0820 { 0821 int crop[2] = { 0,0 }; 0822 unsigned filt; 0823 int c; 0824 if (imgdata.sizes.top_margin % 2) 0825 { 0826 imgdata.sizes.top_margin += 1; 0827 imgdata.sizes.height -= 1; 0828 crop[1] = 1; 0829 } 0830 if (imgdata.sizes.left_margin % 2) 0831 { 0832 imgdata.sizes.left_margin += 1; 0833 imgdata.sizes.width -= 1; 0834 crop[0] = 1; 0835 } 0836 for (filt = c = 0; c < 16; c++) 0837 filt |= FC((c >> 1) + (crop[1]), (c & 1) + (crop[0])) << c * 2; 0838 imgdata.idata.filters = filt; 0839 } 0840 adjust_margins = 2; 0841 } 0842 0843 if(adjust_margins) // adjust crop_inset margins 0844 for (int i = 0; i < 2; i++) 0845 { 0846 if (imgdata.sizes.raw_inset_crops[i].cleft && imgdata.sizes.raw_inset_crops[i].cleft < 0xffff 0847 && imgdata.sizes.raw_inset_crops[i].cwidth && imgdata.sizes.raw_inset_crops[i].cwidth < 0xffff 0848 && (imgdata.sizes.raw_inset_crops[i].cleft%adjust_margins) 0849 && (imgdata.sizes.raw_inset_crops[i].cwidth > adjust_margins)) 0850 { 0851 int newleft = ((imgdata.sizes.raw_inset_crops[i].cleft / adjust_margins) + 1) * adjust_margins; 0852 int diff = newleft - imgdata.sizes.raw_inset_crops[i].cleft; 0853 if (diff > 0) 0854 { 0855 imgdata.sizes.raw_inset_crops[i].cleft += diff; 0856 imgdata.sizes.raw_inset_crops[i].cwidth -= diff; 0857 } 0858 } 0859 if (imgdata.sizes.raw_inset_crops[i].ctop && imgdata.sizes.raw_inset_crops[i].ctop < 0xffff 0860 && imgdata.sizes.raw_inset_crops[i].cheight && imgdata.sizes.raw_inset_crops[i].cheight < 0xffff 0861 && (imgdata.sizes.raw_inset_crops[i].ctop%adjust_margins) 0862 && (imgdata.sizes.raw_inset_crops[i].cheight > adjust_margins)) 0863 { 0864 int newtop = ((imgdata.sizes.raw_inset_crops[i].ctop / adjust_margins) + 1) * adjust_margins; 0865 int diff = newtop - imgdata.sizes.raw_inset_crops[i].ctop; 0866 if (diff > 0) 0867 { 0868 imgdata.sizes.raw_inset_crops[i].ctop += diff; 0869 imgdata.sizes.raw_inset_crops[i].cheight -= diff; 0870 } 0871 } 0872 } 0873 0874 0875 #ifdef USE_DNGSDK 0876 if ( 0877 imgdata.rawparams.use_dngsdk && 0878 !(imgdata.rawparams.options & (LIBRAW_RAWOPTIONS_DNG_STAGE2 | LIBRAW_RAWOPTIONS_DNG_STAGE3 | LIBRAW_RAWOPTIONS_DNG_DISABLEWBADJUST))) 0879 #endif 0880 { 0881 // Fix DNG white balance if needed: observed only for Kalpanika X3F tools produced DNGs 0882 if (imgdata.idata.dng_version && (imgdata.idata.filters == 0) && 0883 imgdata.idata.colors > 1 && imgdata.idata.colors < 5) 0884 { 0885 float delta[4] = { 0.f, 0.f, 0.f, 0.f }; 0886 int black[4]; 0887 for (int c = 0; c < 4; c++) 0888 black[c] = imgdata.color.dng_levels.dng_black + 0889 imgdata.color.dng_levels.dng_cblack[c]; 0890 for (int c = 0; c < imgdata.idata.colors; c++) 0891 delta[c] = imgdata.color.dng_levels.dng_whitelevel[c] - black[c]; 0892 float mindelta = delta[0], maxdelta = delta[0]; 0893 for (int c = 1; c < imgdata.idata.colors; c++) 0894 { 0895 if (mindelta > delta[c]) 0896 mindelta = delta[c]; 0897 if (maxdelta < delta[c]) 0898 maxdelta = delta[c]; 0899 } 0900 if (mindelta > 1 && maxdelta < (mindelta * 20)) // safety 0901 { 0902 for (int c = 0; c < imgdata.idata.colors; c++) 0903 { 0904 imgdata.color.cam_mul[c] /= (delta[c] / maxdelta); 0905 imgdata.color.pre_mul[c] /= (delta[c] / maxdelta); 0906 } 0907 imgdata.color.maximum = imgdata.color.cblack[0] + maxdelta; 0908 } 0909 } 0910 } 0911 0912 if (imgdata.idata.dng_version && 0913 makeIs(LIBRAW_CAMERAMAKER_Panasonic) 0914 && !strcasecmp(imgdata.idata.normalized_model, "DMC-LX100")) 0915 imgdata.sizes.width = 4288; 0916 0917 if (imgdata.idata.dng_version 0918 && makeIs(LIBRAW_CAMERAMAKER_Leica) 0919 && !strcasecmp(imgdata.idata.normalized_model, "SL2")) 0920 imgdata.sizes.height -= 16; 0921 0922 if (makeIs(LIBRAW_CAMERAMAKER_Sony) && 0923 imgdata.idata.dng_version) 0924 { 0925 if (S.raw_width == 3984) 0926 S.width = 3925; 0927 else if (S.raw_width == 4288) 0928 S.width = S.raw_width - 32; 0929 else if (S.raw_width == 4928 && S.height < 3280) 0930 S.width = S.raw_width - 8; 0931 else if (S.raw_width == 5504) 0932 S.width = S.raw_width - (S.height > 3664 ? 8 : 32); 0933 } 0934 0935 if (makeIs(LIBRAW_CAMERAMAKER_Sony) && 0936 !imgdata.idata.dng_version) 0937 { 0938 if(load_raw ==&LibRaw::sony_arq_load_raw) 0939 { 0940 if(S.raw_width > 12000) // A7RM4 16x, both APS-C and APS 0941 S.width = S.raw_width - 64; 0942 else // A7RM3/M4 4x merge 0943 S.width = S.raw_width - 32; 0944 } 0945 0946 if (((!strncasecmp(imgdata.idata.model, "ILCE-7RM", 8) || 0947 !strcasecmp(imgdata.idata.model, "ILCA-99M2")) && 0948 (S.raw_width == 5216 || S.raw_width == 6304)) // A7RM2/M3/A99M2 in APS mode; A7RM4 in APS-C 0949 || 0950 (!strcasecmp(imgdata.idata.model, "ILCE-7R") && S.raw_width >= 4580 && 0951 S.raw_width < 5020) // A7R in crop mode, no samples, so size est. 0952 || (!strcasecmp(imgdata.idata.model, "ILCE-7") && 0953 S.raw_width == 3968) // A7 in crop mode 0954 || 0955 ((!strncasecmp(imgdata.idata.model, "ILCE-7M", 7) || 0956 !strcasecmp(imgdata.idata.model, "ILCE-9") || 0957 #if 0 0958 !strcasecmp(imgdata.idata.model, 0959 "SLT-A99V")) // Does SLT-A99 also have APS-C mode?? 0960 #endif 0961 (mnCamID == SonyID_SLT_A99)) // 2 reasons: some cameras are SLT-A99, no 'V'; some are Hasselblad HV 0962 && S.raw_width > 3750 && 0963 S.raw_width < 4120) // A7M2, A7M3, AA9, most likely APS-C raw_width 0964 // is 3968 (same w/ A7), but no samples, so guess 0965 || (!strncasecmp(imgdata.idata.model, "ILCE-7S", 7) && 0966 S.raw_width == 2816) // A7S2=> exact, hope it works for A7S-I too 0967 ) 0968 S.width = S.raw_width - 32; 0969 } 0970 0971 0972 // FIXME: it is possible that DNG contains 4x main frames + some previews; in this case imgdata.idata.raw_count will be greater than 4 0973 if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && 0974 /*!strcasecmp(imgdata.idata.model,"K-3 II") &&*/ 0975 imgdata.idata.raw_count == 4 && 0976 (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_PENTAX_PS_ALLFRAMES)) 0977 { 0978 imgdata.idata.raw_count = 1; 0979 imgdata.idata.filters = 0; 0980 imgdata.idata.colors = 4; 0981 imgdata.sizes.top_margin+=2; 0982 imgdata.sizes.left_margin+=2; 0983 imgdata.sizes.width-=4; 0984 imgdata.sizes.height-=4; 0985 IO.mix_green = 1; 0986 pentax_component_load_raw = load_raw; 0987 load_raw = &LibRaw::pentax_4shot_load_raw; 0988 } 0989 0990 if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Leaf) && 0991 !strcmp(imgdata.idata.model, "Credo 50")) 0992 { 0993 imgdata.color.pre_mul[0] = 1.f / 0.3984f; 0994 imgdata.color.pre_mul[2] = 1.f / 0.7666f; 0995 imgdata.color.pre_mul[1] = imgdata.color.pre_mul[3] = 1.0; 0996 } 0997 0998 if (!imgdata.idata.dng_version && makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && 0999 (!strncmp(imgdata.idata.model, "S20Pro", 6) || 1000 !strncmp(imgdata.idata.model, "F700", 4))) 1001 { 1002 imgdata.sizes.raw_width /= 2; 1003 load_raw = &LibRaw::unpacked_load_raw_fuji_f700s20; 1004 } 1005 1006 if (load_raw == &LibRaw::packed_load_raw && 1007 makeIs(LIBRAW_CAMERAMAKER_Nikon) && 1008 !libraw_internal_data.unpacker_data.load_flags && 1009 (!strncasecmp(imgdata.idata.model, "D810", 4) || 1010 !strcasecmp(imgdata.idata.model, "D4S")) && 1011 libraw_internal_data.unpacker_data.data_size * 2u == 1012 imgdata.sizes.raw_height * imgdata.sizes.raw_width * 3u) 1013 { 1014 libraw_internal_data.unpacker_data.load_flags = 80; 1015 } 1016 // Adjust BL for Sony A900/A850 1017 if (load_raw == &LibRaw::packed_load_raw && 1018 makeIs(LIBRAW_CAMERAMAKER_Sony)) // 12 bit sony, but metadata may be for 14-bit range 1019 { 1020 if (C.maximum > 4095) 1021 C.maximum = 4095; 1022 if (C.black > 256 || C.cblack[0] > 256) 1023 { 1024 C.black /= 4; 1025 for (int c = 0; c < 4; c++) 1026 C.cblack[c] /= 4; 1027 for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) 1028 C.cblack[6 + c] /= 4; 1029 } 1030 } 1031 1032 if (load_raw == &LibRaw::nikon_yuv_load_raw) // Is it Nikon sRAW? 1033 { 1034 load_raw = &LibRaw::nikon_load_sraw; 1035 C.black = 0; 1036 memset(C.cblack, 0, sizeof(C.cblack)); 1037 imgdata.idata.filters = 0; 1038 libraw_internal_data.unpacker_data.tiff_samples = 3; 1039 imgdata.idata.colors = 3; 1040 double beta_1 = -5.79342238397656E-02; 1041 double beta_2 = 3.28163551282665; 1042 double beta_3 = -8.43136004842678; 1043 double beta_4 = 1.03533181861023E+01; 1044 for (int i = 0; i <= 3072; i++) 1045 { 1046 double x = (double)i / 3072.; 1047 double y = (1. - exp(-beta_1 * x - beta_2 * x * x - beta_3 * x * x * x - 1048 beta_4 * x * x * x * x)); 1049 if (y < 0.) 1050 y = 0.; 1051 imgdata.color.curve[i] = (y * 16383.); 1052 } 1053 for (int i = 0; i < 3; i++) 1054 for (int j = 0; j < 4; j++) 1055 imgdata.color.rgb_cam[i][j] = float(i == j); 1056 } 1057 // Adjust BL for Nikon 12bit 1058 if ((load_raw == &LibRaw::nikon_load_raw || 1059 load_raw == &LibRaw::packed_load_raw || 1060 load_raw == &LibRaw::nikon_load_padded_packed_raw) && 1061 makeIs(LIBRAW_CAMERAMAKER_Nikon) && 1062 strncmp(imgdata.idata.model, "COOLPIX", 7) && 1063 libraw_internal_data.unpacker_data.tiff_bps == 12) 1064 { 1065 C.maximum = 4095; 1066 C.black /= 4; 1067 for (int c = 0; c < 4; c++) 1068 C.cblack[c] /= 4; 1069 for (unsigned c = 0; c < C.cblack[4] * C.cblack[5]; c++) 1070 C.cblack[6 + c] /= 4; 1071 } 1072 1073 // Adjust wb_already_applied 1074 if (load_raw == &LibRaw::nikon_load_sraw) 1075 imgdata.color.as_shot_wb_applied = 1076 LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON_SRAW; 1077 else if (makeIs(LIBRAW_CAMERAMAKER_Canon) && 1078 MN.canon.multishot[0] >= 8 && 1079 MN.canon.multishot[1] > 0) 1080 imgdata.color.as_shot_wb_applied = 1081 LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_CANON; 1082 else if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && 1083 MN.nikon.ExposureMode == 1) 1084 imgdata.color.as_shot_wb_applied = 1085 LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_NIKON; 1086 else if (makeIs(LIBRAW_CAMERAMAKER_Pentax) && 1087 ((MN.pentax.MultiExposure & 0x01) == 1)) 1088 imgdata.color.as_shot_wb_applied = 1089 LIBRAW_ASWB_APPLIED | LIBRAW_ASWB_PENTAX; 1090 else 1091 imgdata.color.as_shot_wb_applied = 0; 1092 1093 // Adjust Highlight Linearity limit 1094 if (C.linear_max[0] < 0) 1095 { 1096 if (imgdata.idata.dng_version) 1097 { 1098 for (int c = 0; c < 4; c++) 1099 C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c + 6]; 1100 } 1101 else 1102 { 1103 for (int c = 0; c < 4; c++) 1104 C.linear_max[c] = -1 * C.linear_max[c] + imgdata.color.cblack[c]; 1105 } 1106 } 1107 1108 if (makeIs(LIBRAW_CAMERAMAKER_Nikon) && 1109 (!C.linear_max[0]) && (C.maximum > 1024) && (load_raw != &LibRaw::nikon_load_sraw)) 1110 { 1111 C.linear_max[0] = C.linear_max[1] = C.linear_max[2] = C.linear_max[3] = 1112 (long)((float)(C.maximum) / 1.07f); 1113 } 1114 1115 // Correct WB for Samsung GX20 1116 if ( 1117 #if 0 1118 /* GX20 should be corrected, but K20 is not */ 1119 makeIs(LIBRAW_CAMERAMAKER_Pentax) && 1120 !strcasecmp(imgdata.idata.normalized_model, "K20D") 1121 #endif 1122 #if 0 1123 !strcasecmp(imgdata.idata.make, "Samsung") && 1124 !strcasecmp(imgdata.idata.model, "GX20") 1125 #endif 1126 makeIs(LIBRAW_CAMERAMAKER_Pentax) && 1127 (mnCamID == PentaxID_GX20) // Samsung rebranding 1128 ) 1129 { 1130 for (int cnt = LIBRAW_WBI_Unknown; cnt <= LIBRAW_WBI_StudioTungsten; cnt++) { 1131 if (C.WB_Coeffs[cnt][1]) { 1132 C.WB_Coeffs[cnt][0] = (int)((float)(C.WB_Coeffs[cnt][0]) * 1.0503f); 1133 C.WB_Coeffs[cnt][2] = (int)((float)(C.WB_Coeffs[cnt][2]) * 2.2867f); 1134 } 1135 } 1136 for (int cnt = 0; cnt < 64; cnt++) { 1137 if (C.WBCT_Coeffs[cnt][0] > 0.0f) { 1138 C.WBCT_Coeffs[cnt][1] *= 1.0503f; 1139 C.WBCT_Coeffs[cnt][3] *= 2.2867f; 1140 } 1141 } 1142 for(int cnt = 0; cnt < 4; cnt++) 1143 imgdata.color.pre_mul[cnt] = 1144 C.WB_Coeffs[LIBRAW_WBI_Daylight][cnt]; 1145 } 1146 1147 // Adjust BL for Panasonic 1148 if (load_raw == &LibRaw::panasonic_load_raw && 1149 makeIs(LIBRAW_CAMERAMAKER_Panasonic) && 1150 ID.pana_black[0] && ID.pana_black[1] && ID.pana_black[2]) 1151 { 1152 if (libraw_internal_data.unpacker_data.pana_encoding == 5) 1153 libraw_internal_data.internal_output_params.zero_is_bad = 0; 1154 C.black = 0; 1155 int add = libraw_internal_data.unpacker_data.pana_encoding == 4 ? 15 : 0; 1156 C.cblack[0] = ID.pana_black[0] + add; 1157 C.cblack[1] = C.cblack[3] = ID.pana_black[1] + add; 1158 C.cblack[2] = ID.pana_black[2] + add; 1159 unsigned i = C.cblack[3]; 1160 for (int c = 0; c < 3; c++) 1161 if (i > C.cblack[c]) 1162 i = C.cblack[c]; 1163 for (int c = 0; c < 4; c++) 1164 C.cblack[c] -= i; 1165 C.black = i; 1166 } 1167 1168 // Adjust sizes for X3F processing 1169 #ifdef USE_X3FTOOLS 1170 if (load_raw == &LibRaw::x3f_load_raw) 1171 { 1172 for (int i = 0; i < foveon_count; i++) 1173 if (!strcasecmp(imgdata.idata.make, foveon_data[i].make) && 1174 !strcasecmp(imgdata.idata.model, foveon_data[i].model) && 1175 imgdata.sizes.raw_width == foveon_data[i].raw_width && 1176 imgdata.sizes.raw_height == foveon_data[i].raw_height) 1177 { 1178 imgdata.sizes.top_margin = foveon_data[i].top_margin; 1179 imgdata.sizes.left_margin = foveon_data[i].left_margin; 1180 imgdata.sizes.width = imgdata.sizes.iwidth = foveon_data[i].width; 1181 imgdata.sizes.height = imgdata.sizes.iheight = foveon_data[i].height; 1182 C.maximum = foveon_data[i].white; 1183 break; 1184 } 1185 } 1186 #endif 1187 #if 0 1188 size_t bytes = ID.input->size()-libraw_internal_data.unpacker_data.data_offset; 1189 float bpp = float(bytes)/float(S.raw_width)/float(S.raw_height); 1190 float bpp2 = float(bytes)/float(S.width)/float(S.height); 1191 if(!strcasecmp(imgdata.idata.make,"Hasselblad") && bpp == 6.0f) 1192 { 1193 load_raw = &LibRaw::hasselblad_full_load_raw; 1194 S.width = S.raw_width; 1195 S.height = S.raw_height; 1196 P1.filters = 0; 1197 P1.colors=3; 1198 P1.raw_count=1; 1199 C.maximum=0xffff; 1200 } 1201 #endif 1202 if (C.profile_length) 1203 { 1204 if (C.profile) 1205 free(C.profile); 1206 INT64 profile_sz = MIN(INT64(C.profile_length), ID.input->size() - ID.profile_offset); 1207 if (profile_sz > 0LL && profile_sz < LIBRAW_MAX_PROFILE_SIZE_MB * 1024LL * 1024LL) 1208 { 1209 C.profile = malloc(size_t(profile_sz)); 1210 ID.input->seek(ID.profile_offset, SEEK_SET); 1211 ID.input->read(C.profile, size_t(profile_sz), 1); 1212 } 1213 else 1214 C.profile = NULL; 1215 } 1216 1217 SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY); 1218 } 1219 catch (const std::bad_alloc&) 1220 { 1221 EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); 1222 } 1223 catch (const LibRaw_exceptions& err) 1224 { 1225 EXCEPTION_HANDLER(err); 1226 } 1227 catch (const std::exception& ) 1228 { 1229 EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); 1230 } 1231 1232 final:; 1233 1234 if (P1.raw_count < 1) 1235 return LIBRAW_FILE_UNSUPPORTED; 1236 1237 write_fun = &LibRaw::write_ppm_tiff; 1238 1239 if (load_raw == &LibRaw::kodak_ycbcr_load_raw) 1240 { 1241 S.height += S.height & 1; 1242 S.width += S.width & 1; 1243 } 1244 1245 IO.shrink = 1246 P1.filters && 1247 (O.half_size || ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1))); 1248 if (IO.shrink && P1.filters >= 1000) 1249 { 1250 S.width &= 65534; 1251 S.height &= 65534; 1252 } 1253 1254 S.iheight = (S.height + IO.shrink) >> IO.shrink; 1255 S.iwidth = (S.width + IO.shrink) >> IO.shrink; 1256 1257 // Save color,sizes and internal data into raw_image fields 1258 memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); 1259 memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); 1260 memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); 1261 memmove(&imgdata.rawdata.ioparams, 1262 &libraw_internal_data.internal_output_params, 1263 sizeof(libraw_internal_data.internal_output_params)); 1264 1265 SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST); 1266 1267 return LIBRAW_SUCCESS; 1268 }