File indexing completed on 2025-01-05 03:57:08
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder, 0005 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net. 0006 LibRaw do not use RESTRICTED code from dcraw.c 0007 0008 LibRaw is free software; you can redistribute it and/or modify 0009 it under the terms of the one of two licenses as you choose: 0010 0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0012 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0013 0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0015 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0016 0017 */ 0018 0019 #include "../../internal/dcraw_defs.h" 0020 0021 int LibRaw::fcol(int row, int col) 0022 { 0023 static const char filter[16][16] = { 0024 {2, 1, 1, 3, 2, 3, 2, 0, 3, 2, 3, 0, 1, 2, 1, 0}, 0025 {0, 3, 0, 2, 0, 1, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2}, 0026 {2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 1, 2, 0, 0, 3}, 0027 {0, 1, 0, 1, 0, 2, 0, 2, 2, 0, 3, 0, 1, 3, 2, 1}, 0028 {3, 1, 1, 2, 0, 1, 0, 2, 1, 3, 1, 3, 0, 1, 3, 0}, 0029 {2, 0, 0, 3, 3, 2, 3, 1, 2, 0, 2, 0, 3, 2, 2, 1}, 0030 {2, 3, 3, 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 0, 0, 1}, 0031 {1, 0, 0, 2, 3, 0, 0, 3, 0, 3, 0, 3, 2, 1, 2, 3}, 0032 {2, 3, 3, 1, 1, 2, 1, 0, 3, 2, 3, 0, 2, 3, 1, 3}, 0033 {1, 0, 2, 0, 3, 0, 3, 2, 0, 1, 1, 2, 0, 1, 0, 2}, 0034 {0, 1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 0, 2, 1, 3, 2}, 0035 {2, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 2, 3, 0, 1, 0}, 0036 {1, 3, 1, 2, 3, 2, 3, 2, 0, 2, 0, 1, 1, 0, 3, 0}, 0037 {0, 2, 0, 3, 1, 0, 0, 1, 1, 3, 3, 2, 3, 2, 2, 1}, 0038 {2, 1, 3, 2, 3, 1, 2, 1, 0, 3, 0, 2, 0, 2, 0, 2}, 0039 {0, 3, 1, 0, 0, 2, 0, 3, 2, 1, 3, 1, 1, 3, 1, 3}}; 0040 0041 if (filters == 1) 0042 return filter[(row + top_margin) & 15][(col + left_margin) & 15]; 0043 if (filters == 9) 0044 return xtrans[(row + 6) % 6][(col + 6) % 6]; 0045 return FC(row, col); 0046 } 0047 0048 size_t LibRaw::strnlen(const char *s, size_t n) 0049 { 0050 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) 0051 const char *p = (const char *)memchr(s, 0, n); 0052 return (p ? p - s : n); 0053 #else 0054 return ::strnlen(s, n); 0055 #endif 0056 } 0057 0058 void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle, 0059 size_t needlelen) 0060 { 0061 #if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) 0062 char *c; 0063 for (c = haystack; c <= haystack + haystacklen - needlelen; c++) 0064 if (!memcmp(c, needle, needlelen)) 0065 return c; 0066 return 0; 0067 #else 0068 return ::memmem(haystack, haystacklen, needle, needlelen); 0069 #endif 0070 } 0071 0072 char *LibRaw::strcasestr(char *haystack, const char *needle) 0073 { 0074 char *c; 0075 for (c = haystack; *c; c++) 0076 if (!strncasecmp(c, needle, strlen(needle))) 0077 return c; 0078 return 0; 0079 } 0080 0081 void LibRaw::initdata() 0082 { 0083 tiff_flip = flip = filters = UINT_MAX; /* unknown */ 0084 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; 0085 maximum = height = width = top_margin = left_margin = 0; 0086 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; 0087 iso_speed = shutter = aperture = focal_len = 0; 0088 unique_id = 0ULL; 0089 tiff_nifds = 0; 0090 memset(tiff_ifd, 0, sizeof tiff_ifd); 0091 for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++) 0092 { 0093 tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant = 0094 0xffff; 0095 for (int c = 0; c < 4; c++) 0096 tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f; 0097 } 0098 for (int i = 0; i < 0x10000; i++) 0099 curve[i] = i; 0100 memset(gpsdata, 0, sizeof gpsdata); 0101 memset(cblack, 0, sizeof cblack); 0102 memset(white, 0, sizeof white); 0103 memset(mask, 0, sizeof mask); 0104 thumb_offset = thumb_length = thumb_width = thumb_height = 0; 0105 load_raw = 0; 0106 thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG 0107 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; 0108 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; 0109 timestamp = shot_order = tiff_samples = black = is_foveon = 0; 0110 mix_green = profile_length = data_error = zero_is_bad = 0; 0111 pixel_aspect = is_raw = raw_color = 1; 0112 tile_width = tile_length = 0; 0113 metadata_blocks = 0; 0114 is_NikonTransfer = 0; 0115 is_Olympus = 0; 0116 OlympusDNG_SubDirOffsetValid = 0; 0117 is_Sony = 0; 0118 is_pana_raw = 0; 0119 maker_index = LIBRAW_CAMERAMAKER_Unknown; 0120 FujiCropMode = 0; 0121 is_PentaxRicohMakernotes = 0; 0122 normalized_model[0] = 0; 0123 normalized_make[0] = 0; 0124 CM_found = 0; 0125 } 0126 0127 void LibRaw::aRGB_coeff(double aRGB_cam[3][3]) 0128 { 0129 static const double rgb_aRGB[3][3] = { 0130 {1.39828313770000, -0.3982830047, 9.64980900741708E-8}, 0131 {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8}, 0132 {2.17237099975343E-8, -0.0429383201, 1.04293828050000}}; 0133 0134 double cmatrix_tmp[3][3] = { 0135 {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; 0136 int i, j, k; 0137 0138 for (i = 0; i < 3; i++) 0139 for (j = 0; j < 3; j++) 0140 { 0141 for (k = 0; k < 3; k++) 0142 cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j]; 0143 cmatrix[i][j] = (float)cmatrix_tmp[i][j]; 0144 } 0145 } 0146 0147 void LibRaw::romm_coeff(float romm_cam[3][3]) 0148 { 0149 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ 0150 {{2.034193f, -0.727420f, -0.306766f}, 0151 {-0.228811f, 1.231729f, -0.002922f}, 0152 {-0.008565f, -0.153273f, 1.161839f}}; 0153 int i, j, k; 0154 0155 for (i = 0; i < 3; i++) 0156 for (j = 0; j < 3; j++) 0157 for (cmatrix[i][j] = k = 0; k < 3; k++) 0158 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; 0159 } 0160 0161 void LibRaw::remove_zeroes() 0162 { 0163 unsigned row, col, tot, n; 0164 int r, c; 0165 0166 RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 0, 2); 0167 0168 for (row = 0; row < height; row++) 0169 for (col = 0; col < width; col++) 0170 if (BAYER(row, col) == 0) 0171 { 0172 tot = n = 0; 0173 for (r = (int)row - 2; r <= (int)row + 2; r++) 0174 for (c = (int)col - 2; c <= (int)col + 2; c++) 0175 if (r >= 0 && r < height && c >= 0 && c < width && 0176 FC(r, c) == FC(row, col) && BAYER(r, c)) 0177 tot += (n++, BAYER(r, c)); 0178 if (n) 0179 BAYER(row, col) = tot / n; 0180 } 0181 RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2); 0182 } 0183 void LibRaw::crop_masked_pixels() 0184 { 0185 int row, col; 0186 unsigned c, m, zero, val; 0187 #define mblack imgdata.color.black_stat 0188 0189 if (mask[0][3] > 0) 0190 goto mask_set; 0191 if (load_raw == &LibRaw::canon_load_raw || 0192 load_raw == &LibRaw::lossless_jpeg_load_raw || 0193 load_raw == &LibRaw::crxLoadRaw) 0194 { 0195 mask[0][1] = mask[1][1] += 2; 0196 mask[0][3] -= 2; 0197 goto sides; 0198 } 0199 if (load_raw == &LibRaw::canon_600_load_raw || 0200 load_raw == &LibRaw::sony_load_raw || 0201 (load_raw == &LibRaw::eight_bit_load_raw && strncmp(model, "DC2", 3)) || 0202 load_raw == &LibRaw::kodak_262_load_raw || 0203 (load_raw == &LibRaw::packed_load_raw && (load_flags & 32))) 0204 { 0205 sides: 0206 mask[0][0] = mask[1][0] = top_margin; 0207 mask[0][2] = mask[1][2] = top_margin + height; 0208 mask[0][3] += left_margin; 0209 mask[1][1] += left_margin + width; 0210 mask[1][3] += raw_width; 0211 } 0212 if (load_raw == &LibRaw::nokia_load_raw) 0213 { 0214 mask[0][2] = top_margin; 0215 mask[0][3] = width; 0216 } 0217 if (load_raw == &LibRaw::broadcom_load_raw) 0218 { 0219 mask[0][2] = top_margin; 0220 mask[0][3] = width; 0221 } 0222 mask_set: 0223 memset(mblack, 0, sizeof mblack); 0224 for (zero = m = 0; m < 8; m++) 0225 for (row = MAX(mask[m][0], 0); row < MIN(mask[m][2], raw_height); row++) 0226 for (col = MAX(mask[m][1], 0); col < MIN(mask[m][3], raw_width); col++) 0227 { 0228 /* No need to subtract margins because full area and active area filters are the same */ 0229 c = FC(row, col); 0230 mblack[c] += val = raw_image[(row)*raw_pitch / 2 + (col)]; 0231 mblack[4 + c]++; 0232 zero += !val; 0233 } 0234 if (load_raw == &LibRaw::canon_600_load_raw && width < raw_width) 0235 { 0236 black = (mblack[0] + mblack[1] + mblack[2] + mblack[3]) / 0237 MAX(1, (mblack[4] + mblack[5] + mblack[6] + mblack[7])) - 0238 4; 0239 } 0240 else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) 0241 { 0242 FORC4 cblack[c] = mblack[c] / MAX(1, mblack[4 + c]); 0243 black = cblack[4] = cblack[5] = cblack[6] = 0; 0244 } 0245 } 0246 #undef mblack 0247 0248 void LibRaw::pseudoinverse(double (*in)[3], double (*out)[3], int size) 0249 { 0250 double work[3][6], num; 0251 int i, j, k; 0252 0253 for (i = 0; i < 3; i++) 0254 { 0255 for (j = 0; j < 6; j++) 0256 work[i][j] = j == i + 3; 0257 for (j = 0; j < 3; j++) 0258 for (k = 0; k < size && k < 4; k++) 0259 work[i][j] += in[k][i] * in[k][j]; 0260 } 0261 for (i = 0; i < 3; i++) 0262 { 0263 num = work[i][i]; 0264 for (j = 0; j < 6; j++) 0265 if (fabs(num) > 0.00001f) 0266 work[i][j] /= num; 0267 for (k = 0; k < 3; k++) 0268 { 0269 if (k == i) 0270 continue; 0271 num = work[k][i]; 0272 for (j = 0; j < 6; j++) 0273 work[k][j] -= work[i][j] * num; 0274 } 0275 } 0276 for (i = 0; i < size && i < 4; i++) 0277 for (j = 0; j < 3; j++) 0278 for (out[i][j] = k = 0; k < 3; k++) 0279 out[i][j] += work[j][k + 3] * in[i][k]; 0280 } 0281 0282 void LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3]) 0283 { 0284 double cam_rgb[4][3], inverse[4][3], num; 0285 int i, j, k; 0286 0287 for (i = 0; i < colors && i < 4; i++) /* Multiply out XYZ colorspace */ 0288 for (j = 0; j < 3; j++) 0289 for (cam_rgb[i][j] = k = 0; k < 3; k++) 0290 cam_rgb[i][j] += cam_xyz[i][k] * LibRaw_constants::xyz_rgb[k][j]; 0291 0292 for (i = 0; i < colors && i < 4; i++) 0293 { /* Normalize cam_rgb so that */ 0294 for (num = j = 0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ 0295 num += cam_rgb[i][j]; 0296 if (num > 0.00001) 0297 { 0298 for (j = 0; j < 3; j++) 0299 cam_rgb[i][j] /= num; 0300 pre_mul[i] = 1 / num; 0301 } 0302 else 0303 { 0304 for (j = 0; j < 3; j++) 0305 cam_rgb[i][j] = 0.0; 0306 pre_mul[i] = 1.0; 0307 } 0308 } 0309 pseudoinverse(cam_rgb, inverse, colors); 0310 for (i = 0; i < 3; i++) 0311 for (j = 0; j < colors && j < 4; j++) 0312 _rgb_cam[i][j] = inverse[j][i]; 0313 } 0314 0315 void LibRaw::tiff_get(unsigned base, unsigned *tag, unsigned *type, 0316 unsigned *len, unsigned *save) 0317 { 0318 #ifdef LIBRAW_IOSPACE_CHECK 0319 INT64 pos = ftell(ifp); 0320 INT64 fsize = ifp->size(); 0321 if (fsize < 12 || (fsize - pos) < 12) 0322 throw LIBRAW_EXCEPTION_IO_EOF; 0323 #endif 0324 *tag = get2(); 0325 *type = get2(); 0326 *len = get4(); 0327 *save = ftell(ifp) + 4; 0328 if (*len * tagtype_dataunit_bytes[(*type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *type : 0] > 4) 0329 fseek(ifp, get4() + base, SEEK_SET); 0330 }