1 /* -*- C++ -*-
2 * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
3 *
4 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6 LibRaw do not use RESTRICTED code from dcraw.c
7
8 LibRaw is free software; you can redistribute it and/or modify
9 it under the terms of the one of two licenses as you choose:
10
11 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12 (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15 (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17 */
18
19 #include "../../internal/dcraw_defs.h"
20
fcol(int row,int col)21 int LibRaw::fcol(int row, int col)
22 {
23 static const char filter[16][16] = {
24 {2, 1, 1, 3, 2, 3, 2, 0, 3, 2, 3, 0, 1, 2, 1, 0},
25 {0, 3, 0, 2, 0, 1, 3, 1, 0, 1, 1, 2, 0, 3, 3, 2},
26 {2, 3, 3, 2, 3, 1, 1, 3, 3, 1, 2, 1, 2, 0, 0, 3},
27 {0, 1, 0, 1, 0, 2, 0, 2, 2, 0, 3, 0, 1, 3, 2, 1},
28 {3, 1, 1, 2, 0, 1, 0, 2, 1, 3, 1, 3, 0, 1, 3, 0},
29 {2, 0, 0, 3, 3, 2, 3, 1, 2, 0, 2, 0, 3, 2, 2, 1},
30 {2, 3, 3, 1, 2, 1, 2, 1, 2, 1, 1, 2, 3, 0, 0, 1},
31 {1, 0, 0, 2, 3, 0, 0, 3, 0, 3, 0, 3, 2, 1, 2, 3},
32 {2, 3, 3, 1, 1, 2, 1, 0, 3, 2, 3, 0, 2, 3, 1, 3},
33 {1, 0, 2, 0, 3, 0, 3, 2, 0, 1, 1, 2, 0, 1, 0, 2},
34 {0, 1, 1, 3, 3, 2, 2, 1, 1, 3, 3, 0, 2, 1, 3, 2},
35 {2, 3, 2, 0, 0, 1, 3, 0, 2, 0, 1, 2, 3, 0, 1, 0},
36 {1, 3, 1, 2, 3, 2, 3, 2, 0, 2, 0, 1, 1, 0, 3, 0},
37 {0, 2, 0, 3, 1, 0, 0, 1, 1, 3, 3, 2, 3, 2, 2, 1},
38 {2, 1, 3, 2, 3, 1, 2, 1, 0, 3, 0, 2, 0, 2, 0, 2},
39 {0, 3, 1, 0, 0, 2, 0, 3, 2, 1, 3, 1, 1, 3, 1, 3}};
40
41 if (filters == 1)
42 return filter[(row + top_margin) & 15][(col + left_margin) & 15];
43 if (filters == 9)
44 return xtrans[(row + 6) % 6][(col + 6) % 6];
45 return FC(row, col);
46 }
47
strnlen(const char * s,size_t n)48 size_t LibRaw::strnlen(const char *s, size_t n)
49 {
50 #if !defined(__FreeBSD__) && !defined(__OpenBSD__)
51 const char *p = (const char *)memchr(s, 0, n);
52 return (p ? p - s : n);
53 #else
54 return ::strnlen(s, n);
55 #endif
56 }
57
memmem(char * haystack,size_t haystacklen,char * needle,size_t needlelen)58 void *LibRaw::memmem(char *haystack, size_t haystacklen, char *needle,
59 size_t needlelen)
60 {
61 #if !defined(__GLIBC__) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
62 char *c;
63 for (c = haystack; c <= haystack + haystacklen - needlelen; c++)
64 if (!memcmp(c, needle, needlelen))
65 return c;
66 return 0;
67 #else
68 return ::memmem(haystack, haystacklen, needle, needlelen);
69 #endif
70 }
71
strcasestr(char * haystack,const char * needle)72 char *LibRaw::strcasestr(char *haystack, const char *needle)
73 {
74 char *c;
75 for (c = haystack; *c; c++)
76 if (!strncasecmp(c, needle, strlen(needle)))
77 return c;
78 return 0;
79 }
80
initdata()81 void LibRaw::initdata()
82 {
83 tiff_flip = flip = filters = UINT_MAX; /* unknown */
84 raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
85 maximum = height = width = top_margin = left_margin = 0;
86 cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
87 iso_speed = shutter = aperture = focal_len = 0;
88 unique_id = 0ULL;
89 tiff_nifds = 0;
90 memset(tiff_ifd, 0, sizeof tiff_ifd);
91 for (int i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
92 {
93 tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant =
94 0xffff;
95 for (int c = 0; c < 4; c++)
96 tiff_ifd[i].dng_levels.analogbalance[c] = 1.0f;
97 }
98 for (int i = 0; i < 0x10000; i++)
99 curve[i] = i;
100 memset(gpsdata, 0, sizeof gpsdata);
101 memset(cblack, 0, sizeof cblack);
102 memset(white, 0, sizeof white);
103 memset(mask, 0, sizeof mask);
104 thumb_offset = thumb_length = thumb_width = thumb_height = 0;
105 load_raw = thumb_load_raw = 0;
106 write_thumb = &LibRaw::jpeg_thumb;
107 data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
108 kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
109 timestamp = shot_order = tiff_samples = black = is_foveon = 0;
110 mix_green = profile_length = data_error = zero_is_bad = 0;
111 pixel_aspect = is_raw = raw_color = 1;
112 tile_width = tile_length = 0;
113 metadata_blocks = 0;
114 is_NikonTransfer = 0;
115 is_Olympus = 0;
116 OlympusDNG_SubDirOffsetValid = 0;
117 is_Sony = 0;
118 is_pana_raw = 0;
119 maker_index = LIBRAW_CAMERAMAKER_Unknown;
120 FujiCropMode = 0;
121 is_PentaxRicohMakernotes = 0;
122 normalized_model[0] = 0;
123 normalized_make[0] = 0;
124 CM_found = 0;
125 }
126
aRGB_coeff(double aRGB_cam[3][3])127 void LibRaw::aRGB_coeff(double aRGB_cam[3][3])
128 {
129 static const double rgb_aRGB[3][3] = {
130 {1.39828313770000, -0.3982830047, 9.64980900741708E-8},
131 {6.09219200572997E-8, 0.9999999809, 1.33230799934103E-8},
132 {2.17237099975343E-8, -0.0429383201, 1.04293828050000}};
133
134 double cmatrix_tmp[3][3] = {
135 {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
136 int i, j, k;
137
138 for (i = 0; i < 3; i++)
139 for (j = 0; j < 3; j++)
140 {
141 for (k = 0; k < 3; k++)
142 cmatrix_tmp[i][j] += rgb_aRGB[i][k] * aRGB_cam[k][j];
143 cmatrix[i][j] = (float)cmatrix_tmp[i][j];
144 }
145 }
146
romm_coeff(float romm_cam[3][3])147 void LibRaw::romm_coeff(float romm_cam[3][3])
148 {
149 static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */
150 {{2.034193, -0.727420, -0.306766},
151 {-0.228811, 1.231729, -0.002922},
152 {-0.008565, -0.153273, 1.161839}};
153 int i, j, k;
154
155 for (i = 0; i < 3; i++)
156 for (j = 0; j < 3; j++)
157 for (cmatrix[i][j] = k = 0; k < 3; k++)
158 cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j];
159 }
160
remove_zeroes()161 void LibRaw::remove_zeroes()
162 {
163 unsigned row, col, tot, n;
164 int r, c;
165
166 RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 0, 2);
167
168 for (row = 0; row < height; row++)
169 for (col = 0; col < width; col++)
170 if (BAYER(row, col) == 0)
171 {
172 tot = n = 0;
173 for (r = (int)row - 2; r <= (int)row + 2; r++)
174 for (c = (int)col - 2; c <= (int)col + 2; c++)
175 if (r >= 0 && r < height && c >= 0 && c < width &&
176 FC(r, c) == FC(row, col) && BAYER(r, c))
177 tot += (n++, BAYER(r, c));
178 if (n)
179 BAYER(row, col) = tot / n;
180 }
181 RUN_CALLBACK(LIBRAW_PROGRESS_REMOVE_ZEROES, 1, 2);
182 }
crop_masked_pixels()183 void LibRaw::crop_masked_pixels()
184 {
185 int row, col;
186 unsigned c, m, zero, val;
187 #define mblack imgdata.color.black_stat
188
189 if (mask[0][3] > 0)
190 goto mask_set;
191 if (load_raw == &LibRaw::canon_load_raw ||
192 load_raw == &LibRaw::lossless_jpeg_load_raw ||
193 load_raw == &LibRaw::crxLoadRaw)
194 {
195 mask[0][1] = mask[1][1] += 2;
196 mask[0][3] -= 2;
197 goto sides;
198 }
199 if (load_raw == &LibRaw::canon_600_load_raw ||
200 load_raw == &LibRaw::sony_load_raw ||
201 (load_raw == &LibRaw::eight_bit_load_raw && strncmp(model, "DC2", 3)) ||
202 load_raw == &LibRaw::kodak_262_load_raw ||
203 (load_raw == &LibRaw::packed_load_raw && (load_flags & 32)))
204 {
205 sides:
206 mask[0][0] = mask[1][0] = top_margin;
207 mask[0][2] = mask[1][2] = top_margin + height;
208 mask[0][3] += left_margin;
209 mask[1][1] += left_margin + width;
210 mask[1][3] += raw_width;
211 }
212 if (load_raw == &LibRaw::nokia_load_raw)
213 {
214 mask[0][2] = top_margin;
215 mask[0][3] = width;
216 }
217 if (load_raw == &LibRaw::broadcom_load_raw)
218 {
219 mask[0][2] = top_margin;
220 mask[0][3] = width;
221 }
222 mask_set:
223 memset(mblack, 0, sizeof mblack);
224 for (zero = m = 0; m < 8; m++)
225 for (row = MAX(mask[m][0], 0); row < MIN(mask[m][2], raw_height); row++)
226 for (col = MAX(mask[m][1], 0); col < MIN(mask[m][3], raw_width); col++)
227 {
228 /* No need to subtract margins because full area and active area filters are the same */
229 c = FC(row, col);
230 mblack[c] += val = raw_image[(row)*raw_pitch / 2 + (col)];
231 mblack[4 + c]++;
232 zero += !val;
233 }
234 if (load_raw == &LibRaw::canon_600_load_raw && width < raw_width)
235 {
236 black = (mblack[0] + mblack[1] + mblack[2] + mblack[3]) /
237 MAX(1, (mblack[4] + mblack[5] + mblack[6] + mblack[7])) -
238 4;
239 }
240 else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7])
241 {
242 FORC4 cblack[c] = mblack[c] / MAX(1, mblack[4 + c]);
243 black = cblack[4] = cblack[5] = cblack[6] = 0;
244 }
245 }
246 #undef mblack
247
pseudoinverse(double (* in)[3],double (* out)[3],int size)248 void LibRaw::pseudoinverse(double (*in)[3], double (*out)[3], int size)
249 {
250 double work[3][6], num;
251 int i, j, k;
252
253 for (i = 0; i < 3; i++)
254 {
255 for (j = 0; j < 6; j++)
256 work[i][j] = j == i + 3;
257 for (j = 0; j < 3; j++)
258 for (k = 0; k < size && k < 4; k++)
259 work[i][j] += in[k][i] * in[k][j];
260 }
261 for (i = 0; i < 3; i++)
262 {
263 num = work[i][i];
264 for (j = 0; j < 6; j++)
265 if (fabs(num) > 0.00001f)
266 work[i][j] /= num;
267 for (k = 0; k < 3; k++)
268 {
269 if (k == i)
270 continue;
271 num = work[k][i];
272 for (j = 0; j < 6; j++)
273 work[k][j] -= work[i][j] * num;
274 }
275 }
276 for (i = 0; i < size && i < 4; i++)
277 for (j = 0; j < 3; j++)
278 for (out[i][j] = k = 0; k < 3; k++)
279 out[i][j] += work[j][k + 3] * in[i][k];
280 }
281
cam_xyz_coeff(float _rgb_cam[3][4],double cam_xyz[4][3])282 void LibRaw::cam_xyz_coeff(float _rgb_cam[3][4], double cam_xyz[4][3])
283 {
284 double cam_rgb[4][3], inverse[4][3], num;
285 int i, j, k;
286
287 for (i = 0; i < colors && i < 4; i++) /* Multiply out XYZ colorspace */
288 for (j = 0; j < 3; j++)
289 for (cam_rgb[i][j] = k = 0; k < 3; k++)
290 cam_rgb[i][j] += cam_xyz[i][k] * LibRaw_constants::xyz_rgb[k][j];
291
292 for (i = 0; i < colors && i < 4; i++)
293 { /* Normalize cam_rgb so that */
294 for (num = j = 0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */
295 num += cam_rgb[i][j];
296 if (num > 0.00001)
297 {
298 for (j = 0; j < 3; j++)
299 cam_rgb[i][j] /= num;
300 pre_mul[i] = 1 / num;
301 }
302 else
303 {
304 for (j = 0; j < 3; j++)
305 cam_rgb[i][j] = 0.0;
306 pre_mul[i] = 1.0;
307 }
308 }
309 pseudoinverse(cam_rgb, inverse, colors);
310 for (i = 0; i < 3; i++)
311 for (j = 0; j < colors && j < 4; j++)
312 _rgb_cam[i][j] = inverse[j][i];
313 }
314
tiff_get(unsigned base,unsigned * tag,unsigned * type,unsigned * len,unsigned * save)315 void LibRaw::tiff_get(unsigned base, unsigned *tag, unsigned *type,
316 unsigned *len, unsigned *save)
317 {
318 #ifdef LIBRAW_IOSPACE_CHECK
319 INT64 pos = ftell(ifp);
320 INT64 fsize = ifp->size();
321 if (fsize < 12 || (fsize - pos) < 12)
322 throw LIBRAW_EXCEPTION_IO_EOF;
323 #endif
324 *tag = get2();
325 *type = get2();
326 *len = get4();
327 *save = ftell(ifp) + 4;
328 if (*len * tagtype_dataunit_bytes[(*type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *type : 0] > 4)
329 fseek(ifp, get4() + base, SEEK_SET);
330 }
331