File indexing completed on 2025-01-05 03:56:58

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 #ifdef _MSC_VER
0021 #if _MSC_VER < 1800 /* below MSVC 2013 */
0022 float roundf(float f)
0023 {
0024  return floorf(f + 0.5);
0025 }
0026 
0027 #endif
0028 #endif
0029 
0030 /*
0031    CIFF block 0x1030 contains an 8x8 white sample.
0032    Load this into white[][] for use in scale_colors().
0033  */
0034 void LibRaw::ciff_block_1030()
0035 {
0036   static const ushort key[] = {0x410, 0x45f3};
0037   int i, bpp, row, col, vbits = 0;
0038   unsigned long bitbuf = 0;
0039 
0040   if ((get2(), get4()) != 0x80008 || !get4())
0041     return;
0042   bpp = get2();
0043   if (bpp != 10 && bpp != 12)
0044     return;
0045   for (i = row = 0; row < 8; row++)
0046     for (col = 0; col < 8; col++)
0047     {
0048       if (vbits < bpp)
0049       {
0050         bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]);
0051         vbits += 16;
0052       }
0053       white[row][col] = bitbuf >> (vbits -= bpp) & ~(-1 << bpp);
0054     }
0055 }
0056 
0057 /*
0058    Parse a CIFF file, better known as Canon CRW format.
0059  */
0060 void LibRaw::parse_ciff(int offset, int length, int depth)
0061 {
0062   int nrecs, c, type, len, wbi = -1;
0063   INT64 save, tboff;
0064   ushort key[] = {0x410, 0x45f3};
0065   ushort CanonColorInfo1_key;
0066   ushort Appendix_A = 0;
0067   INT64 WB_table_offset = 0;
0068   int UseWBfromTable_as_AsShot = 1;
0069   int Got_AsShotWB = 0;
0070   INT64 fsize = ifp->size();
0071   if (metadata_blocks++ > LIBRAW_MAX_METADATA_BLOCKS)
0072     throw LIBRAW_EXCEPTION_IO_CORRUPT;
0073 
0074   fseek(ifp, offset + length - 4, SEEK_SET);
0075   tboff = INT64(get4()) + offset;
0076   fseek(ifp, tboff, SEEK_SET);
0077   nrecs = get2();
0078   if (nrecs < 1)
0079     return;
0080   if ((nrecs | depth) > 127)
0081     return;
0082 
0083   if (nrecs * 10 + offset > fsize)
0084     return;
0085 
0086   while (nrecs--)
0087   {
0088     type = get2();
0089     len = get4();
0090     INT64 see = offset + get4();
0091     save = ftell(ifp);
0092 
0093     /* the following tags are not sub-tables
0094      * they contain the value in the "len" field
0095      * for such tags skip the check against filesize
0096      */
0097     if ((type != 0x2007) && (type != 0x580b) && (type != 0x501c) &&
0098         (type != 0x5029) && (type != 0x5813) && (type != 0x5814) &&
0099         (type != 0x5817) && (type != 0x5834) && (type != 0x580e))
0100     {
0101 
0102       if (see >= fsize)
0103       { // At least one byte
0104         fseek(ifp, save, SEEK_SET);
0105         continue;
0106       }
0107       fseek(ifp, see, SEEK_SET);
0108       if ((((type >> 8) + 8) | 8) == 0x38)
0109       {
0110         parse_ciff(ftell(ifp), len, depth + 1); /* Parse a sub-table */
0111       }
0112     }
0113 
0114     if (type == 0x3004)
0115     {
0116       parse_ciff(ftell(ifp), len, depth + 1);
0117     }
0118     else if (type == 0x0810)
0119     {
0120       fread(artist, 64, 1, ifp);
0121     }
0122     else if (type == 0x080a)
0123     {
0124       fread(make, 64, 1, ifp);
0125       fseek(ifp, strbuflen(make) - 63, SEEK_CUR);
0126       fread(model, 64, 1, ifp);
0127 
0128     } else if (type == 0x080b) {
0129       stmread(imCommon.firmware, (unsigned)len, ifp);
0130       if (!strncasecmp(imCommon.firmware, "Firmware Version", 16))
0131         memmove(imCommon.firmware, imCommon.firmware + 16, strlen(imCommon.firmware) - 15);
0132       trimSpaces(imCommon.firmware);
0133 
0134     } else if (type == 0x1810)
0135     {
0136       width = get4();
0137       height = get4();
0138       pixel_aspect = int_to_float(get4());
0139       flip = get4();
0140     }
0141     else if (type == 0x1835)
0142     { /* Get the decoder table */
0143       tiff_compress = get4();
0144     }
0145     else if (type == 0x2007)
0146     {
0147       thumb_offset = see;
0148       thumb_length = len;
0149     }
0150     else if (type == 0x1818)
0151     {
0152       shutter = libraw_powf64l(2.0f, -int_to_float((get4(), get4())));
0153       ilm.CurAp = aperture = libraw_powf64l(2.0f, int_to_float(get4()) / 2);
0154     }
0155     else if (type == 0x102a) // CanonShotInfo
0156     {
0157       //      iso_speed = pow (2.0, (get4(),get2())/32.0 - 4) * 50;
0158       get2(); // skip one
0159       iso_speed =
0160           libraw_powf64l(2.0f, (get2() + get2()) / 32.0f - 5.0f) * 100.0f;
0161       ilm.CurAp = aperture = _CanonConvertAperture((get2(), get2()));
0162       shutter = libraw_powf64l(2.0f, -float((short)get2()) / 32.f);
0163       imCanon.wbi = wbi = (get2(), get2());
0164       if (wbi >= (int)Canon_wbi2std.size())
0165         wbi = 0;
0166       fseek(ifp, 32, SEEK_CUR);
0167       if (shutter > 1e6)
0168         shutter = float(get2()) / 10.f;
0169     }
0170     else if (type == 0x102c) // CanonColorInfo2 / Appendix A: Pro90IS, G1, G2, S30, S40
0171     {
0172       int CanonColorInfo2_type = get2(); // G1 1028, G2 272, Pro90 IS 769, S30 274, S40 273, EOS D30 276
0173       if (CanonColorInfo2_type > 512) { /* Pro90 IS, G1 */
0174         fseek(ifp, 118, SEEK_CUR);
0175         FORC4 cam_mul[BG2RG1_2_RGBG(c)] = get2();
0176       }
0177       else if (CanonColorInfo2_type != 276) { /* G2, S30, S40 */
0178         Appendix_A = 1;
0179         WB_table_offset = -14;
0180         fseek(ifp, 98, SEEK_CUR);
0181         FORC4 cam_mul[GRBG_2_RGBG(c)] = get2();
0182         if (cam_mul[0] > 0.001f) Got_AsShotWB = 1;
0183       }
0184     }
0185     else if (type == 0x10a9) // ColorBalance: Canon D60, 10D, 300D, and clones
0186     {
0187       int bls = 0;
0188 /*
0189       int table[] = {
0190           LIBRAW_WBI_Auto,     // 0
0191           LIBRAW_WBI_Daylight, // 1
0192           LIBRAW_WBI_Cloudy,   // 2
0193           LIBRAW_WBI_Tungsten, // 3
0194           LIBRAW_WBI_FL_W,     // 4
0195           LIBRAW_WBI_Flash,    // 5
0196           LIBRAW_WBI_Custom,   // 6, absent in Canon D60
0197           LIBRAW_WBI_Auto,     // 7, use this if camera is set to b/w JPEG
0198           LIBRAW_WBI_Shade,    // 8
0199           LIBRAW_WBI_Kelvin    // 9, absent in Canon D60
0200       };
0201 */
0202       int nWB =
0203           ((get2() - 2) / 8) -
0204           1; // 2 bytes this, N recs 4*2bytes each, last rec is black level
0205       if (nWB)
0206         FORC4 icWBC[LIBRAW_WBI_Auto][RGGB_2_RGBG(c)] = get2();
0207       if (nWB >= 7)
0208         Canon_WBpresets(0, 0);
0209       else
0210         FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]);
0211       if (nWB == 7) // mostly Canon EOS D60 + some fw#s for 300D;
0212                     // check for 0x1668000 is unreliable
0213       {
0214         if ((wbi >= 0) && (wbi < 9) && (wbi != 6))
0215         {
0216           FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]);
0217         }
0218         else
0219         {
0220           FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]);
0221         }
0222       }
0223       else if (nWB == 9) // Canon 10D, 300D
0224       {
0225         FORC4 icWBC[LIBRAW_WBI_Custom][RGGB_2_RGBG(c)] = get2();
0226         FORC4 icWBC[LIBRAW_WBI_Kelvin][RGGB_2_RGBG(c)] = get2();
0227         if ((wbi >= 0) && (wbi < 10))
0228         {
0229           FORC4 cam_mul[c] = float(icWBC[Canon_wbi2std[wbi]][c]);
0230         }
0231         else
0232         {
0233           FORC4 cam_mul[c] = float(icWBC[LIBRAW_WBI_Auto][c]);
0234         }
0235       }
0236       FORC4
0237       bls += (imCanon.ChannelBlackLevel[RGGB_2_RGBG(c)] = get2());
0238       imCanon.AverageBlackLevel = bls / 4;
0239     }
0240     else if (type == 0x102d)
0241     {
0242       Canon_CameraSettings(len >> 1);
0243     }
0244 
0245     else if (type == 0x10b4) {
0246       switch (get2()) {
0247       case 1:
0248         imCommon.ColorSpace = LIBRAW_COLORSPACE_sRGB;
0249         break;
0250       case 2:
0251         imCommon.ColorSpace = LIBRAW_COLORSPACE_AdobeRGB;
0252         break;
0253       default:
0254         imCommon.ColorSpace = LIBRAW_COLORSPACE_Unknown;
0255         break;
0256       }
0257 
0258     } else if (type == 0x580b)
0259     {
0260       if (strcmp(model, "Canon EOS D30"))
0261         sprintf(imgdata.shootinginfo.BodySerial, "%d", len);
0262       else
0263         sprintf(imgdata.shootinginfo.BodySerial, "%0x-%05d", len >> 16,
0264                 len & 0xffff);
0265     }
0266     else if (type == 0x0032) // CanonColorInfo1
0267     {
0268       if (len == 768) { // EOS D30
0269 
0270         ushort q;
0271         fseek(ifp, 4, SEEK_CUR);
0272         for (unsigned linenum = 0; linenum < Canon_D30_linenums_2_StdWBi.size(); linenum++) {
0273           if (Canon_D30_linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) {
0274             FORC4 {
0275               q = get2();
0276               icWBC[Canon_D30_linenums_2_StdWBi[linenum]][RGGB_2_RGBG(c)] =
0277                 (int)(roundf(1024000.0f / (float)MAX(1, q)));
0278             }
0279 //         if (Canon_wbi2std[imCanon.wbi] == *(Canon_D30_linenums_2_StdWBi + linenum)) {
0280 //           FORC4 cam_mul[c] = icWBC[*(Canon_D30_linenums_2_StdWBi + linenum)][c];
0281 //           Got_AsShotWB = 1;
0282 //           }
0283           }
0284         }
0285         fseek (ifp, 68-int(Canon_D30_linenums_2_StdWBi.size())*8, SEEK_CUR);
0286 
0287         FORC4 {
0288           q = get2();
0289           cam_mul[RGGB_2_RGBG(c)] = 1024.f / float(MAX(1, q));
0290         }
0291         if (!wbi)
0292           cam_mul[0] = -1; // use my auto white balance
0293 
0294       }
0295       else if ((cam_mul[0] <= 0.001f) || // Pro1, G3, G5, G6, S45, S50, S60, S70
0296                Appendix_A)               // G2, S30, S40
0297       {
0298         libraw_static_table_t linenums_2_StdWBi;
0299         unsigned AsShotWB_linenum = Canon_wbi2std.size();
0300 
0301         CanonColorInfo1_key = get2();
0302         if ((CanonColorInfo1_key == key[0]) && (len == 2048)) { // Pro1
0303           linenums_2_StdWBi = Canon_KeyIs0x0410_Len2048_linenums_2_StdWBi;
0304           WB_table_offset = 8;
0305 
0306         } else if ((CanonColorInfo1_key == key[0]) && (len == 3072)) { // S60, S70, G6
0307           linenums_2_StdWBi = Canon_KeyIs0x0410_Len3072_linenums_2_StdWBi;
0308           WB_table_offset = 16;
0309 
0310         } else if (!CanonColorInfo1_key && (len == 2048)) { // G2, S30, S40; S45, S50, G3, G5
0311           key[0] = key[1] = 0;
0312           linenums_2_StdWBi = Canon_KeyIsZero_Len2048_linenums_2_StdWBi;
0313           if (atof(imCommon.firmware) < 1.02f)
0314             UseWBfromTable_as_AsShot = 0;
0315 
0316         } else goto next_tag;
0317 
0318         if ((Canon_wbi2std[wbi] == LIBRAW_WBI_Auto)    ||
0319             (Canon_wbi2std[wbi] == LIBRAW_WBI_Unknown) ||
0320             Got_AsShotWB)
0321           UseWBfromTable_as_AsShot = 0;
0322 
0323         if (UseWBfromTable_as_AsShot) {
0324           int temp_wbi;
0325           if (Canon_wbi2std[wbi] == LIBRAW_WBI_Custom) temp_wbi = LIBRAW_WBI_Daylight;
0326           else temp_wbi = wbi;
0327           for (AsShotWB_linenum = 0; AsShotWB_linenum < linenums_2_StdWBi.size(); AsShotWB_linenum++) {
0328             if (Canon_wbi2std[temp_wbi] == linenums_2_StdWBi[AsShotWB_linenum]) {
0329               break;
0330             }
0331           }
0332         }
0333 
0334         fseek (ifp, 78LL+WB_table_offset, SEEK_CUR);
0335         for (unsigned linenum = 0; linenum < linenums_2_StdWBi.size(); linenum++) {
0336           if (linenums_2_StdWBi[linenum] != LIBRAW_WBI_Unknown) {
0337             FORC4 icWBC[linenums_2_StdWBi[linenum]][GRBG_2_RGBG(c)] = get2() ^ key[c & 1];
0338             if (UseWBfromTable_as_AsShot && (AsShotWB_linenum == linenum)) {
0339               FORC4 cam_mul[c] = float(icWBC[linenums_2_StdWBi[linenum]][c]);
0340               Got_AsShotWB = 1;
0341             }
0342           } else {
0343             fseek(ifp, 8, SEEK_CUR);
0344           }
0345         }
0346         if (!Got_AsShotWB)
0347           cam_mul[0] = -1;
0348       }
0349     }
0350     else if (type == 0x1030 && wbi >= 0 && (0x18040 >> wbi & 1))
0351     {
0352       ciff_block_1030(); // all that don't have 0x10a9
0353     }
0354     else if (type == 0x1031)
0355     {
0356             raw_width  = imCanon.SensorWidth = (get2(), get2());
0357             raw_height = imCanon.SensorHeight = get2();
0358             fseek(ifp, 4, SEEK_CUR);
0359             imCanon.DefaultCropAbsolute = get_CanonArea();
0360             imCanon.LeftOpticalBlack    = get_CanonArea();
0361     }
0362     else if (type == 0x501c)
0363     {
0364       iso_speed = float(len & 0xffff);
0365     }
0366     else if (type == 0x5029)
0367     {
0368       ilm.CurFocal = float( len >> 16);
0369       ilm.FocalType = len & 0xffff;
0370       if (ilm.FocalType == LIBRAW_FT_ZOOM_LENS)
0371       {
0372         ilm.FocalUnits = 32;
0373         if (ilm.FocalUnits > 1)
0374           ilm.CurFocal /= (float)ilm.FocalUnits;
0375       }
0376       focal_len = ilm.CurFocal;
0377     }
0378     else if (type == 0x5813)
0379     {
0380       flash_used = int_to_float(len);
0381     }
0382     else if (type == 0x5814)
0383     {
0384       canon_ev = int_to_float(len);
0385     }
0386     else if (type == 0x5817)
0387     {
0388       shot_order = len;
0389     }
0390     else if (type == 0x5834)
0391     {
0392       unique_id = ((unsigned long long)len << 32) >> 32;
0393       setCanonBodyFeatures(unique_id);
0394     }
0395     else if (type == 0x580e)
0396     {
0397       timestamp = len;
0398     }
0399     else if (type == 0x180e)
0400     {
0401       timestamp = get4();
0402     }
0403 
0404 next_tag:;
0405 #ifdef LOCALTIME
0406     if ((type | 0x4000) == 0x580e)
0407       timestamp = mktime(gmtime(&timestamp));
0408 #endif
0409     fseek(ifp, save, SEEK_SET);
0410   }
0411 }