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__) && !defined(__DragonFly__)
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__) && !defined(__DragonFly__)
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