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 }