File indexing completed on 2025-01-05 03:57:00

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 #include "../../internal/libraw_cameraids.h"
0021 
0022 // clang-format on
0023 static const struct
0024 {
0025     const int CorpId;
0026     const char *CorpName;
0027 } CorpTable[] = {
0028     {LIBRAW_CAMERAMAKER_Agfa,           "AgfaPhoto"},
0029     {LIBRAW_CAMERAMAKER_Apple,          "Apple"},
0030     {LIBRAW_CAMERAMAKER_Broadcom,       "Broadcom"},
0031     {LIBRAW_CAMERAMAKER_Canon,          "Canon"},
0032     {LIBRAW_CAMERAMAKER_Casio,          "Casio"},
0033     {LIBRAW_CAMERAMAKER_CINE,           "CINE"},
0034     {LIBRAW_CAMERAMAKER_Epson,          "Epson"},
0035     {LIBRAW_CAMERAMAKER_Fujifilm,       "Fujifilm"},
0036     {LIBRAW_CAMERAMAKER_Mamiya,         "Mamiya"},
0037     {LIBRAW_CAMERAMAKER_Motorola,       "Motorola"},
0038     {LIBRAW_CAMERAMAKER_Kodak,          "Kodak"},
0039     {LIBRAW_CAMERAMAKER_Konica,         "Konica"},
0040     {LIBRAW_CAMERAMAKER_Minolta,        "Minolta"},
0041     {LIBRAW_CAMERAMAKER_Leica,          "Leica"},
0042     {LIBRAW_CAMERAMAKER_Nikon,          "Nikon"},
0043     {LIBRAW_CAMERAMAKER_Nokia,          "Nokia"},
0044     {LIBRAW_CAMERAMAKER_Olympus,        "Olympus"},
0045     {LIBRAW_CAMERAMAKER_OmDigital,      "OM Digital"},
0046     {LIBRAW_CAMERAMAKER_Ricoh,          "Ricoh"},
0047     {LIBRAW_CAMERAMAKER_Pentax,         "Pentax"},
0048     {LIBRAW_CAMERAMAKER_PhaseOne,       "Phase One"},
0049     {LIBRAW_CAMERAMAKER_PhaseOne,       "PhaseOne"},
0050     {LIBRAW_CAMERAMAKER_Samsung,        "Samsung"},
0051     {LIBRAW_CAMERAMAKER_Sigma,          "Sigma"},
0052     {LIBRAW_CAMERAMAKER_Sinar,          "Sinar"},
0053     {LIBRAW_CAMERAMAKER_Sony,           "Sony"},
0054     {LIBRAW_CAMERAMAKER_YI,             "YI"},
0055     // add corp. names below
0056     {LIBRAW_CAMERAMAKER_Alcatel,        "Alcatel"},
0057     {LIBRAW_CAMERAMAKER_Aptina,         "Aptina"},
0058     {LIBRAW_CAMERAMAKER_AVT,            "AVT"},
0059     {LIBRAW_CAMERAMAKER_Baumer,         "Baumer"},
0060     {LIBRAW_CAMERAMAKER_Clauss,         "Clauss"},
0061     {LIBRAW_CAMERAMAKER_Contax,         "Contax"},
0062     {LIBRAW_CAMERAMAKER_Creative,       "Creative"},
0063     {LIBRAW_CAMERAMAKER_DJI,            "DJI"},
0064     {LIBRAW_CAMERAMAKER_Foculus,        "Foculus"},
0065     {LIBRAW_CAMERAMAKER_Generic,        "Generic"},
0066     {LIBRAW_CAMERAMAKER_Gione,          "Gione"},
0067     {LIBRAW_CAMERAMAKER_GITUP,          "GITUP"},
0068     {LIBRAW_CAMERAMAKER_Hasselblad,     "Hasselblad"},
0069     {LIBRAW_CAMERAMAKER_HTC,            "HTC"},
0070     {LIBRAW_CAMERAMAKER_I_Mobile,       "I_Mobile"},
0071     {LIBRAW_CAMERAMAKER_Imacon,         "Imacon"},
0072     {LIBRAW_CAMERAMAKER_ISG,            "ISG"},
0073     {LIBRAW_CAMERAMAKER_JK_Imaging,     "JK Imaging"}, // Kodak
0074     {LIBRAW_CAMERAMAKER_Leaf,           "Leaf"},
0075     {LIBRAW_CAMERAMAKER_Lenovo,         "Lenovo"},
0076     {LIBRAW_CAMERAMAKER_LG,             "LG"},
0077     {LIBRAW_CAMERAMAKER_Logitech,       "Logitech"},
0078     {LIBRAW_CAMERAMAKER_Matrix,         "Matrix"},
0079     {LIBRAW_CAMERAMAKER_Meizu,          "Meizu"},
0080     {LIBRAW_CAMERAMAKER_Micron,         "Micron"},
0081     {LIBRAW_CAMERAMAKER_NGM,            "NGM"},
0082     {LIBRAW_CAMERAMAKER_OmniVison,      "OmniVison"},
0083     {LIBRAW_CAMERAMAKER_Panasonic,      "Panasonic"},
0084     {LIBRAW_CAMERAMAKER_Photron,        "Photron"},
0085     {LIBRAW_CAMERAMAKER_Pixelink,       "Pixelink"},
0086     {LIBRAW_CAMERAMAKER_Polaroid,       "Polaroid"},
0087     {LIBRAW_CAMERAMAKER_Rollei,         "Rollei"},
0088     {LIBRAW_CAMERAMAKER_RoverShot,      "RoverShot"},
0089     {LIBRAW_CAMERAMAKER_SMaL,           "SMaL"},
0090     {LIBRAW_CAMERAMAKER_ST_Micro,       "ST Micro"},
0091     {LIBRAW_CAMERAMAKER_THL,            "THL"},
0092     {LIBRAW_CAMERAMAKER_Xiaomi,         "Xiaomi"},
0093     {LIBRAW_CAMERAMAKER_XIAOYI,         "Xiayi"},
0094     {LIBRAW_CAMERAMAKER_Yuneec,         "Yuneec"},
0095     {LIBRAW_CAMERAMAKER_DXO,            "DxO"},
0096     {LIBRAW_CAMERAMAKER_RED,            "Red"},
0097     {LIBRAW_CAMERAMAKER_PhotoControl,   "Photo Control"},
0098     {LIBRAW_CAMERAMAKER_Google,         "Google"},
0099     {LIBRAW_CAMERAMAKER_GoPro,          "GoPro"},
0100     {LIBRAW_CAMERAMAKER_Parrot,         "Parrot"},
0101     {LIBRAW_CAMERAMAKER_Zeiss,          "Zeiss"},
0102     {LIBRAW_CAMERAMAKER_OnePlus,        "OnePlus"},
0103     {LIBRAW_CAMERAMAKER_VIVO,           "Vivo"},
0104     {LIBRAW_CAMERAMAKER_HMD_Global,     "HMD Global"},
0105     {LIBRAW_CAMERAMAKER_HUAWEI,         "Huawei"},
0106     {LIBRAW_CAMERAMAKER_RaspberryPi,    "RaspberryPi"},
0107 };
0108 // clang-format on
0109 
0110 int LibRaw::setMakeFromIndex(unsigned makei)
0111 {
0112     if (makei <= LIBRAW_CAMERAMAKER_Unknown || makei >= LIBRAW_CAMERAMAKER_TheLastOne) return 0;
0113 
0114     for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
0115         if ((unsigned)CorpTable[i].CorpId == makei)
0116         {
0117             strcpy(normalized_make, CorpTable[i].CorpName);
0118             maker_index = makei;
0119             return 1;
0120         }
0121     return 0;
0122 }
0123 
0124 const char *LibRaw::cameramakeridx2maker(unsigned maker)
0125 {
0126     for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
0127         if((unsigned)CorpTable[i].CorpId == maker)
0128             return CorpTable[i].CorpName;
0129     return 0;
0130 }
0131 
0132 
0133 #ifdef LIBRAW_OLD_VIDEO_SUPPORT
0134 void LibRaw::fixupArri()
0135 {
0136     struct alist_t
0137     {
0138         const char *a_model;
0139         const char *a_software;
0140         ushort a_width,a_height;
0141         int a_black;
0142         unsigned a_filters;
0143         float a_aspect;
0144     }
0145     alist[] =
0146     {
0147         {"ALEXA65", "Alexa65  XT", 6560 ,3100, 256,0x49494949,1.f},
0148 
0149         {"ALEXALF", "Alexa LF Plus W", 3840 ,2160, 256,0x49494949,1.0f },
0150         {"ALEXALF", "Alexa LF Plus W", 4448 ,1856, 256,0x49494949,0.75f },
0151         {"ALEXALF", "Alexa LF Plus W", 4448 ,3096, 256,0x49494949,1.f },
0152 
0153         {"ALEXA", "Alexa Plus 4:3 SXT", 2880 ,1620, 256,0x61616161,.75f},
0154         {"ALEXA", "Alexa Plus 4:3 SXT", 3168 ,1782, 256,0x61616161,0.75f},
0155         {"ALEXA", "Alexa Plus 4:3 SXT", 3424 ,2202, 256,0x61616161,1.f},
0156         {"ALEXA", "Alexa Plus 4:3 SXT", 2592 ,2160, 256,0x61616161,1.12f},
0157 
0158         {"ALEXA", "Alexa Plus 4:3 XT", 2592 ,2160, 256,0x61616161,1.12f},
0159         {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,2160, 256,0x61616161,1.f},
0160         {"ALEXA", "Alexa Plus 4:3 XT", 2880 ,1620, 256,0x61616161,0.75f},
0161         {"ALEXA", "Alexa Plus 4:3 XT", 3424 ,2202, 256,0x61616161,1.f},
0162     };
0163     for(int i = 0; i < int(sizeof(alist)/sizeof(alist[0])); i++)
0164         if(!strncasecmp(model,alist[i].a_model,strlen(alist[i].a_model)) && software
0165             && !strncasecmp(software,alist[i].a_software,strlen(alist[i].a_software))
0166             && width == alist[i].a_width && height == alist[i].a_height)
0167         {
0168             filters = alist[i].a_filters;
0169             black = alist[i].a_black;
0170             pixel_aspect = alist[i].a_aspect;
0171             strcpy(model,software);
0172             software[0]=0;
0173             return;
0174         }
0175 }
0176 #endif
0177 /*
0178    Identify which camera created this file, and set global variables
0179    accordingly.
0180  */
0181 void LibRaw::identify()
0182 {
0183   // clang-format off
0184   static const ushort canon[][11] = {
0185       // raw_width, raw_height, left_margin, top_margin,
0186       // width_decrement, height_decrement,
0187       // mask01, mask03, mask11, mask13,
0188       // CFA_filters.
0189       { 1944, 1416, 0, 0, 48, 0 }, // 00 "PowerShot Pro90 IS"
0190       { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, // 01 "PowerShot S30", "PowerShot G1"
0191       { 2224, 1456, 48, 6, 0, 2 }, // 02 "EOS D30"
0192       { 2376, 1728, 12, 6, 52, 2 }, // 03 "PowerShot G2", "PowerShot S40", "PowerShot G3", "PowerShot S45"
0193       { 2672, 1968, 12, 6, 44, 2 }, // 04 "PowerShot G5", "PowerShot S50", "PowerShot S60"
0194       { 3152, 2068, 64, 12, 0, 0, 16 }, // 05 "EOS D60", "EOS 10D", "EOS 300D"
0195       { 3160, 2344, 44, 12, 4, 4 }, // 06 "PowerShot G6", "PowerShot S70"
0196       { 3344, 2484, 4, 6, 52, 6 }, // 07 "PowerShot Pro1"
0197       { 3516, 2328, 42, 14, 0, 0 }, // 08 "EOS 350D"
0198       { 3596, 2360, 74, 12, 0, 0 }, // 09 "EOS-1D Mark II", "EOS 20D", "EOS-1D Mark II N", "EOS 30D"
0199       { 3744, 2784, 52, 12, 8, 12 }, // 10 "PowerShot G11", "PowerShot S90", "PowerShot G12", "PowerShot S95"
0200       { 3944, 2622, 30, 18, 6, 2 }, // 11 "EOS 40D"
0201       { 3948, 2622, 42, 18, 0, 2 }, // 12 "EOS 400D", "EOS 1000D"
0202       { 3984, 2622, 76, 20, 0, 2, 14 }, // 13 "EOS-1D Mark III"
0203       { 4032, 2656, 112, 44, 10, 0 }, // 14 APS-C crop mode: "EOS 6D Mark II"??, "EOS RP"
0204       { 4104, 3048, 48, 12, 24, 12 }, // 15 "PowerShot G9"
0205       { 4116, 2178, 4, 2, 0, 0 },  // 16 ??
0206       { 4152, 2772, 192, 12, 0, 0 }, // 17 "PowerShot SX1 IS"
0207       { 4160, 3124, 104, 11, 8, 65 }, // 18 "PowerShot S100 (new)", "PowerShot S100V", "PowerShot G15", "PowerShot S110 (new)"
0208       { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, // 19 "PowerShot SX50 HS"
0209       { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, // 20 "PowerShot G16", "PowerShot S120"
0210       { 4312, 2876, 22, 18, 0, 2 }, // 21 "EOS 450D"
0211       { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R"
0212       { 4352, 2874, 62, 18, 0, 0 }, // 23 "EOS 1100D"
0213       { 4476, 2954, 90, 34, 0, 0 }, // 24 "EOS 5D"
0214       { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, // 25 "PowerShot G10"
0215       { 4480, 3366, 80, 50, 0, 0 }, // 26 "PowerShot G1 X Mark II"
0216       { 4496, 3366, 80, 50, 12, 0 }, // 27 "PowerShot G1 X"
0217       { 4768, 3516, 96, 16, 0, 0, 0, 16 }, // 28 "PowerShot SX60 HS"
0218       { 4832, 3204, 62, 26, 0, 0 }, // 29 "EOS 500D"
0219       { 4832, 3228, 62, 51, 0, 0 }, // 30 "EOS 50D"
0220       { 5108, 3349, 98, 13, 0, 0 }, // 31 "EOS-1Ds Mark II"
0221       { 5120, 3318, 142, 45, 62, 0 }, // 32  "EOS-1D Mark IV"
0222       { 5280, 3528, 72, 52, 0, 0 }, // 33 "EOS M10", "EOS 650D", "EOS 700D", "EOS M", "EOS 100D", "EOS M2"
0223       { 5344, 3516, 142, 51, 0, 0 }, // 34 "EOS 550D", "EOS 600D", "EOS 60D", "EOS 1200D", "EOS 1300D", "EOS 3000D"
0224       { 5344, 3584, 126, 100, 0, 2 }, // 35 "EOS-1D X", "EOS-1D C"
0225       { 5344, 3950, 98, 18, 0, 0, 0, 24, 0, 0 }, // 36 "PowerShot SX70 HS"
0226       { 5360, 3516, 158, 51, 0, 0 }, // 37 "EOS 7D"
0227       { 5568, 3708, 72, 38, 0, 0 }, // 38; "EOS 7D Mark II", "EOS 6D", "EOS 70D", "EOS-1D X MARK II"
0228       { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, // 39 "PowerShot G7 X", "PowerShot G3 X", "PowerShot G9 X", "PowerShot G5 X", "PowerShot G7 X Mark II", "PowerShot G9 X Mark II"
0229       { 5712, 3774, 62, 20, 10, 2 }, // 40 "EOS-1Ds Mark III"
0230       { 5792, 3804, 158, 51, 0, 0 }, // 41 "EOS 5D Mark II"
0231       { 5920, 3950, 122, 80, 2, 0 }, // 42 "EOS 5D Mark III"
0232       { 6096, 4051, 76, 35, 0, 0 }, // 43 "EOS 1500D"
0233       { 6096, 4056, 72, 34, 0, 0 }, // 44 "EOS M3", "EOS 760D", "EOS 750D"
0234       { 6288, 4056, 264, 36, 0, 0 }, // 45 "EOS M5", "EOS M100", "EOS M6", "PowerShot G1 X Mark III", "EOS 80D", "EOS 800D", "EOS 77D", "EOS 200D", "EOS 250D", "EOS M50"
0235       { 6384, 4224, 120, 44, 0, 0 }, // 46 "EOS 6D Mark II", "EOS RP"
0236       { 6880, 4544, 136, 42, 0, 0 }, // 47 "EOS 5D Mark IV"
0237       { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R"
0238       { 7128, 4732, 144, 72, 0, 0 }, // 49 "EOS M6 II", "EOS 90D"
0239       { 8896, 5920, 160, 64, 0, 0 }, // 50 "EOS 5DS", "EOS 5DS R"
0240       { 6192, 4152, 160, 120, 0, 0}, // EOS R3
0241       { 6192, 4060, 168, 52, 24, 8, 16,48,32,0,} // EOS R10
0242   };
0243 
0244   static const libraw_custom_camera_t const_table[] = {
0245       { 786432, 1024, 768, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-080C" },
0246       { 1447680, 1392, 1040, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-145C" },
0247       { 1920000, 1600, 1200, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-201C" },
0248       { 5067304, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C" },
0249       { 5067316, 2588, 1958, 0, 0, 0, 0, 0, 0x94, 0, 0, "AVT", "F-510C", 12 },
0250       { 10134608, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C" },
0251       { 10134620, 2588, 1958, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-510C", 12 },
0252       { 16157136, 3272, 2469, 0, 0, 0, 0, 9, 0x94, 0, 0, "AVT", "F-810C" },
0253       { 3995136, 1632, 1224, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" },
0254       { 15980544, 3264, 2448, 0, 0, 0, 0, 8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" },
0255       { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" },
0256       { 31850496, 4608, 3456, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 4:3" },
0257       { 23887872, 4608, 2592, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "GIT2 16:9" },
0258       { 32257024, 4624, 3488, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" },
0259       { 24192768, 4624, 2616, 8, 2, 16, 2, 0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" },
0260       { 18016000, 4000, 2252, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" },
0261       //          {24000000, 4000, 3000, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP",
0262       //          "G3DUO 4:3"}, // Conflict w/ Samsung WB550
0263 
0264       //   Android Raw dumps id start
0265       //   File Size in bytes Horizontal Res Vertical Flag then bayer order eg
0266       //   0x16 bbgr 0x94 rggb
0267       { 1540857, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "Samsung", "S3" },
0268       { 2658304, 1212, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontMipi" },
0269       { 2842624, 1296, 1096, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3FrontQCOM" },
0270       { 2969600, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" },
0271       { 3170304, 1976, 1200, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" },
0272       { 3763584, 1584, 1184, 0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" },
0273       { 5107712, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" },
0274       { 5382640, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" },
0275       { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" },
0276       { 5664912, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" },
0277       { 5364240, 2688, 1520, 0, 0, 0, 0, 1, 0x61, 0, 0, "OmniVisi", "4688" },
0278       { 6299648, 2592, 1944, 0, 0, 0, 0, 1, 0x16, 0, 0, "OmniVisi", "OV5648" },
0279       { 6721536, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "OmniVisi", "OV56482" },
0280       { 6746112, 2592, 1944, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "OneSV" },
0281       { 9631728, 2532, 1902, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" },
0282       { 9830400, 2560, 1920, 0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" },
0283       { 10186752, 3264, 2448, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" },
0284       { 10223360, 2608, 1944, 0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" },
0285       { 10782464, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" },
0286       { 10788864, 3282, 2448, 0, 0, 0, 0, 0, 0x16, 0, 0, "Xperia", "L" },
0287       { 15967488, 3264, 2446, 0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" },
0288       { 16224256, 4208, 3082, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3MipiL" },
0289       { 16424960, 4208, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "IMX135", "MipiL" },
0290       { 17326080, 4164, 3120, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G3LQCom" },
0291       { 17522688, 4212, 3120, 0, 0, 0, 0, 0, 0x16, 0, 0, "Sony", "IMX135-QCOM" },
0292       { 19906560, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7mipi" },
0293       { 19976192, 5312, 2988, 0, 0, 0, 0, 1, 0x16, 0, 0, "LG", "G4" },
0294       { 20389888, 4632, 3480, 0, 0, 0, 0, 1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" },
0295       { 20500480, 4656, 3496, 0, 0, 0, 0, 1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" },
0296       { 21233664, 4608, 3456, 0, 0, 0, 0, 1, 0x16, 0, 0, "Gione", "E7qcom" },
0297       { 26023936, 4192, 3104, 0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" },
0298       { 26257920, 4208, 3120, 0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" },
0299       { 26357760, 4224, 3120, 0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" },
0300       { 41312256, 5248, 3936, 0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" },
0301       { 42923008, 5344, 4016, 0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" },
0302       //   Android Raw dumps id end
0303       { 20137344, 3664, 2748, 0, 0, 0, 0, 0x40, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff },
0304       { 2868726, 1384, 1036, 0, 0, 0, 0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 },
0305       { 6553440, 2664, 1968, 4, 4, 44, 4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack
0306       { 9243240, 3152, 2346, 12, 7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack
0307       { 6653280, 2672, 1992, 10, 6, 42, 2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack
0308       { 6573120, 2672, 1968, 12, 8, 44, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack
0309       { 9219600, 3152, 2340, 36, 12, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack
0310       { 10383120, 3344, 2484, 12, 6, 44, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack
0311       { 12945240, 3736, 2772, 12, 6, 52, 6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack
0312       { 15636240, 4104, 3048, 48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack
0313       { 10341600, 3336, 2480, 6, 5, 32, 3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack
0314       { 24724224, 4704, 3504, 8, 16, 56, 8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack
0315       { 18763488, 4104, 3048, 10, 22, 82, 22, 8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ?
0316       { 19493760, 4160, 3124, 104, 12, 8, 66, 40, 0x49, 0, 2,  "Canon", "PowerShot S100" }, // chdk hack CRW
0317       { 7710960, 2888, 2136, 44, 8, 4, 0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack
0318       { 5298000, 2400, 1766, 12, 12, 44, 2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack
0319       { 18653760, 4080, 3048, 24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack
0320       { 21936096, 4464, 3276, 25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack
0321       { 19167840, 4176, 3060, 96, 16, 8, 0,  40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2
0322       { 15467760, 3720, 2772, 6, 12, 30, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack
0323       { 15534576, 3728, 2778, 12, 9, 44, 9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack
0324       { 19131120, 4168, 3060, 92, 16, 4, 1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack
0325       { 31663200, 5344, 3950, 96, 18, 0, 0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack
0326       { 30858240, 5248, 3920, 8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack
0327       { 1976352, 1632, 1211, 0, 2, 0, 1, 0, 0x94, 0, 1, "Casio", "QV-2000UX" },
0328       { 3217760, 2080, 1547, 0, 0, 10, 1, 0, 0x94, 0, 1, "Casio", "QV-3*00EX" },
0329       { 6218368, 2585, 1924, 0, 0, 9, 0, 0, 0x94, 0, 1, "Casio", "QV-5700" },
0330       { 7816704, 2867, 2181, 0, 0, 34, 36, 0, 0x16, 0, 1, "Casio", "EX-Z60" },
0331       { 2937856, 1621, 1208, 0, 0, 1, 0, 0, 0x94, 7, 13, "Casio", "EX-S20" },
0332       { 4948608, 2090, 1578, 0, 0, 32, 34, 0, 0x94, 7, 1, "Casio", "EX-S100" },
0333       { 6054400, 2346, 1720, 2, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "QV-R41" },
0334       { 7426656, 2568, 1928, 0, 0, 0, 0, 0, 0x94, 0, 1, "Casio", "EX-P505" },
0335       { 7530816, 2602, 1929, 0, 0, 22, 0, 0, 0x94, 7, 1, "Casio", "QV-R51" },
0336       { 7542528, 2602, 1932, 0, 0, 32, 0, 0, 0x94, 7, 1, "Casio", "EX-Z50" },
0337       { 7562048, 2602, 1937, 0, 0, 25, 0, 0, 0x16, 7, 1, "Casio", "EX-Z500" },
0338       { 7753344, 2602, 1986, 0, 0, 32, 26, 0, 0x94, 7, 1, "Casio", "EX-Z55" },
0339       { 9313536, 2858, 2172, 0, 0, 14, 30, 0, 0x94, 7, 1, "Casio", "EX-P600" },
0340       { 10834368, 3114, 2319, 0, 0, 27, 0, 0, 0x94, 0, 1, "Casio", "EX-Z750" },
0341       { 10843712, 3114, 2321, 0, 0, 25, 0, 0, 0x94, 0, 1, "Casio", "EX-Z75" },
0342       { 10979200, 3114, 2350, 0, 0, 32, 32, 0, 0x94, 7, 1, "Casio", "EX-P700" },
0343       { 12310144, 3285, 2498, 0, 0, 6, 30, 0, 0x94, 0, 1, "Casio", "EX-Z850" },
0344       { 12489984, 3328, 2502, 0, 0, 47, 35, 0, 0x94, 0, 1, "Casio", "EX-Z8" },
0345       { 15499264, 3754, 2752, 0, 0, 82, 0, 0, 0x94, 0, 1, "Casio", "EX-Z1050" },
0346       { 18702336, 4096, 3044, 0, 0, 24, 0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" },
0347       { 7684000, 2260, 1700, 0, 0, 0, 0, 13, 0x94, 0, 1, "Casio", "QV-4000" },
0348       { 787456, 1024, 769, 0, 1, 0, 0, 0, 0x49, 0, 0, "Creative", "PC-CAM 600" },
0349       { 28829184, 4384, 3288, 0, 0, 0, 0, 36, 0x61, 0, 0, "DJI" },
0350       { 15151104, 4608, 3288, 0, 0, 0, 0, 0, 0x94, 0, 0, "Matrix" },
0351       { 3840000, 1600, 1200, 0, 0, 0, 0, 65, 0x49, 0, 0, "Foculus", "531C" },
0352       { 307200, 640, 480, 0, 0, 0, 0, 0, 0x94, 0, 0, "Generic" },
0353       { 62464, 256, 244, 1, 1, 6, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" },
0354       { 124928, 512, 244, 1, 1, 10, 1, 0, 0x8d, 0, 0, "Kodak", "DC20" },
0355       { 1652736, 1536, 1076, 0, 52, 0, 0, 0, 0x61, 0, 0, "Kodak", "DCS200" },
0356       { 4159302, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330" },
0357       { 4162462, 2338, 1779, 1, 33, 1, 2, 0, 0x94, 0, 0, "Kodak", "C330", 3160 },
0358       { 2247168, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" },
0359       { 3370752, 1232, 912, 0, 0, 16, 0, 0, 0x00, 0, 0, "Kodak", "C330" },
0360       { 6163328, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603" },
0361       { 6166488, 2864, 2152, 0, 0, 0, 0, 0, 0x94, 0, 0, "Kodak", "C603", 3160 },
0362       { 460800, 640, 480, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" },
0363       { 9116448, 2848, 2134, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "C603" },
0364       { 12241200, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP" },
0365       { 12272756, 4040, 3030, 2, 0, 0, 13, 0, 0x49, 0, 0, "Kodak", "12MP", 31556 },
0366       { 18000000, 4000, 3000, 0, 0, 0, 0, 0, 0x00, 0, 0, "Kodak", "12MP" },
0367       { 614400, 640, 480, 0, 3, 0, 0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" },
0368       { 15360000, 3200, 2400, 0, 0, 0, 0, 96, 0x16, 0, 0, "Lenovo", "A820" },
0369       { 3884928, 1608, 1207, 0, 0, 0, 0, 96, 0x16, 0, 0, "Micron", "2010", 3212 },
0370       { 1138688, 1534, 986, 0, 0, 0, 0, 0, 0x61, 0, 0, "Minolta", "RD175", 513 },
0371       { 1581060, 1305, 969, 0, 0, 18, 6, 6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack
0372       { 2465792, 1638, 1204, 0, 0, 22, 1, 6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775;
0373                                                                             // Olympus C-2020Z
0374       { 2940928, 1616, 1213, 0, 0, 0, 7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500
0375       { 4771840, 2064, 1541, 0, 0, 0, 1, 6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995;
0376                                                                            // Olympus C-3030Z
0377       { 4775936, 2064, 1542, 0, 0, 0, 0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500;
0378                                                                              // Pentax "Optio 33WR"; possibly also Olympus C-740UZ
0379       { 5865472, 2288, 1709, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z
0380       { 5869568, 2288, 1710, 0, 0, 0, 0, 6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2"
0381       { 7438336, 2576, 1925, 0, 0, 0, 1, 6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700
0382       { 8998912, 2832, 2118, 0, 0, 0, 0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack
0383       { 5939200, 2304, 1718, 0, 0, 0, 0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ
0384       { 3178560, 2064, 1540, 0, 0, 0, 0, 0, 0x94, 0, 1, "Pentax", "Optio S V1.01" },
0385       { 4841984, 2090, 1544, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S" },
0386       { 6114240, 2346, 1737, 0, 0, 22, 0, 0, 0x94, 7, 1, "Pentax", "Optio S4" },
0387       { 10702848, 3072, 2322, 0, 0, 0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" },
0388       { 4147200, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD" },
0389       { 4151666, 1920, 1080, 0, 0, 0, 0, 0, 0x49, 0, 0, "Photron", "BC2-HD", 8 },
0390       { 13248000, 2208, 3000, 0, 0, 0, 0, 13, 0x61, 0, 0, "Pixelink", "A782" },
0391       { 6291456, 2048, 1536, 0, 0, 0, 0, 96, 0x61, 0, 0, "RoverShot", "3320AF" },
0392       { 311696, 644, 484, 0, 0, 0, 0, 0, 0x16, 0, 8, "ST Micro", "STV680 VGA" },
0393       { 16098048, 3288, 2448, 0, 0, 24, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack
0394       { 16215552, 3312, 2448, 0, 0, 48, 0, 9, 0x94, 0, 1, "Samsung", "S85" }, // hack
0395       { 20487168, 3648, 2808, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" },
0396       { 24000000, 4000, 3000, 0, 0, 0, 0, 13, 0x94, 5, 1, "Samsung", "WB550" },
0397       { 12582980, 3072, 2048, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare
0398       { 33292868, 4080, 4080, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44
0399       { 44390468, 4080, 5440, 0, 0, 0, 0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54
0400       { 1409024, 1376, 1024, 0, 0, 1, 0, 0, 0x49, 0, 0, "Sony", "XCD-SX910CR" },
0401       { 2818048, 1376, 1024, 0, 0, 1, 0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" },
0402   };
0403 
0404   libraw_custom_camera_t
0405       table[64 + sizeof(const_table) / sizeof(const_table[0])];
0406 
0407 
0408   // clang-format on
0409 
0410   char head[64] = {0}, *cp;
0411   int hlen, fsize, flen, zero_fsize = 1, i, c;
0412   INT64 fsize64;
0413   struct jhead jh;
0414 
0415   unsigned camera_count =
0416       parse_custom_cameras(64, table, imgdata.rawparams.custom_camera_strings);
0417   for (int q = 0; q < int(sizeof(const_table) / sizeof(const_table[0])); q++)
0418     memmove(&table[q + camera_count], &const_table[q], sizeof(const_table[0]));
0419   camera_count += sizeof(const_table) / sizeof(const_table[0]);
0420 
0421   tiff_flip = flip = filters = UINT_MAX; /* unknown */
0422   raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
0423   maximum = height = width = top_margin = left_margin = 0;
0424   cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
0425   iso_speed = shutter = aperture = focal_len = 0;
0426   unique_id = 0ULL;
0427   tiff_nifds = 0;
0428   is_NikonTransfer = 0;
0429   is_Olympus = 0;
0430   OlympusDNG_SubDirOffsetValid = 0;
0431   is_Sony = 0;
0432   is_pana_raw = 0;
0433   maker_index = LIBRAW_CAMERAMAKER_Unknown;
0434   FujiCropMode = 0;
0435   is_PentaxRicohMakernotes = 0;
0436   normalized_model[0] = 0;
0437   normalized_make[0] = 0;
0438   CM_found = 0;
0439   memset(tiff_ifd, 0, sizeof tiff_ifd);
0440   libraw_internal_data.unpacker_data.crx_track_selected = -1;
0441   libraw_internal_data.unpacker_data.crx_track_count = -1;
0442   libraw_internal_data.unpacker_data.CR3_CTMDtag = 0;
0443   imHassy.nIFD_CM[0] = imHassy.nIFD_CM[1] = -1;
0444   imKodak.ISOCalibrationGain = 1.0f;
0445   imCommon.CameraTemperature = imCommon.SensorTemperature =
0446       imCommon.SensorTemperature2 = imCommon.LensTemperature =
0447           imCommon.AmbientTemperature = imCommon.BatteryTemperature =
0448               imCommon.exifAmbientTemperature = -1000.0f;
0449 
0450   libraw_internal_data.unpacker_data.ifd0_offset = -1LL;
0451 
0452   imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_Unknown;
0453   for (i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
0454   {
0455     tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant =
0456         0xffff;
0457     for (int q = 0; q < 4; q++)
0458       tiff_ifd[i].dng_levels.analogbalance[q] = 1.0f;
0459   }
0460 
0461   memset(gpsdata, 0, sizeof gpsdata);
0462   memset(cblack, 0, sizeof cblack);
0463   memset(white, 0, sizeof white);
0464   memset(mask, 0, sizeof mask);
0465   thumb_offset = thumb_length = thumb_width = thumb_height = 0;
0466   load_raw = 0;
0467   thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG
0468   data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
0469   kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
0470   timestamp = shot_order = tiff_samples = black = is_foveon = 0;
0471   mix_green = profile_length = data_error = zero_is_bad = 0;
0472   pixel_aspect = is_raw = raw_color = 1;
0473   tile_width = tile_length = 0;
0474   metadata_blocks = 0;
0475 
0476   for (i = 0; i < 4; i++)
0477   {
0478     cam_mul[i] = i == 1;
0479     pre_mul[i] = i < 3;
0480     FORC3 cmatrix[c][i] = 0;
0481     FORC3 rgb_cam[c][i] = c == i;
0482   }
0483   colors = 3;
0484   for (i = 0; i < 0x10000; i++)
0485     curve[i] = i;
0486 
0487   order = get2();
0488   hlen = get4();
0489   fseek(ifp, 0, SEEK_SET);
0490 
0491   if (fread(head, 1, 64, ifp) < 64)
0492     throw LIBRAW_EXCEPTION_IO_CORRUPT;
0493   libraw_internal_data.unpacker_data.lenRAFData =
0494       libraw_internal_data.unpacker_data.posRAFData = 0;
0495 
0496   fseek(ifp, 0, SEEK_END);
0497   fsize64 = ftell(ifp);
0498   if(fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE && fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE)
0499       throw LIBRAW_EXCEPTION_TOOBIG;
0500 
0501   flen = fsize = ftell(ifp);
0502   if ((cp = (char *)memmem(head, 32, (char *)"MMMM", 4)) ||
0503       (cp = (char *)memmem(head, 32, (char *)"IIII", 4)))
0504   {
0505     parse_phase_one(cp - head);
0506     if (cp - head && parse_tiff(0))
0507       apply_tiff();
0508   }
0509   else if (order == 0x4949 || order == 0x4d4d)
0510   {
0511     if (!memcmp(head + 6, "HEAPCCDR", 8))
0512     {
0513       data_offset = hlen;
0514       parse_ciff(hlen, flen - hlen, 0);
0515       load_raw = &LibRaw::canon_load_raw;
0516     }
0517     else if (parse_tiff(0))
0518       apply_tiff();
0519   }
0520   else if (!memcmp(head, "\xff\xd8\xff\xe1", 4) && !memcmp(head + 6, "Exif", 4))
0521   {
0522     fseek(ifp, 4, SEEK_SET);
0523     data_offset = 4 + get2();
0524     fseek(ifp, data_offset, SEEK_SET);
0525     if (fgetc(ifp) != 0xff)
0526       parse_tiff(12);
0527     thumb_offset = 0;
0528   }
0529   else if (!memcmp(head + 25, "ARECOYK", 7)) // 'KYOCERA' right-to-left
0530   {
0531     strcpy(make, "Contax");
0532     strcpy(model, "N Digital");
0533     parse_kyocera();
0534   }
0535   else if (!strcmp(head, "PXN"))
0536   {
0537     strcpy(make, "Logitech");
0538     strcpy(model, "Fotoman Pixtura");
0539   }
0540   else if (!strcmp(head, "qktk"))
0541   {
0542     strcpy(make, "Apple");
0543     strcpy(model, "QuickTake 100");
0544     load_raw = &LibRaw::quicktake_100_load_raw;
0545   }
0546   else if (!strcmp(head, "qktn"))
0547   {
0548     strcpy(make, "Apple");
0549     strcpy(model, "QuickTake 150");
0550     load_raw = &LibRaw::kodak_radc_load_raw;
0551   }
0552   else if (!memcmp(head, "FUJIFILM", 8))
0553   {
0554     memcpy(imFuji.SerialSignature, head + 0x10, 0x0c);
0555     imFuji.SerialSignature[0x0c] = 0;
0556     memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04);
0557     imFuji.SensorID[0x04] = 0;
0558     strncpy(model, head + 0x1c, 0x20);
0559     model[0x20] = 0;
0560     c = 11;
0561     while (imFuji.SerialSignature[c] > 0 && isdigit(imFuji.SerialSignature[c]) && (c>0))
0562       c--;
0563     if(c < 11)
0564         unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1);
0565     memcpy(imFuji.RAFVersion, head + 0x3c, 4);
0566     imFuji.RAFVersion[4] = 0;
0567     fseek(ifp, 84, SEEK_SET);
0568     thumb_offset = get4();
0569     thumb_length = get4();
0570     fseek(ifp, 92, SEEK_SET);
0571     parse_fuji(get4());
0572     if (thumb_offset > 120)
0573     {
0574       fseek(ifp, 120, SEEK_SET);
0575       is_raw += (i = get4()) ? 1 : 0;
0576       if (is_raw == 2 && shot_select)
0577         parse_fuji(i);
0578     }
0579     load_raw = &LibRaw::unpacked_load_raw;
0580     fseek(ifp, 100 + 28 * (shot_select > 0), SEEK_SET);
0581     parse_tiff(data_offset = get4());
0582     parse_tiff(thumb_offset + 12);
0583     parse_fuji_thumbnail(thumb_offset);
0584     apply_tiff();
0585   }
0586   else if (!memcmp(head, "RIFF", 4))
0587   {
0588     fseek(ifp, 0, SEEK_SET);
0589     parse_riff(100);
0590   }
0591   else if (!memcmp(head + 4, "ftypqt   ", 9))
0592   {
0593     fseek(ifp, 0, SEEK_SET);
0594     parse_qt(fsize);
0595     is_raw = 0;
0596   }
0597   else if (!memcmp(head, "\0\001\0\001\0@", 6))
0598   {
0599     fseek(ifp, 6, SEEK_SET);
0600     fread(make, 1, 8, ifp);
0601     fread(model, 1, 8, ifp);
0602     fread(model2, 1, 16, ifp);
0603     data_offset = get2();
0604     get2();
0605     raw_width = get2();
0606     raw_height = get2();
0607     load_raw = &LibRaw::nokia_load_raw;
0608     filters = 0x61616161;
0609   }
0610   else if (!memcmp(head, "NOKIARAW", 8))
0611   {
0612     strcpy(make, "NOKIA");
0613     order = 0x4949;
0614     fseek(ifp, 300, SEEK_SET);
0615     data_offset = get4();
0616     i = get4(); // bytes count
0617     width = get2();
0618     height = get2();
0619 
0620     // Data integrity check
0621     if (width < 1 || width > 16000 || height < 1 || height > 16000 ||
0622         i < (width * height) || i > (2 * width * height))
0623       throw LIBRAW_EXCEPTION_IO_CORRUPT;
0624 
0625     switch (tiff_bps = i * 8 / (width * height))
0626     {
0627     case 8:
0628       load_raw = &LibRaw::eight_bit_load_raw;
0629       break;
0630     case 10:
0631       load_raw = &LibRaw::nokia_load_raw;
0632       break;
0633     case 0:
0634       throw LIBRAW_EXCEPTION_IO_CORRUPT;
0635       break;
0636     }
0637     raw_height = height + (top_margin = i / (width * tiff_bps / 8) - height);
0638     mask[0][3] = 1;
0639     filters = 0x61616161;
0640   }
0641 #ifdef LIBRAW_OLD_VIDEO_SUPPORT
0642   else if (!memcmp(head, "ARRI", 4))
0643   {
0644     order = 0x4949;
0645     fseek(ifp, 20, SEEK_SET);
0646     width = get4();
0647     height = get4();
0648     strcpy(make, "ARRI");
0649     fseek(ifp, 668, SEEK_SET);
0650     fread(model, 1, 64, ifp);
0651     model[63] = 0;
0652     fseek(ifp, 760, SEEK_SET);
0653     fread(software, 1, 64, ifp);
0654     if((unsigned char)software[0] == 0xff) software[0] = 0;
0655     software[63] = 0;
0656     data_offset = 4096;
0657     load_raw = &LibRaw::packed_load_raw;
0658     load_flags = 88;
0659     filters = 0x61616161;
0660     fixupArri();
0661   }
0662   else if (!memcmp(head, "XPDS", 4))
0663   {
0664     order = 0x4949;
0665     fseek(ifp, 0x800, SEEK_SET);
0666     fread(make, 1, 41, ifp);
0667     raw_height = get2();
0668     raw_width = get2();
0669     fseek(ifp, 56, SEEK_CUR);
0670     fread(model, 1, 30, ifp);
0671     data_offset = 0x10000;
0672     load_raw = &LibRaw::canon_rmf_load_raw;
0673     gamma_curve(0, 12.25, 1, 1023);
0674   }
0675   else if (!memcmp(head + 4, "RED1", 4))
0676   {
0677     strcpy(make, "Red");
0678     strcpy(model, "One");
0679     parse_redcine();
0680     load_raw = &LibRaw::redcine_load_raw;
0681     gamma_curve(1 / 2.4, 12.92, 1, 4095);
0682     filters = 0x49494949;
0683   }
0684 #endif
0685   else if (!memcmp(head, "DSC-Image", 9))
0686     parse_rollei();
0687   else if (!memcmp(head, "PWAD", 4))
0688     parse_sinar_ia();
0689   else if (!memcmp(head, "\0MRM", 4))
0690     parse_minolta(0);
0691   else if (!memcmp(head, "FOVb", 4))
0692   {
0693     parse_x3f(); /* Does nothing if USE_X3FTOOLS is not defined */
0694   }
0695   else if (!memcmp(head, "CI", 2))
0696     parse_cine();
0697 #ifdef USE_6BY9RPI
0698   else if (!memcmp(head, "BRCM", 4)) {
0699     fseek(ifp, 0, SEEK_SET);
0700     strcpy(make, "RaspberryPi");
0701     strcpy(model, "Pi");
0702     parse_raspberrypi();
0703     }
0704 #endif
0705   else if (!memcmp(head + 4, "ftypcrx ", 8))
0706   {
0707     int err;
0708     unsigned long long szAtomList;
0709     short nesting = -1;
0710     short nTrack = -1;
0711     short TrackType;
0712     char AtomNameStack[129];
0713     strcpy(make, "Canon");
0714 
0715     szAtomList = ifp->size();
0716     err = parseCR3(0ULL, szAtomList, nesting, AtomNameStack, nTrack, TrackType);
0717     libraw_internal_data.unpacker_data.crx_track_count = nTrack;
0718     if ((err == 0 || err == -14) &&
0719         nTrack >= 0) // no error, or too deep nesting
0720       selectCRXTrack();
0721   }
0722 
0723   if (dng_version)
0724   {
0725       if (fsize64 > LIBRAW_MAX_DNG_RAW_FILE_SIZE)
0726           throw LIBRAW_EXCEPTION_TOOBIG;
0727   }
0728   else
0729   {
0730     if (fsize64 > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)
0731       throw LIBRAW_EXCEPTION_TOOBIG;
0732   }
0733 
0734   if (make[0] == 0)
0735     for (zero_fsize = i = 0; i < (int)camera_count; i++)
0736       if (fsize == (int)table[i].fsize)
0737       {
0738         strcpy(make, table[i].t_make);
0739         strcpy(model, table[i].t_model);
0740         flip = table[i].flags >> 2;
0741         zero_is_bad = table[i].flags & 2;
0742         data_offset = table[i].offset == 0xffff ? 0 : table[i].offset;
0743         raw_width = table[i].rw;
0744         raw_height = table[i].rh;
0745         left_margin = table[i].lm;
0746         top_margin = table[i].tm;
0747         width = raw_width - left_margin - table[i].rm;
0748         height = raw_height - top_margin - table[i].bm;
0749         filters = 0x1010101U * table[i].cf;
0750         colors = 4 - !((filters & filters >> 1) & 0x5555);
0751         load_flags = table[i].lf & 0xff;
0752         if (table[i].lf & 0x100) /* Monochrome sensor dump */
0753         {
0754           colors = 1;
0755           filters = 0;
0756         }
0757         switch (tiff_bps = (fsize - data_offset) * 8 / (raw_width * raw_height))
0758         {
0759         case 6:
0760           load_raw = &LibRaw::minolta_rd175_load_raw;
0761           ilm.CameraMount = LIBRAW_MOUNT_Minolta_A;
0762           break;
0763         case 8:
0764           load_raw = &LibRaw::eight_bit_load_raw;
0765           break;
0766         case 10:
0767           if ((fsize - data_offset) / raw_height * 3 >= raw_width * 4)
0768           {
0769             load_raw = &LibRaw::android_loose_load_raw;
0770             break;
0771           }
0772           else if (load_flags & 1)
0773           {
0774             load_raw = &LibRaw::android_tight_load_raw;
0775             break;
0776           }
0777         case 12:
0778           load_flags |= 128;
0779           load_raw = &LibRaw::packed_load_raw;
0780           break;
0781         case 16:
0782           order = 0x4949 | 0x404 * (load_flags & 1);
0783           tiff_bps -= load_flags >> 4;
0784           tiff_bps -= load_flags = load_flags >> 1 & 7;
0785           load_raw = table[i].offset == 0xffff
0786                          ? &LibRaw::unpacked_load_raw_reversed
0787                          : &LibRaw::unpacked_load_raw;
0788         }
0789         maximum = (1 << tiff_bps) - (1 << table[i].max);
0790         break;
0791       }
0792   if (zero_fsize)
0793     fsize = 0;
0794   if (make[0] == 0 && fsize64 < 25000000LL)
0795     parse_smal(0, flen);
0796   if (make[0] == 0)
0797   {
0798     parse_jpeg(0);
0799 #ifdef USE_6BY9RPI
0800     if (!(strncmp(model, "ov", 2) && strncmp(model, "RP_", 3) && strncmp(model, "imx477", 6))) {
0801         //Assume that this isn't a raw unless the header can be found
0802         is_raw = 0;
0803 
0804         if (!strncasecmp(model, "RP_testc",8) 
0805             || !strncasecmp(model, "imx477", 6) //  from PyDNG
0806             || !strncasecmp(model, "RP_imx477",9)) {
0807             const long offsets[] = {
0808                 //IMX477 offsets
0809                 3375104,  //2028x1080 12bit
0810                 4751360,  //2028x1520 12bit
0811                 18711040, //4056x3040 12bit
0812                 1015808,  //1012x760 10bit
0813                 -1        //Marker for end of table
0814             };
0815             int offset_idx;
0816             for (offset_idx=0; offsets[offset_idx]!=-1; offset_idx++) {
0817                 if(!fseek (ifp, -offsets[offset_idx], SEEK_END) &&
0818                    fread (head, 1, 32, ifp) && !strncmp(head,"BRCM", 4)) {
0819                     fseek(ifp, -32, SEEK_CUR);
0820                     strcpy (make, "RaspberryPi");
0821                     strcpy(model, "RP_imx477"); // Force single model
0822                     black = (offset_idx == 3) ? 64 : 256;
0823                     parse_raspberrypi();
0824                     break;
0825                 }
0826             }
0827         }
0828         else if (!strncasecmp(model, "RP_imx", 6)) {
0829             const long offsets[] = {
0830                 //IMX219 offsets
0831                 10270208, //8MPix 3280x2464
0832                 2678784,  //1920x1080
0833                 2628608,  //1640x1232
0834                 1963008,  //1640x922
0835                 1233920,  //1280x720
0836                 445440,   //640x480
0837                 -1        //Marker for end of table
0838             };
0839             int offset_idx;
0840             for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) {
0841                 if (!fseek(ifp, -offsets[offset_idx], SEEK_END) &&
0842                     fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) {
0843 
0844                     fseek(ifp, -32, SEEK_CUR);
0845                     strcpy(make, "RaspberryPi");
0846                     black = 66;
0847                     parse_raspberrypi();
0848                     break;
0849                 }
0850             }
0851         }
0852         else if (!strncasecmp(model, "RP_OV", 5) || !strncasecmp(model, "ov5647", 6)) {
0853             const long offsets[] = {
0854                     6404096,  //5MPix 2592x1944
0855                     2717696,  //1920x1080
0856                     1625600,  //1296x972
0857                     1233920,  //1296x730
0858                     445440,   //640x480
0859                     -1        //Marker for end of table
0860             };
0861             int offset_idx;
0862             for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) {
0863                 if (!fseek(ifp, -offsets[offset_idx], SEEK_END) &&
0864                     fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) {
0865                     fseek(ifp, -32, SEEK_CUR);
0866                     strcpy(make, "RaspberryPi");
0867                     strcpy(model, "ov5647"); // Force single model
0868                     width = raw_width;
0869                     //Defaults
0870                     raw_width = 2611;
0871                     filters = 0x16161616;
0872                     black = 16;
0873                     parse_raspberrypi();
0874                     break;
0875                 }
0876             }
0877       }
0878     }// else is_raw = 0;
0879 #else
0880     fseek(ifp, 0, SEEK_END);
0881     int sz = ftell(ifp);
0882     if (!strncmp(model, "RP_imx219", 9) && sz >= 0x9cb600 &&
0883         !fseek(ifp, -0x9cb600, SEEK_END) && fread(head, 1, 0x20, ifp) &&
0884         !strncmp(head, "BRCM", 4))
0885     {
0886       strcpy(make, "Broadcom");
0887       strcpy(model, "RPi IMX219");
0888       if (raw_height > raw_width)
0889         flip = 5;
0890       data_offset = ftell(ifp) + 0x8000 - 0x20;
0891       parse_broadcom();
0892       black = 66;
0893       maximum = 0x3ff;
0894       load_raw = &LibRaw::broadcom_load_raw;
0895       thumb_offset = 0;
0896       thumb_length = sz - 0x9cb600 - 1;
0897     }
0898     else if (!(strncmp(model, "ov5647", 6) && strncmp(model, "RP_OV5647", 9)) &&
0899              sz >= 0x61b800 && !fseek(ifp, -0x61b800, SEEK_END) &&
0900              fread(head, 1, 0x20, ifp) && !strncmp(head, "BRCM", 4))
0901     {
0902       strcpy(make, "Broadcom");
0903       if (!strncmp(model, "ov5647", 6))
0904         strcpy(model, "RPi OV5647 v.1");
0905       else
0906         strcpy(model, "RPi OV5647 v.2");
0907       if (raw_height > raw_width)
0908         flip = 5;
0909       data_offset = ftell(ifp) + 0x8000 - 0x20;
0910       parse_broadcom();
0911       black = 16;
0912       maximum = 0x3ff;
0913       load_raw = &LibRaw::broadcom_load_raw;
0914       thumb_offset = 0;
0915       thumb_length = sz - 0x61b800 - 1;
0916     }
0917     else
0918       is_raw = 0;
0919 #endif
0920   }
0921 
0922   // make sure strings are terminated
0923   desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
0924 
0925   for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
0926   {
0927     if (strcasestr(make, CorpTable[i].CorpName))
0928     { /* Simplify company names */
0929       maker_index = CorpTable[i].CorpId;
0930       break;
0931     }
0932   }
0933 
0934   if (makeIs(LIBRAW_CAMERAMAKER_HMD_Global) && !strncasecmp(model, "Nokia", 5)) {
0935     maker_index = LIBRAW_CAMERAMAKER_Nokia;
0936   }  else if (makeIs(LIBRAW_CAMERAMAKER_JK_Imaging) && !strncasecmp(model, "Kodak", 5)) {
0937     maker_index = LIBRAW_CAMERAMAKER_Kodak;
0938   } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && !strncasecmp(model, "PENTAX", 6)) {
0939     maker_index = LIBRAW_CAMERAMAKER_Pentax;
0940   }
0941 
0942   for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) {
0943     if (maker_index == (unsigned)CorpTable[i].CorpId) {
0944       strcpy(make, CorpTable[i].CorpName);
0945       break;
0946     }
0947   }
0948 
0949   if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Leica)) &&
0950       ((cp = strcasestr(model, " DIGITAL CAMERA")) ||
0951        (cp = strstr(model, "FILE VERSION")))) {
0952     *cp = 0;
0953   }
0954 
0955   remove_trailing_spaces(make, sizeof(make));
0956   remove_trailing_spaces(model, sizeof(model));
0957 
0958   i = int(strbuflen(make)); /* Remove make from model */
0959   if (!strncasecmp(model, make, i) && model[i++] == ' ')
0960     memmove(model, model + i, 64 - i);
0961 
0962   if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && !strncmp(model, "FinePix", 7)) {
0963     memmove(model, model + 7, strlen(model) - 6);
0964     if (model[0] == ' ') {
0965       memmove(model, model + 1, strlen(model));
0966     }
0967   } else if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Konica)) &&
0968              !strncmp(model, "Digital Camera ", 15)) {
0969     memmove(model, model + 15, strlen(model) - 14);
0970   }
0971 
0972   desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
0973   if (!is_raw)
0974     goto notraw;
0975 
0976   if (!height)
0977     height = raw_height;
0978   if (!width)
0979     width = raw_width;
0980 
0981   identify_finetune_pentax();
0982 
0983 
0984   if (dng_version)
0985   {
0986     if (filters == UINT_MAX)
0987       filters = 0;
0988     if (!filters)
0989       colors = tiff_samples;
0990     switch (tiff_compress)
0991     {
0992     case 0: // Compression not set, assuming uncompressed
0993     case 1:
0994       // Uncompressed float: decoder set in apply_tiff for valid files; not set for non-valid with sampleformat==3
0995       if ((load_raw != &LibRaw::uncompressed_fp_dng_load_raw)  && (tiff_sampleformat != 3))
0996         load_raw = &LibRaw::packed_dng_load_raw;
0997       break;
0998     case 7:
0999       load_raw = &LibRaw::lossless_dng_load_raw;
1000       break;
1001     case 8:
1002         if (tiff_sampleformat == 3 && tiff_bps > 8 && (tiff_bps % 8 == 0) && tiff_bps <= 32)
1003             load_raw = &LibRaw::deflate_dng_load_raw;
1004         else if((tiff_sampleformat == 0 || tiff_sampleformat == 1) && tiff_bps>=8 && tiff_bps <=16)
1005           load_raw = &LibRaw::deflate_dng_load_raw;
1006         break;
1007 #ifdef USE_GPRSDK
1008     case 9:
1009         load_raw = &LibRaw::vc5_dng_load_raw_placeholder;
1010         break;
1011 #endif
1012     case 34892:
1013       load_raw = &LibRaw::lossy_dng_load_raw;
1014       break;
1015     default:
1016       load_raw = 0;
1017     }
1018     GetNormalizedModel();
1019     if (makeIs(LIBRAW_CAMERAMAKER_Leica)) {
1020           if (!strcmp(model, "SL2")) 
1021               height -= 3;
1022           if (!strncasecmp(model, "Q2 MONO",7))
1023               height -= 18;
1024     }
1025 
1026     else if (makeIs(LIBRAW_CAMERAMAKER_Olympus) &&
1027         (OlyID == OlyID_STYLUS_1) && // don't use normalized_model below, it is 'Stylus 1'
1028         (strchr(model+6, 's') ||
1029          strchr(model+6, 'S')))
1030     {
1031       width -= 16;
1032     }
1033     goto dng_skip;
1034   }
1035 
1036   if (makeIs(LIBRAW_CAMERAMAKER_Canon) && !fsize && tiff_bps != 15)
1037   {
1038       bool fromtable = false;
1039     if (!load_raw)
1040       load_raw = &LibRaw::lossless_jpeg_load_raw;
1041     for (i = 0; i < int(sizeof canon / sizeof *canon); i++)
1042       if (raw_width == canon[i][0] && raw_height == canon[i][1])
1043       {
1044         width = raw_width - (left_margin = canon[i][2]);
1045         height = raw_height - (top_margin = canon[i][3]);
1046         width -= canon[i][4];
1047         height -= canon[i][5];
1048         mask[0][1] = canon[i][6];
1049         mask[0][3] = -canon[i][7];
1050         mask[1][1] = canon[i][8];
1051         mask[1][3] = -canon[i][9];
1052         if (canon[i][10])
1053           filters = canon[i][10] * 0x01010101U;
1054         fromtable = true;
1055       }
1056     if ((unique_id | 0x20000ULL) ==
1057         0x2720000ULL) // "PowerShot G11", "PowerShot S90": 0x2700000, 0x2720000
1058                       // possibly "PowerShot SX120 IS" (if not chdk hack?): 0x2710000
1059     {
1060       left_margin = 8;
1061       top_margin = 16;
1062     }
1063     if(!fromtable && imCanon.AverageBlackLevel) // not known, but metadata known
1064     {
1065         FORC4 cblack[c] = imCanon.ChannelBlackLevel[c];
1066         black = cblack[4] = cblack[5] = 0;
1067         // Prevent automatic BL calculation
1068         mask[0][3] = 1;
1069         mask[0][1] = 2;
1070 
1071         if ((imCanon.SensorWidth == raw_width) &&
1072             (imCanon.SensorHeight == raw_height))
1073         {
1074             left_margin = (imCanon.DefaultCropAbsolute.l+1) & 0xfffe; // round to 2
1075             width = imCanon.DefaultCropAbsolute.r - left_margin;
1076             top_margin = (imCanon.DefaultCropAbsolute.t +1)  & 0xfffe;
1077             height = imCanon.DefaultCropAbsolute.b - top_margin;
1078         }
1079     }
1080   }
1081 
1082   identify_finetune_by_filesize(fsize);
1083 
1084   if (!strcmp(model, "KAI-0340") && find_green(16, 16, 3840, 5120) < 25)
1085   {
1086     height = 480;
1087     top_margin = filters = 0;
1088     strcpy(model, "C603");
1089   }
1090 
1091   GetNormalizedModel();
1092 
1093   identify_finetune_dcr(head, fsize, flen);
1094 
1095   /* Early reject for damaged images */
1096   if (!load_raw || height < 22 || width < 22 ||
1097       (tiff_bps > 16 &&
1098        (load_raw != &LibRaw::deflate_dng_load_raw &&
1099         load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) ||
1100       tiff_samples > 4 || colors > 4 ||
1101       colors < 1
1102       /* alloc in unpack() may be fooled by size adjust */
1103       || ((int)width + (int)left_margin > 65535) ||
1104       ((int)height + (int)top_margin > 65535))
1105   {
1106     is_raw = 0;
1107     RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1108     return;
1109   }
1110   if (!model[0])
1111   {
1112     sprintf(model, "%dx%d", width, height);
1113     strcpy(normalized_model, model);
1114   }
1115 
1116   if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS) &&
1117       (filters == UINT_MAX)) // Default dcraw behaviour
1118     filters = 0x94949494;
1119   else if (filters == UINT_MAX)
1120   {
1121     if (tiff_nifds > 0 && tiff_samples == 1)
1122     {
1123       colors = 1;
1124       filters = 0;
1125     }
1126     else
1127       filters = 0x94949494;
1128   }
1129 
1130   if (thumb_offset && !thumb_height)
1131   {
1132     fseek(ifp, thumb_offset, SEEK_SET);
1133     if (ljpeg_start(&jh, 1))
1134     {
1135       thumb_width = jh.wide;
1136       thumb_height = jh.high;
1137     }
1138   }
1139 
1140 dng_skip:
1141   if (dng_version)
1142       identify_process_dng_fields();
1143 
1144   /* Early reject for damaged images again (after dng fields processing) */
1145   if (!load_raw || height < 22 || width < 22 ||
1146       (tiff_bps > 16 &&
1147        (load_raw != &LibRaw::deflate_dng_load_raw &&
1148         load_raw != &LibRaw::uncompressed_fp_dng_load_raw )) ||
1149       ((load_raw == &LibRaw::deflate_dng_load_raw || load_raw == &LibRaw::uncompressed_fp_dng_load_raw)
1150         && (tiff_bps < 16 || tiff_bps > 32 || (tiff_bps % 8))   )
1151       ||tiff_samples > 4 || colors > 4 || colors < 1)
1152   {
1153     is_raw = 0;
1154     RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1155     return;
1156   }
1157   {
1158     // Check cam_mul range
1159     int cmul_ok = 1;
1160     FORCC if (cam_mul[c] <= 0.001f) cmul_ok = 0;
1161     ;
1162 
1163     if (cmul_ok)
1164     {
1165       double cmin = cam_mul[0], cmax;
1166       double cnorm[4];
1167       FORCC cmin = MIN(cmin, cam_mul[c]);
1168       FORCC cnorm[c] = cam_mul[c] / cmin;
1169       cmax = cmin = cnorm[0];
1170       FORCC
1171       {
1172         cmin = MIN(cmin, cnorm[c]);
1173         cmax = MIN(cmax, cnorm[c]);
1174       }
1175       if (cmin <= 0.01f || cmax > 100.f)
1176         cmul_ok = false;
1177     }
1178     if (!cmul_ok)
1179     {
1180       if (cam_mul[0] > 0)
1181         cam_mul[0] = 0;
1182       cam_mul[3] = 0;
1183     }
1184   }
1185   if ((use_camera_matrix & (((use_camera_wb || dng_version)?1:0) | 0x2)) &&
1186       cmatrix[0][0] > 0.125)
1187   {
1188     memcpy(rgb_cam, cmatrix, sizeof cmatrix);
1189     raw_color = 0;
1190   }
1191   if (raw_color && !CM_found)
1192     CM_found = adobe_coeff(maker_index, normalized_model);
1193   else if ((imgdata.color.cam_xyz[0][0] < 0.01) && !CM_found)
1194     CM_found = adobe_coeff(maker_index, normalized_model, 1);
1195 
1196   if (load_raw == &LibRaw::kodak_radc_load_raw)
1197     if ((raw_color) && !CM_found)
1198         CM_found = adobe_coeff(LIBRAW_CAMERAMAKER_Apple, "Quicktake");
1199 
1200   if ((maker_index != LIBRAW_CAMERAMAKER_Unknown) && normalized_model[0])
1201     SetStandardIlluminants (maker_index, normalized_model);
1202 
1203   // Clear erroneous fuji_width if not set through parse_fuji or for DNG
1204   if (fuji_width && !dng_version &&
1205       !(imgdata.process_warnings & LIBRAW_WARN_PARSEFUJI_PROCESSED))
1206     fuji_width = 0;
1207 
1208   if (fuji_width)
1209   {
1210     fuji_width = width >> int(!fuji_layout);
1211     filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
1212     width = (height >> fuji_layout) + fuji_width;
1213     height = width - 1;
1214     pixel_aspect = 1;
1215     // Prevent incorrect-sized fuji-rotated files
1216     if (INT64(width)*INT64(height) > INT64(raw_width) * INT64(raw_height) * 8LL)
1217         is_raw = 0;
1218   }
1219   else
1220   {
1221     if (raw_height < height)
1222       raw_height = height;
1223     if (raw_width < width)
1224       raw_width = width;
1225   }
1226   if (!tiff_bps)
1227     tiff_bps = 12;
1228   if (!maximum)
1229   {
1230     maximum = (1 << tiff_bps) - 1;
1231     if (maximum < 0x10000 && curve[maximum] > 0 &&
1232         load_raw == &LibRaw::sony_arw2_load_raw)
1233       maximum = curve[maximum];
1234   }
1235   if (maximum > 0xffff)
1236     maximum = 0xffff;
1237   if (!load_raw || height < 22 || width < 22 ||
1238       (tiff_bps > 16 &&
1239        (load_raw != &LibRaw::deflate_dng_load_raw &&
1240         load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) ||
1241       tiff_samples > 6 || colors > 4)
1242     is_raw = 0;
1243 
1244   if (raw_width < 22 || raw_width > 64000 || raw_height < 22 ||
1245       pixel_aspect < 0.1 || pixel_aspect > 10. ||
1246       raw_height > 64000)
1247     is_raw = 0;
1248    if(raw_width <= left_margin || raw_height <= top_margin)
1249        is_raw = 0;
1250    if (dng_version && (tiff_samples < 1 || tiff_samples > 4))
1251        is_raw = 0; // we do not handle DNGs with more than 4 values per pixel
1252 
1253 #ifdef LIBRAW_OLD_VIDEO_SUPPORT
1254 #ifdef NO_JASPER
1255   if (load_raw == &LibRaw::redcine_load_raw)
1256   {
1257     is_raw = 0;
1258     imgdata.process_warnings |= LIBRAW_WARN_NO_JASPER;
1259   }
1260 #endif
1261 #endif
1262 #ifdef NO_JPEG
1263   if (load_raw == &LibRaw::kodak_jpeg_load_raw ||
1264       load_raw == &LibRaw::lossy_dng_load_raw)
1265   {
1266     is_raw = 0;
1267     imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
1268   }
1269 #endif
1270   if (!cdesc[0])
1271     strcpy(cdesc, colors == 3 ? "RGBG" : "GMCY");
1272   if (!raw_height)
1273     raw_height = height;
1274   if (!raw_width)
1275     raw_width = width;
1276   if (filters > 999 && colors == 3)
1277     filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) &
1278                filters << 1;
1279 notraw:
1280   if (flip == (int)UINT_MAX)
1281     flip = tiff_flip;
1282   if (flip == (int)UINT_MAX)
1283     flip = 0;
1284 
1285   // Convert from degrees to bit-field if needed
1286   if (flip > 89 || flip < -89)
1287   {
1288     switch ((flip + 3600) % 360)
1289     {
1290     case 270:
1291       flip = 5;
1292       break;
1293     case 180:
1294       flip = 3;
1295       break;
1296     case 90:
1297       flip = 6;
1298       break;
1299     }
1300   }
1301 
1302   if (pana_bpp)
1303     imgdata.color.raw_bps = pana_bpp;
1304   else if ((load_raw == &LibRaw::phase_one_load_raw) ||
1305            (load_raw == &LibRaw::phase_one_load_raw_s) ||
1306            (load_raw == &LibRaw::phase_one_load_raw_c))
1307     imgdata.color.raw_bps = ph1.format;
1308   else
1309     imgdata.color.raw_bps = tiff_bps;
1310 
1311   RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1312 }
1313 
1314 void LibRaw::identify_process_dng_fields()
1315 {
1316     if (!dng_version) return;
1317 
1318     // Cleanup inset_crops if set by makernotes parser
1319     imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[0].ctop =
1320         imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff;
1321     imgdata.sizes.raw_inset_crops[0].cwidth = imgdata.sizes.raw_inset_crops[0].cheight =
1322         imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[1].cheight = 0;
1323 
1324 
1325     int c;
1326     {
1327         /* copy DNG data from per-IFD field to color.dng */
1328         int iifd = find_ifd_by_offset(data_offset);
1329         int pifd = find_ifd_by_offset(thumb_offset);
1330 
1331 
1332 #define IFDCOLORINDEX(ifd, subset, bit)                                        \
1333   (tiff_ifd[ifd].dng_color[subset].parsedfields & bit)                         \
1334       ? ifd                                                                    \
1335       : ((tiff_ifd[0].dng_color[subset].parsedfields & bit) ? 0 : -1)
1336 
1337 #define IFDLEVELINDEX(ifd, bit)                                                \
1338   (tiff_ifd[ifd].dng_levels.parsedfields & bit)                                \
1339       ? ifd                                                                    \
1340       : ((tiff_ifd[0].dng_levels.parsedfields & bit) ? 0 : -1)
1341 
1342 #define COPYARR(to, from) memmove(&to, &from, sizeof(from))
1343 
1344         if (iifd < (int)tiff_nifds && iifd >= 0)
1345         {
1346             int sidx;
1347             // Per field, not per structure
1348             if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT))
1349             {
1350                 int illidx[2], cmidx[2], calidx[2], abidx;
1351                 for (int i = 0; i < 2; i++)
1352                 {
1353                     illidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_ILLUMINANT);
1354                     cmidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_COLORMATRIX);
1355                     calidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_CALIBRATION);
1356                 }
1357                 abidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE);
1358                 // Data found, all in same ifd, illuminants are inited
1359                 if (illidx[0] >= 0 && illidx[0] < (int)tiff_nifds &&
1360                     illidx[0] == illidx[1] && illidx[0] == cmidx[0] &&
1361                     illidx[0] == cmidx[1] &&
1362                     tiff_ifd[illidx[0]].dng_color[0].illuminant > 0 &&
1363                     tiff_ifd[illidx[0]].dng_color[1].illuminant > 0)
1364                 {
1365                     sidx = illidx[0]; // => selected IFD
1366                     double cc[4][4], cm[4][3], cam_xyz[4][3];
1367                     // CM -> Color Matrix
1368                     // CC -> Camera calibration
1369                     for (int j = 0; j < 4; j++)
1370                         for (int i = 0; i < 4; i++)
1371                             cc[j][i] = i == j;
1372                     int colidx = -1;
1373 
1374                     // IS D65 here?
1375                     for (int i = 0; i < 2; i++)
1376                     {
1377                         if (tiff_ifd[sidx].dng_color[i].illuminant == LIBRAW_WBI_D65)
1378                         {
1379                             colidx = i;
1380                             break;
1381                         }
1382                     }
1383 
1384                     // Other daylight-type ill
1385                     if (colidx < 0)
1386                         for (int i = 0; i < 2; i++)
1387                         {
1388                             int ill = tiff_ifd[sidx].dng_color[i].illuminant;
1389                             if (ill == LIBRAW_WBI_Daylight || ill == LIBRAW_WBI_D55 ||
1390                                 ill == LIBRAW_WBI_D75 || ill == LIBRAW_WBI_D50 ||
1391                                 ill == LIBRAW_WBI_Flash)
1392                             {
1393                                 colidx = i;
1394                                 break;
1395                             }
1396                         }
1397                     if (colidx >= 0) // Selected
1398                     {
1399                         // Init camera matrix from DNG
1400                         FORCC for (int j = 0; j < 3; j++) cm[c][j] =
1401                             tiff_ifd[sidx].dng_color[colidx].colormatrix[c][j];
1402 
1403                         if (calidx[colidx] == sidx)
1404                         {
1405                             for (int i = 0; i < colors && i < 4; i++)
1406                                 FORCC
1407                                 cc[i][c] = tiff_ifd[sidx].dng_color[colidx].calibration[i][c];
1408                         }
1409 
1410                         if (abidx == sidx)
1411                             for (int i = 0; i < colors && i < 4; i++)
1412                                 FORCC cc[i][c] *= tiff_ifd[sidx].dng_levels.analogbalance[i];
1413                         int j;
1414                         FORCC for (int i = 0; i < 3; i++)
1415                             for (cam_xyz[c][i] = j = 0; j < colors && j < 4; j++)
1416                                 cam_xyz[c][i] +=
1417                                     cc[c][j] * cm[j][i]; // add AsShotXY later * xyz[i];
1418                         cam_xyz_coeff(cmatrix, cam_xyz);
1419                     }
1420                 }
1421             }
1422 
1423             bool noFujiDNGCrop = makeIs(LIBRAW_CAMERAMAKER_Fujifilm)
1424                 && (!strcmp(normalized_model, "S3Pro")
1425                     || !strcmp(normalized_model, "S5Pro")
1426                     || !strcmp(normalized_model, "S2Pro"));
1427 
1428             if (!noFujiDNGCrop) // Promote DNG Crops to raw_inset_crops
1429             {
1430                 sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPORIGIN);
1431                 int sidx2 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPSIZE);
1432                 if (sidx >= 0 && sidx == sidx2 &&
1433                     tiff_ifd[sidx].dng_levels.default_crop[2] > 0 &&
1434                     tiff_ifd[sidx].dng_levels.default_crop[3] > 0)
1435                 {
1436                     int lm = tiff_ifd[sidx].dng_levels.default_crop[0];
1437                     int tm = tiff_ifd[sidx].dng_levels.default_crop[1];
1438                     int ww = tiff_ifd[sidx].dng_levels.default_crop[2];
1439                     int hh = tiff_ifd[sidx].dng_levels.default_crop[3];
1440                     if ((lm + ww < int(raw_width) + int(left_margin))
1441                         && (tm + hh < int(raw_height) + int(top_margin))) // Crop data is correct
1442                     {
1443                         imgdata.sizes.raw_inset_crops[0].cleft = left_margin + lm;
1444                         imgdata.sizes.raw_inset_crops[0].cwidth = ww;
1445                         imgdata.sizes.raw_inset_crops[0].ctop = top_margin + tm;
1446                         imgdata.sizes.raw_inset_crops[0].cheight = hh;
1447 
1448                         int sidx3 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_USERCROP);
1449                         if (sidx3 >= 0 && sidx3 == sidx) // No need to check values range, it is checked at parse
1450                         {
1451                             int dt = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[0]);
1452                             int dl = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[1]);
1453                             int db = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[2]);
1454                             int dr = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[3]);
1455 
1456                             int dh = db - dt;
1457                             int dw = dr - dl;
1458 
1459                             if (dh > 0 && dw > 0
1460                                 && dh < imgdata.sizes.raw_inset_crops[0].cheight // No need to repeat crop for 0,0,1,1
1461                                 && dw < imgdata.sizes.raw_inset_crops[0].cwidth)
1462                             {
1463                                 imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dl;
1464                                 imgdata.sizes.raw_inset_crops[1].cwidth = dw;
1465                                 imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dt;
1466                                 imgdata.sizes.raw_inset_crops[1].cheight = dh;
1467                             }
1468                         }
1469 
1470                     }
1471                 }
1472             }
1473             if (!(imgdata.color.dng_color[0].parsedfields &
1474                 LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes)
1475             {
1476                 sidx = IFDCOLORINDEX(iifd, 0, LIBRAW_DNGFM_FORWARDMATRIX);
1477                 if (sidx >= 0)
1478                     COPYARR(imgdata.color.dng_color[0].forwardmatrix,
1479                         tiff_ifd[sidx].dng_color[0].forwardmatrix);
1480             }
1481             if (!(imgdata.color.dng_color[1].parsedfields &
1482                 LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes)
1483             {
1484                 sidx = IFDCOLORINDEX(iifd, 1, LIBRAW_DNGFM_FORWARDMATRIX);
1485                 if (sidx >= 0)
1486                     COPYARR(imgdata.color.dng_color[1].forwardmatrix,
1487                         tiff_ifd[sidx].dng_color[1].forwardmatrix);
1488             }
1489             for (int ss = 0; ss < 2; ss++)
1490             {
1491                 sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_COLORMATRIX);
1492                 if (sidx >= 0)
1493                     COPYARR(imgdata.color.dng_color[ss].colormatrix,
1494                         tiff_ifd[sidx].dng_color[ss].colormatrix);
1495 
1496                 sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_CALIBRATION);
1497                 if (sidx >= 0)
1498                     COPYARR(imgdata.color.dng_color[ss].calibration,
1499                         tiff_ifd[sidx].dng_color[ss].calibration);
1500 
1501                 sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_ILLUMINANT);
1502                 if (sidx >= 0)
1503                     imgdata.color.dng_color[ss].illuminant =
1504                     tiff_ifd[sidx].dng_color[ss].illuminant;
1505             }
1506             // Levels
1507             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE);
1508             if (sidx >= 0)
1509                 COPYARR(imgdata.color.dng_levels.analogbalance,
1510                     tiff_ifd[sidx].dng_levels.analogbalance);
1511 
1512             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BASELINEEXPOSURE);
1513             if (sidx >= 0)
1514                 imgdata.color.dng_levels.baseline_exposure =
1515                 tiff_ifd[sidx].dng_levels.baseline_exposure;
1516 
1517             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_WHITE);
1518             if (sidx >= 0 && tiff_ifd[sidx].dng_levels.dng_whitelevel[0])
1519                 COPYARR(imgdata.color.dng_levels.dng_whitelevel,
1520                     tiff_ifd[sidx].dng_levels.dng_whitelevel);
1521             else if (tiff_ifd[iifd].sample_format <= 2 && tiff_ifd[iifd].bps > 0 && tiff_ifd[iifd].bps < 32)
1522                 FORC4
1523                 imgdata.color.dng_levels.dng_whitelevel[c] = (1 << tiff_ifd[iifd].bps) - 1;
1524 
1525 
1526 
1527             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ASSHOTNEUTRAL);
1528             if (sidx >= 0)
1529             {
1530                 COPYARR(imgdata.color.dng_levels.asshotneutral,
1531                     tiff_ifd[sidx].dng_levels.asshotneutral);
1532                 if (imgdata.color.dng_levels.asshotneutral[0])
1533                 {
1534                     cam_mul[3] = 0;
1535                     FORCC
1536                         if (fabs(imgdata.color.dng_levels.asshotneutral[c]) > 0.0001)
1537                             cam_mul[c] = 1 / imgdata.color.dng_levels.asshotneutral[c];
1538                 }
1539             }
1540             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BLACK);
1541             if (sidx >= 0)
1542             {
1543                 imgdata.color.dng_levels.dng_fblack =
1544                     tiff_ifd[sidx].dng_levels.dng_fblack;
1545                 imgdata.color.dng_levels.dng_black =
1546                     tiff_ifd[sidx].dng_levels.dng_black;
1547                 COPYARR(imgdata.color.dng_levels.dng_cblack,
1548                     tiff_ifd[sidx].dng_levels.dng_cblack);
1549                 COPYARR(imgdata.color.dng_levels.dng_fcblack,
1550                     tiff_ifd[sidx].dng_levels.dng_fcblack);
1551             }
1552 
1553 
1554             if (pifd >= 0)
1555             {
1556                 sidx = IFDLEVELINDEX(pifd, LIBRAW_DNGFM_PREVIEWCS);
1557                 if (sidx >= 0)
1558                     imgdata.color.dng_levels.preview_colorspace =
1559                     tiff_ifd[sidx].dng_levels.preview_colorspace;
1560             }
1561             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_OPCODE2);
1562             if (sidx >= 0)
1563                 meta_offset = tiff_ifd[sidx].opcode2_offset;
1564 
1565             sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINTABLE);
1566             INT64 linoff = -1;
1567             int linlen = 0;
1568             if (sidx >= 0)
1569             {
1570                 linoff = tiff_ifd[sidx].lineartable_offset;
1571                 linlen = tiff_ifd[sidx].lineartable_len;
1572             }
1573 
1574             if (linoff >= 0 && linlen > 0)
1575             {
1576                 INT64 pos = ftell(ifp);
1577                 fseek(ifp, linoff, SEEK_SET);
1578                 linear_table(linlen);
1579                 fseek(ifp, pos, SEEK_SET);
1580             }
1581             // Need to add curve too
1582         }
1583         /* Copy DNG black level to LibRaw's */
1584         if (load_raw == &LibRaw::lossy_dng_load_raw)
1585         {
1586             maximum = 0xffff;
1587             FORC4 imgdata.color.linear_max[c] = imgdata.color.dng_levels.dng_whitelevel[c] = 0xffff;
1588         }
1589         else
1590         {
1591             maximum = imgdata.color.dng_levels.dng_whitelevel[0];
1592         }
1593         black = imgdata.color.dng_levels.dng_black;
1594         if (tiff_samples == 2 &&
1595             !imgdata.color.dng_levels.dng_cblack[2] &&
1596             !imgdata.color.dng_levels.dng_cblack[3] &&
1597             (imgdata.color.dng_levels.dng_cblack[4] == 1) &&
1598             (imgdata.color.dng_levels.dng_cblack[5] == 1)
1599             && (imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] == tiff_samples)
1600             ) {
1601           black = imgdata.color.dng_levels.dng_cblack[shot_select];
1602           imgdata.color.dng_levels.dng_cblack[0] = imgdata.color.dng_levels.dng_cblack[1] = 0;
1603           imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1604           imgdata.color.dng_levels.dng_fcblack[0] = imgdata.color.dng_levels.dng_fcblack[1] = 0.0f;
1605           imgdata.color.dng_levels.dng_fcblack[4] = imgdata.color.dng_levels.dng_fcblack[5] = 0.0f;
1606         }
1607         else if (tiff_samples == 2 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples
1608             == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1])
1609         {
1610             unsigned ff = filters;
1611             if (filters > 999 && colors == 3)
1612                 filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) &
1613                 filters << 1;
1614 
1615             /* Special case, Fuji SuperCCD dng */
1616             int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 };
1617             int i = 6 + shot_select;
1618             for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++)
1619                 for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++)
1620                 {
1621                     csum[FC(row, col)] += imgdata.color.dng_levels.dng_cblack[i];
1622                     ccount[FC(row, col)]++;
1623                     i += tiff_samples;
1624                 }
1625             for (int q = 0; q < 4; q++)
1626                 if (ccount[q])
1627                     imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q];
1628             imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1629             filters = ff;
1630         }
1631         else if (tiff_samples > 2 && tiff_samples <= 4 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples
1632             == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1])
1633         {
1634             /* Special case, per_channel blacks in RepeatDim, average for per-channel */
1635             int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 };
1636             int i = 6;
1637             for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++)
1638                 for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++)
1639                     for (unsigned q = 0; q < tiff_samples && q < 4; q++)
1640                     {
1641                         csum[q] += imgdata.color.dng_levels.dng_cblack[i];
1642                         ccount[q]++;
1643                         i++;
1644                     }
1645             for (int q = 0; q < 4; q++)
1646                 if (ccount[q])
1647                     imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q];
1648             imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1649         }
1650 
1651         memmove(cblack, imgdata.color.dng_levels.dng_cblack, sizeof(cblack));
1652 
1653         if (iifd < (int)tiff_nifds && iifd >= 0)
1654         {
1655             int sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINEARRESPONSELIMIT);
1656             if (sidx >= 0)
1657             {
1658                 imgdata.color.dng_levels.LinearResponseLimit =
1659                     tiff_ifd[sidx].dng_levels.LinearResponseLimit;
1660                 if (imgdata.color.dng_levels.LinearResponseLimit > 0.1 &&
1661                     imgdata.color.dng_levels.LinearResponseLimit <= 1.0)
1662                 {
1663                     // And approx promote it to linear_max:
1664                     int bl4 = 0, bl64 = 0;
1665                     for (int chan = 0; chan < colors && chan < 4; chan++)
1666                         bl4 += cblack[chan];
1667                     bl4 /= LIM(colors, 1, 4);
1668 
1669                     if (cblack[4] * cblack[5] > 0)
1670                     {
1671                         unsigned cnt = 0;
1672                         for (unsigned q = 0; q < 4096 && q < cblack[4] * cblack[5]; q++)
1673                         {
1674                             bl64 += cblack[q + 6];
1675                             cnt++;
1676                         }
1677                         bl64 /= LIM(cnt, 1, 4096);
1678                     }
1679                     int rblack = black + bl4 + bl64;
1680                     for (int chan = 0; chan < colors && chan < 4; chan++)
1681                         imgdata.color.linear_max[chan] =
1682                             (maximum - rblack) *
1683                             imgdata.color.dng_levels.LinearResponseLimit +
1684                             rblack;
1685                     if (imgdata.color.linear_max[1] && !imgdata.color.linear_max[3])
1686                         imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
1687                 }
1688             }
1689         }
1690     }
1691 }
1692 
1693 void LibRaw::identify_finetune_pentax()
1694 {
1695     if (dng_version && data_offset)
1696     {
1697         for(int i = 0; i < (int)tiff_nifds; i++)
1698             if (tiff_ifd[i].offset == data_offset)
1699             {
1700                 if (tiff_ifd[i].phint == 34892) return; // Linear DNG made from Pentax source
1701                 break;
1702             }
1703     }
1704 
1705     if (makeIs(LIBRAW_CAMERAMAKER_Pentax) ||
1706         makeIs(LIBRAW_CAMERAMAKER_Samsung)) {
1707         if (height == 2624 &&
1708             width == 3936) // Pentax K10D, Samsung GX10;
1709         {
1710             height = 2616;
1711             width = 3896;
1712         }
1713         if (height == 3136 &&
1714             width == 4864) // Pentax K20D, Samsung GX20;
1715         {
1716             height = 3124;
1717             width = 4688;
1718             filters = 0x16161616;
1719         }
1720     }
1721 
1722     if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) {
1723         if ((width == 4352) &&
1724             ((unique_id == PentaxID_K_r) ||
1725             (unique_id == PentaxID_K_x)))
1726         {
1727             width = 4309;
1728             filters = 0x16161616;
1729         }
1730         if ((width >= 4960) &&
1731             ((unique_id == PentaxID_K_5) ||
1732             (unique_id == PentaxID_K_5_II) ||
1733                 (unique_id == PentaxID_K_5_II_s)))
1734         {
1735             left_margin = 10;
1736             width = 4950;
1737             filters = 0x16161616;
1738         }
1739         if ((width == 6080) && (unique_id == PentaxID_K_70))
1740         {
1741             height = 4016;
1742             top_margin = 32;
1743             width = 6020;
1744             left_margin = 60;
1745         }
1746         if ((width == 4736) && (unique_id == PentaxID_K_7))
1747         {
1748             height = 3122;
1749             width = 4684;
1750             filters = 0x16161616;
1751             top_margin = 2;
1752         }
1753         if ((width == 6080) && (unique_id == PentaxID_K_3_II))
1754         {
1755             left_margin = 4;
1756             width = 6040;
1757         }
1758         if ((width == 6304) && (unique_id == PentaxID_K_3_III)) // From DNG ActiveArea
1759         {
1760           left_margin = 26;
1761           width = 6224;
1762           top_margin = 34;
1763           height = 4160;
1764         }
1765         if ((width == 6112) && (unique_id == PentaxID_KP))
1766         {
1767             // From DNG, maybe too strict
1768             left_margin = 54;
1769             top_margin = 28;
1770             width = 6028;
1771             height = raw_height - top_margin;
1772         }
1773         if ((width == 6080) && (unique_id == PentaxID_K_3))
1774         {
1775             left_margin = 4;
1776             width = 6040;
1777         }
1778         if ((width == 7424) && (unique_id == PentaxID_645D))
1779         {
1780             height = 5502;
1781             width = 7328;
1782             filters = 0x61616161;
1783             top_margin = 29;
1784             left_margin = 48;
1785         }
1786     }
1787     else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) &&
1788         (height == 3014) && (width == 4096))  // Ricoh GX200
1789         width = 4014;
1790 }
1791 
1792 void LibRaw::identify_finetune_by_filesize(int fsize)
1793 {
1794 
1795     if (fsize == 4771840)
1796     { // hack Nikon 3mpix: E880, E885, E990, E995;
1797       // Olympus C-3030Z
1798         if (!timestamp && nikon_e995())
1799             strcpy(model, "E995");
1800     }
1801     else if (fsize == 2940928)
1802     { // hack Nikon 2mpix: E2100, E2500
1803         if (!timestamp && !nikon_e2100())
1804             strcpy(model, "E2500");
1805     }
1806     else if (fsize == 4775936)
1807     { // hack Nikon 3mpix: E3100, E3200, E3500, E3700;
1808       // Pentax "Optio 33WR";
1809       // Olympus C-740UZ
1810         if (!timestamp)
1811             nikon_3700();
1812     }
1813     else if (fsize == 5869568)
1814     { // hack Nikon 4mpix: E4300;
1815       // hack Minolta "DiMAGE Z2"
1816         if (!timestamp && minolta_z2())
1817         {
1818             maker_index = LIBRAW_CAMERAMAKER_Minolta;
1819             strcpy(make, "Minolta");
1820             strcpy(model, "DiMAGE Z2");
1821         }
1822     }
1823 }
1824 
1825 void LibRaw::identify_finetune_dcr(char head[64], int fsize, int flen)
1826 {
1827     static const short pana[][6] = {
1828         // raw_width, raw_height, left_margin, top_margin, width_increment,
1829         // height_increment
1830         {3130, 1743, 4, 0, -6, 0},      /* 00 */
1831         {3130, 2055, 4, 0, -6, 0},      /* 01 */
1832         {3130, 2319, 4, 0, -6, 0},      /* 02 DMC-FZ8 */
1833         {3170, 2103, 18, 0, -42, 20},   /* 03 */
1834         {3170, 2367, 18, 13, -42, -21}, /* 04 */
1835         {3177, 2367, 0, 0, -1, 0},      /* 05 DMC-L1 */
1836         {3304, 2458, 0, 0, -1, 0},      /* 06 DMC-FZ30 */
1837         {3330, 2463, 9, 0, -5, 0},      /* 07 DMC-FZ18 */
1838         {3330, 2479, 9, 0, -17, 4},     /* 08 */
1839         {3370, 1899, 15, 0, -44, 20},   /* 09 */
1840         {3370, 2235, 15, 0, -44, 20},   /* 10 */
1841         {3370, 2511, 15, 10, -44, -21}, /* 11 */
1842         {3690, 2751, 3, 0, -8, -3},     /* 12 DMC-FZ50 */
1843         {3710, 2751, 0, 0, -3, 0},      /* 13 DMC-L10 */
1844         {3724, 2450, 0, 0, 0, -2},      /* 14 */
1845         {3770, 2487, 17, 0, -44, 19},   /* 15 */
1846         {3770, 2799, 17, 15, -44, -19}, /* 16 */
1847         {3880, 2170, 6, 0, -6, 0},      /* 17 DMC-LX1 */
1848         {4060, 3018, 0, 0, 0, -2},      /* 18 DMC-FZ35, DMC-FZ38 */
1849         {4290, 2391, 3, 0, -8, -1},     /* 19 DMC-LX2 */
1850         {4330, 2439, 17, 15, -44, -19}, /* 20 "D-LUX 3" */
1851         {4508, 2962, 0, 0, -3, -4},     /* 21 */
1852         {4508, 3330, 0, 0, -3, -6},     /* 22 */
1853         {10480, 7794, 0, 0, -2, 0},     /* 23: G9 in high-res */
1854     };
1855     int i,c;
1856     struct jhead jh;
1857 
1858     if (makeIs(LIBRAW_CAMERAMAKER_Canon) 
1859         && ( !tiff_flip || unique_id == CanonID_EOS_40D)
1860         && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION)
1861         && imCanon.MakernotesFlip)
1862     {
1863         tiff_flip = imCanon.MakernotesFlip;
1864     }
1865 
1866     else if (makeIs(LIBRAW_CAMERAMAKER_Nikon))
1867     {
1868         if (!load_raw)
1869             load_raw = &LibRaw::packed_load_raw;
1870         if (model[0] == 'E') // Nikon E8800, E8700, E8400, E5700, E5400, E5000,
1871                              // others are diag hacks?
1872             load_flags |= !data_offset << 2 | 2;
1873     }
1874     /* Set parameters based on camera name (for non-DNG files). */
1875 
1876     /* Always 512 for arw2_load_raw */
1877     else if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
1878         (raw_width > 3888) && !black && !cblack[0])
1879     {
1880         black = (load_raw == &LibRaw::sony_arw2_load_raw)
1881             ? 512
1882             : (128 << (tiff_bps - 12));
1883     }
1884 
1885     if (is_foveon) {
1886         if (height * 2 < width)
1887             pixel_aspect = 0.5;
1888         if (height > width)
1889             pixel_aspect = 2;
1890         filters = 0;
1891 
1892     }
1893     else if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) {
1894         if ((unique_id == PentaxID_K_1) ||
1895             (unique_id == PentaxID_K_1_Mark_II)) {
1896             top_margin = 18;
1897             height = raw_height - top_margin;
1898             if (raw_width == 7392) {
1899                 left_margin = 6;
1900                 width = 7376;
1901             }
1902 
1903         }
1904         else if (unique_id == PentaxID_Optio_S_V101) { // (fsize == 3178560)
1905             cam_mul[0] *= 4;
1906             cam_mul[2] *= 4;
1907 
1908         }
1909         else if (unique_id == PentaxID_Optio_33WR) { // (fsize == 4775936)
1910             flip = 1;
1911             filters = 0x16161616;
1912 
1913         }
1914         else if (unique_id == PentaxID_staristD) {
1915             load_raw = &LibRaw::unpacked_load_raw;
1916             /* data_error = -1; */ /* No way to know why data_error was raised in dcraw.c, looks not needed esp. for unpacked_load_raw */
1917         }
1918         else if (unique_id == PentaxID_staristDS) {
1919             height -= 2;
1920         }
1921 
1922     }
1923     else if (makeIs(LIBRAW_CAMERAMAKER_Canon)) {
1924         if (tiff_bps == 15) { // Canon sRAW
1925             if (width == 3344)
1926                 width = 3272;
1927             else if (width == 3872)
1928                 width = 3866;
1929 
1930             if (height > width) {
1931                 SWAP(height, width);
1932                 SWAP(raw_height, raw_width);
1933             }
1934             if (width == 7200 &&
1935                 height == 3888) { // Canon EOS 5DS (R);
1936                 raw_width = width = 6480;
1937                 raw_height = height = 4320;
1938             }
1939             filters = 0;
1940             tiff_samples = colors = 3;
1941             load_raw = &LibRaw::canon_sraw_load_raw;
1942         }
1943 
1944         if (!strcmp(normalized_model, "PowerShot 600")) {
1945             height = 613;
1946             width = 854;
1947             raw_width = 896;
1948             colors = 4;
1949             filters = 0xe1e4e1e4;
1950             load_raw = &LibRaw::canon_600_load_raw;
1951 
1952         }
1953         else if (!strcmp(normalized_model, "PowerShot A5") ||
1954             !strcmp(normalized_model, "PowerShot A5 Zoom")) {
1955             height = 773;
1956             width = 960;
1957             raw_width = 992;
1958             pixel_aspect = 256 / 235.0;
1959             filters = 0x1e4e1e4e;
1960             goto canon_a5;
1961 
1962         }
1963         else if (!strcmp(normalized_model, "PowerShot A50")) {
1964             height = 968;
1965             width = 1290;
1966             raw_width = 1320;
1967             filters = 0x1b4e4b1e;
1968             goto canon_a5;
1969 
1970         }
1971         else if (!strcmp(normalized_model, "PowerShot Pro70")) {
1972             height = 1024;
1973             width = 1552;
1974             filters = 0x1e4b4e1b;
1975         canon_a5:
1976             colors = 4;
1977             tiff_bps = 10;
1978             load_raw = &LibRaw::packed_load_raw;
1979             load_flags = 40;
1980 
1981         }
1982         else if (!strcmp(normalized_model, "PowerShot Pro90 IS") ||
1983             !strcmp(normalized_model, "PowerShot G1")) {
1984             colors = 4;
1985             filters = 0xb4b4b4b4;
1986 
1987         }
1988         else if (!strcmp(normalized_model, "PowerShot A610")) { // chdk hack
1989             if (canon_s2is()) {
1990                 strcpy(model + 10, "S2 IS");
1991                 strcpy(normalized_model + 10, "S2 IS");
1992             }
1993 
1994         }
1995         else if (!strcmp(normalized_model, "PowerShot SX220 HS")) { // chdk hack
1996             mask[1][3] = -4;
1997             top_margin = 16;
1998             left_margin = 92;
1999 
2000         }
2001         else if (!strcmp(normalized_model, "PowerShot S120")) { // chdk hack
2002             raw_width = 4192;
2003             raw_height = 3062;
2004             width = 4022;
2005             height = 3016;
2006             mask[0][0] = top_margin = 31;
2007             mask[0][2] = top_margin + height;
2008             left_margin = 120;
2009             mask[0][1] = 23;
2010             mask[0][3] = 72;
2011 
2012         }
2013         else if (!strcmp(normalized_model, "PowerShot G16")) {
2014             mask[0][0] = 0;
2015             mask[0][2] = 80;
2016             mask[0][1] = 0;
2017             mask[0][3] = 16;
2018             top_margin = 29;
2019             left_margin = 120;
2020             width = raw_width - left_margin - 48;
2021             height = raw_height - top_margin - 14;
2022 
2023         }
2024         else if (!strcmp(normalized_model, "PowerShot SX50 HS")) {
2025             top_margin = 17;
2026         }
2027 
2028     }
2029 
2030     else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) {
2031         if (!strcmp(model, "D1"))
2032         {
2033             imgdata.other.analogbalance[0] = cam_mul[0];
2034             imgdata.other.analogbalance[2] = cam_mul[2];
2035             imgdata.other.analogbalance[1] = imgdata.other.analogbalance[3] =
2036                 cam_mul[1];
2037             cam_mul[0] = cam_mul[1] = cam_mul[2] = 1.0f;
2038         }
2039 
2040         else if (!strcmp(model, "D1X"))
2041         {
2042             width -= 4;
2043             pixel_aspect = 0.5;
2044         }
2045         else if (!strcmp(model, "D40X") ||
2046             !strcmp(model, "D60") ||
2047             !strcmp(model, "D80") ||
2048             !strcmp(model, "D3000"))
2049         {
2050             height -= 3;
2051             width -= 4;
2052         }
2053         else if (!strcmp(model, "D3") ||
2054             !strcmp(model, "D3S") ||
2055             !strcmp(model, "D700"))
2056         {
2057             width -= 4;
2058             left_margin = 2;
2059         }
2060         else if (!strcmp(model, "D3100"))
2061         {
2062             width -= 28;
2063             left_margin = 6;
2064         }
2065         else if (!strcmp(model, "D5000") ||
2066             !strcmp(model, "D90"))
2067         {
2068             width -= 42;
2069         }
2070         else if (!strcmp(model, "D5100") ||
2071             !strcmp(model, "D7000") ||
2072             !strcmp(model, "COOLPIX A"))
2073         {
2074             width -= 44;
2075         }
2076         else if (!strcmp(model, "D3200") ||
2077             !strcmp(model, "D600") ||
2078             !strcmp(model, "D610") ||
2079             !strncmp(model, "D800", 4)) // Nikons: D800, D800E
2080         {
2081             width -= 46;
2082         }
2083         else if (!strcmp(model, "D4") ||
2084             !strcmp(model, "Df"))
2085         {
2086             width -= 52;
2087             left_margin = 2;
2088         }
2089         else if (!strcmp(model, "D500"))
2090         {
2091             // Empty - to avoid width-1 below
2092         }
2093         else if (!strncmp(model, "D40", 3) ||
2094             !strncmp(model, "D50", 3) ||
2095             !strncmp(model, "D70", 3))
2096         {
2097             width--;
2098         }
2099         else if (!strcmp(model, "D100"))
2100         {
2101             if (load_flags) // compressed NEF
2102                 raw_width = (width += 3) + 3;
2103         }
2104         else if (!strcmp(model, "D200"))
2105         {
2106             left_margin = 1;
2107             width -= 4;
2108             filters = 0x94949494;
2109         }
2110         else if (!strncmp(model, "D2H", 3)) // Nikons: D2H, D2Hs
2111         {
2112             left_margin = 6;
2113             width -= 14;
2114         }
2115         else if (!strncmp(model, "D2X", 3)) // Nikons: D2X, D2Xs
2116         {
2117             if (width == 3264) // in-camera Hi-speed crop: On
2118                 width -= 32;
2119             else
2120                 width -= 8;
2121         }
2122         else if (!strncmp(model, "D300", 4)) // Nikons: D300, D300s
2123         {
2124             width -= 32;
2125         }
2126         else if (raw_width == 4032) // Nikon "COOLPIX P7700", "COOLPIX P7800",
2127                                     // "COOLPIX P330", "COOLPIX P340"
2128         {
2129             if (!strcmp(normalized_model, "COOLPIX P7700"))
2130             {
2131                 maximum = 65504;
2132                 load_flags = 0;
2133             }
2134             else if (!strcmp(normalized_model, "COOLPIX P7800"))
2135             {
2136                 maximum = 65504;
2137                 load_flags = 0;
2138             }
2139             else if (!strcmp(model, "COOLPIX P340"))
2140             {
2141                 load_flags = 0;
2142             }
2143         }
2144         else if (!strncmp(model, "COOLPIX P", 9) &&
2145             raw_width != 4032) // Nikon "COOLPIX P1000", "COOLPIX P6000",
2146                                // "COOLPIX P7000", "COOLPIX P7100"
2147         {
2148             load_flags = 24;
2149             filters = 0x94949494;
2150             /* the following 'if' is most probably obsolete, because we now read black
2151              * level from metadata */
2152             if ((model[9] == '7') && /* P7000, P7100 */
2153                 ((iso_speed >= 400) || (iso_speed == 0)) &&
2154                 !strstr(software, "V1.2")) /* v. 1.2 seen for P7000 only */
2155                 black = 255;
2156         }
2157         else if (!strncmp(model, "COOLPIX B700", 12))
2158         {
2159             load_flags = 24;
2160         }
2161         else if (!strncmp(model, "1 ",
2162             2)) // Nikons: "1 AW1", "1 J1", "1 J2", "1 J3", "1 J4",
2163                 // "1 J5", "1 S1", "1 S2", "1 V1", "1 V2", "1 V3"
2164         {
2165             height -= 2;
2166         }
2167         else if (fsize == 1581060) // hack Nikon 1mpix: E900
2168         {
2169             simple_coeff(3);
2170             pre_mul[0] = 1.2085f;
2171             pre_mul[1] = 1.0943f;
2172             pre_mul[3] = 1.1103f;
2173         }
2174         else if ((fsize == 4771840) &&  // hack Nikon 3mpix: E880, E885, E990
2175             strcmp(model, "E995")) // but not E995
2176         {
2177             filters = 0xb4b4b4b4;
2178             simple_coeff(3);
2179             pre_mul[0] = 1.196f;
2180             pre_mul[1] = 1.246f;
2181             pre_mul[2] = 1.018f;
2182         }
2183         else if ((fsize == 4775936) && // hack Nikon 3mpix: E3100, E3200, E3500
2184             (atoi(model + 1) < 3700)) // but not E3700;
2185         {
2186             filters = 0x49494949;
2187         }
2188         else if (fsize == 5869568) // hack Nikon 4mpix: E4300;
2189         {
2190             load_flags = 6;
2191         }
2192         else if (!strcmp(model, "E2500"))
2193         {
2194             height -= 2;
2195             load_flags = 6;
2196             colors = 4;
2197             filters = 0x4b4b4b4b;
2198         }
2199     }
2200 
2201     else if (makeIs(LIBRAW_CAMERAMAKER_Olympus)) {
2202         if (OlyID == OlyID_C_740UZ) { // (fsize == 4775936)
2203             i = find_green(12, 32, 1188864, 3576832);
2204             c = find_green(12, 32, 2383920, 2387016);
2205             if (abs(i) < abs(c)) {
2206                 SWAP(i, c);
2207                 load_flags = 24;
2208             }
2209             if (i < 0)
2210                 filters = 0x61616161;
2211         }
2212         else if (OlyID == OlyID_C_770UZ) {
2213             height = 1718;
2214             width = 2304;
2215             filters = 0x16161616;
2216             load_raw = &LibRaw::packed_load_raw;
2217             load_flags = 30;
2218         }
2219         else {
2220             height += height & 1;
2221             if (exif_cfa)
2222                 filters = exif_cfa;
2223 
2224             if (width == 4100) // Olympus E-PL2, E-PL1, E-P2, E-P1, E-620, E-600, E-5, E-30;
2225                 width -= 4;
2226 
2227             if (width == 4080) // Olympus E-PM1, E-PL3, E-P3;
2228                 width -= 24;
2229 
2230             if (width == 10400) // Olympus PEN-F, E-M1-II, E-M1-III, E-M1X, OM-1
2231                 width -= 12;
2232 
2233             if (width == 8200) // E-M1-III in 50Mp mode, E-M1X
2234                 width -= 30;
2235 
2236             if (width == 8180) // OM-1 in 50Mp
2237               width -= 10;
2238 
2239             if (width == 9280) { // Olympus E-M5 Mark II;
2240                 width -= 6;
2241                 height -= 6;
2242             }
2243 
2244             if (load_raw == &LibRaw::unpacked_load_raw) {
2245                 load_flags = 4;
2246         if (imOly.ValidBits == 10) load_flags += 2;
2247             }
2248       tiff_bps = imOly.ValidBits;
2249 
2250             if ((OlyID == OlyID_E_300) ||
2251                 (OlyID == OlyID_E_500)) {
2252                 width -= 20;
2253                 if (load_raw == &LibRaw::unpacked_load_raw) {
2254                     maximum = 0xfc3;
2255                     memset(cblack, 0, sizeof cblack);
2256                 }
2257             }
2258             else if (OlyID == OlyID_STYLUS_1) {
2259                 width -= 16;
2260                 maximum = 0xfff;
2261 
2262             }
2263             else if (OlyID == OlyID_E_330) {
2264                 width -= 30;
2265                 if (load_raw == &LibRaw::unpacked_load_raw)
2266                     maximum = 0xf79;
2267 
2268             }
2269             else if (OlyID == OlyID_SP_550UZ) {
2270                 thumb_length = flen - (thumb_offset = 0xa39800);
2271                 thumb_height = 480;
2272                 thumb_width = 640;
2273 
2274             }
2275             else if (OlyID == OlyID_TG_4) {
2276                 width -= 16;
2277 
2278             }
2279             else if ((OlyID == OlyID_TG_5) ||
2280                 (OlyID == OlyID_TG_6)) {
2281                 width -= 26;
2282             }
2283         }
2284 
2285     }
2286     else if (makeIs(LIBRAW_CAMERAMAKER_RoverShot) &&
2287         (fsize == 6291456)) { // RoverShot 3320AF
2288         fseek(ifp, 0x300000, SEEK_SET);
2289         if ((order = guess_byte_order(0x10000)) == 0x4d4d)
2290         {
2291             height -= (top_margin = 16);
2292             width -= (left_margin = 28);
2293             maximum = 0xf5c0;
2294             strcpy(make, "ISG");
2295             maker_index = LIBRAW_CAMERAMAKER_ISG;
2296             model[0] = 0;
2297         }
2298 
2299     }
2300     else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) {
2301     if (!imFuji.RAFDataGeneration && (raw_width == 2944)) // S2Pro
2302         {
2303             height = 2144;
2304             width = 2880;
2305             flip = 6;
2306         }
2307         else if (load_raw != &LibRaw::packed_load_raw &&
2308                  strncmp(model, "X-", 2)              &&
2309                    filters >= 1000) // Bayer and not an X-model
2310             maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
2311 
2312     if (!FujiCropMode && imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096))
2313     {
2314       width  = imFuji.RAFData_ImageSizeTable[0];
2315       height = imFuji.RAFData_ImageSizeTable[1];
2316     }
2317         else if (FujiCropMode == 1) // FF crop on GFX
2318         {
2319             width = raw_width;
2320             height = raw_height;
2321         }
2322         // Do we need set height = raw_height for CropMode == 2 for all cameras??
2323         else if (FujiCropMode == 4) // electronic shutter, high speed mode (1.25x crop)
2324         {
2325             height = raw_height;
2326         }
2327 
2328         top_margin = (raw_height >= height) ? (raw_height - height) >> 2 << 1 : 0;
2329         left_margin = (raw_width >= width) ? (raw_width - width) >> 2 << 1 : 0;
2330 
2331     if (imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) {
2332       switch (raw_width) {
2333       case 2944:                // X-S1, X10, XF1
2334         filters = 0x16161616;
2335         break;
2336       case 4096:                // X20, X30, XQ1, XQ2
2337       case 5120:                // X-Pro1, X-E1, X-A1, X-A2, X-M1
2338       case 6048:                // lossless compressed X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3
2339       case 6160:                // uncompressed (unpacked) X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3
2340         left_margin = 0;
2341         break;
2342       case 4992:                // X-E2S, X-E2, X-T10, X-T1, X100S, X100T, X70
2343         left_margin = 4;
2344         break;
2345       case 6336: // X-H2S
2346           top_margin = 6;
2347           left_margin = 0;
2348           width = 6264;
2349           height = 4176;
2350           break;
2351       case 6384:                // X-T3, X-T4, X100V, X-S10, X-T30, X-Pro3
2352         top_margin = 0;
2353         switch (FujiCropMode) {
2354         case 0:        // no crop
2355                   left_margin = 0;
2356                   top_margin = 6;
2357                   width = 6246;
2358                   height = 4170;
2359                   break;
2360                 case 2:        // sports finder mode
2361                   left_margin = 624;
2362                   width = 5004;
2363                   height = raw_height;
2364                   break;
2365                 case 4:        // electronic shutter, high speed mode (1.25x crop)
2366           left_margin = 624;
2367                   width = 5004;
2368                   break;
2369         }
2370         break;
2371       case 6912:                // GFX 50S, GFX 50R; FF crop
2372       case 9216:                // GFX 50S, GFX 50R; no crop
2373               left_margin = 0;
2374               top_margin = 0;
2375         break;
2376       case 8472:                // GFX 50S II
2377         left_margin = 0;
2378               top_margin  = 0;
2379               width = raw_width - 192;
2380         break;
2381       case 9696:                // GFX 100; FF crop
2382       case 11808:               // GFX 100; no crop
2383               left_margin = 0;
2384               width = raw_width - 146;
2385               height = raw_height - (top_margin = 2);
2386               if (tiff_bps == 16)
2387                   maximum = 0xffff;
2388       default:
2389       /* insert model name-based width/height/margins/etc. assignments */
2390         break;
2391       }
2392 
2393     } else if (!imFuji.RAFDataGeneration) {
2394       switch (raw_width) {
2395       case 2304:                // S5100
2396         height -= (top_margin = 6);
2397         break;
2398       case 3328:                // F550EXR, F600EXR, F770EXR, F800EXR, F900EXR,
2399                                 // HS20EXR, HS30EXR, HS33EXR, HS50EXR
2400         if ((width = raw_width - 66))
2401           left_margin = 34;
2402         if (imgdata.sizes.raw_inset_crops[0].cleft == 8) // HS50EXR, F900EXR
2403         {
2404                 left_margin = 0;
2405                 width += 2;
2406                 filters = 0x16161616;
2407         }
2408         break;
2409       case 3664:                // "HS10 HS11"
2410         filters = 0x16161616;
2411         break;
2412       case 5504:                // DBP for GX680 aka DX-2000
2413 
2414 //         7712 2752 -> 5504 3856
2415 //         width = 688;
2416 //         height = 30848;
2417 //         raw_width = 688;
2418 //         raw_height = 30848;
2419 
2420         left_margin = 32; // imgdata.sizes.raw_inset_crops[0].cleft
2421         top_margin = 8;
2422         width = raw_width - 2*left_margin;
2423         height = raw_height - 2*top_margin;
2424 
2425         load_raw = &LibRaw::unpacked_load_raw_FujiDBP;
2426         //  maximum = 0x0fff;
2427         filters = 0x16161616;
2428         load_flags = 0;
2429         flip = 6;
2430         break;
2431       default:
2432       /* insert model name-based width/height/margins/etc. assignments */
2433         break;
2434       }
2435     }
2436         if (fuji_layout)
2437             raw_width *= is_raw;
2438         if (filters == 9)
2439             FORC(36)
2440             ((char *)xtrans)[c] =
2441             xtrans_abs[(c / 6 + top_margin) % 6][(c + left_margin) % 6];
2442     }
2443 
2444     else if (makeIs(LIBRAW_CAMERAMAKER_Konica)) {
2445         if (!strcmp(model, "KD-400Z")) {
2446             height = 1711; // 1712
2447             width = 2312;
2448             raw_width = 2336;
2449             goto konica_400z;
2450         }
2451         else if (!strcmp(model, "KD-510Z")) {
2452             goto konica_510z;
2453         }
2454 
2455     }
2456     else if (makeIs(LIBRAW_CAMERAMAKER_Minolta)) {
2457         if (fsize == 5869568) { // hack "DiMAGE Z2"
2458             load_flags = 30;
2459         }
2460 
2461         if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_UNPACKED) {
2462             load_raw = &LibRaw::unpacked_load_raw;
2463         } else if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_PACKED) {
2464             load_raw = &LibRaw::packed_load_raw;
2465       } else if (!load_raw && (maximum = 0xfff)) {
2466             load_raw = &LibRaw::unpacked_load_raw;
2467         }
2468 
2469       if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) {
2470             filters = 0x49494949;
2471       } else if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_RGGB) {
2472             filters = 0x94949494;
2473       }
2474 
2475       if (imSony.prd_Active_bps && imSony.prd_Total_bps) {
2476             tiff_bps = imSony.prd_Active_bps;
2477       }
2478 
2479         if (!strncmp(model, "DiMAGE G", 8)) // hack "DiMAGE G400", "DiMAGE G500",
2480                                                // "DiMAGE G530", "DiMAGE G600"
2481         {
2482             if (model[8] == '4') // DiMAGE G400
2483             {
2484                 height = 1716;
2485                 width = 2304;
2486             }
2487             else if (model[8] == '5') // DiMAGE G500 / G530
2488             {
2489             konica_510z:
2490                 height = 1956;
2491                 width = 2607;
2492                 raw_width = 2624;
2493             }
2494             else if (model[8] == '6') // DiMAGE G600
2495             {
2496                 height = 2136;
2497                 width = 2848;
2498             }
2499             data_offset += 14;
2500             filters = 0x61616161;
2501         konica_400z:
2502             load_raw = &LibRaw::unpacked_load_raw;
2503             maximum = 0x3df;
2504             order = 0x4d4d;
2505         }
2506 
2507     }
2508     else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) {
2509         if (raw_width == 4704) // Samsung NX100, NX10, NX11,
2510         {
2511             height -= top_margin = 8;
2512             width -= 2 * (left_margin = 8);
2513             load_flags = 32;
2514         }
2515         else if (!strcmp(model, "NX3000")) // Samsung NX3000; raw_width: 5600
2516         {
2517             top_margin = 38;
2518             left_margin = 92;
2519             width = 5456;
2520             height = 3634;
2521             filters = 0x61616161;
2522             colors = 3;
2523         }
2524         else if (raw_height == 3714) // Samsung NX2000, NX300M, NX300, NX30,
2525                                      // "NX U" (aka:
2526                                      //         "EK-GN100", "EK-GN110", "EK-GN120",
2527                                      //         "EK-KN120", "Galaxy NX")
2528         {
2529             height -= top_margin = 18;
2530             left_margin = raw_width - (width = 5536);
2531             if (raw_width != 5600)
2532                 left_margin = top_margin = 0;
2533             filters = 0x61616161;
2534             colors = 3;
2535         }
2536         else if (raw_width == 5632) // Samsung NX1000, NX200, NX20, NX210
2537         {
2538             order = 0x4949;
2539             height = 3694;
2540             top_margin = 2;
2541             width = 5574 - (left_margin = 32 + tiff_bps);
2542             if (tiff_bps == 12)
2543                 load_flags = 80;
2544         }
2545         else if (raw_width == 5664) // Samsung "NX mini"
2546         {
2547             height -= top_margin = 17;
2548             left_margin = 96;
2549             width = 5544;
2550             filters = 0x49494949;
2551         }
2552         else if (raw_width == 6496) // Samsung NX1, NX500
2553         {
2554             filters = 0x61616161;
2555             if (!black && !cblack[0] && !cblack[1] && !cblack[2] && !cblack[3])
2556                 black = 1 << (tiff_bps - 7);
2557         }
2558         else if (!strcmp(normalized_model, "EX1")) // Samsung EX1; raw_width: 3688
2559         {
2560             order = 0x4949;
2561             height -= 20;
2562             top_margin = 2;
2563             if ((width -= 6) > 3682)
2564             {
2565                 height -= 10;
2566                 width -= 46;
2567                 top_margin = 8;
2568             }
2569         }
2570         else if (!strcmp(normalized_model, "WB2000")) // Samsung WB2000; raw_width: 3728
2571         {
2572             order = 0x4949;
2573             height -= 3;
2574             top_margin = 2;
2575             if ((width -= 10) > 3718)
2576             {
2577                 height -= 28;
2578                 width -= 56;
2579                 top_margin = 8;
2580             }
2581         }
2582         else if (!strcmp(model, "WB550")) // Samsung WB550; raw_width: 4000
2583         {
2584             order = 0x4949;
2585         }
2586         else if (!strcmp(model, "EX2F")) // Samsung EX2F; raw_width: 4176
2587         {
2588             height = 3030;
2589             width = 4040;
2590             top_margin = 15;
2591             left_margin = 24;
2592             order = 0x4949;
2593             filters = 0x49494949;
2594             load_raw = &LibRaw::unpacked_load_raw;
2595         }
2596     }
2597 
2598     else if (makeIs(LIBRAW_CAMERAMAKER_ST_Micro) && !strcmp(model, "STV680 VGA"))
2599     {
2600         black = 16;
2601     }
2602     else if (!strcmp(model, "N95"))
2603     {
2604         height = raw_height - (top_margin = 2);
2605     }
2606     else if (!strcmp(model, "640x480"))
2607     {
2608         gamma_curve(0.45, 4.5, 1, 255);
2609     }
2610     else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad))
2611     {
2612         if (load_raw == &LibRaw::lossless_jpeg_load_raw)
2613             load_raw = &LibRaw::hasselblad_load_raw;
2614 
2615         if ((imHassy.SensorCode == 4) && !strncmp(model, "V96C", 4)) { // Hasselblad V96C
2616             strcpy(model, "V96C");
2617             strcpy(normalized_model, model);
2618             height -= (top_margin = 6);
2619             width -= (left_margin = 3) + 7;
2620             filters = 0x61616161;
2621 
2622         }
2623         else if ((imHassy.SensorCode == 9) && imHassy.uncropped) { // various Hasselblad '-39'
2624             height = 5444;
2625             width = 7248;
2626             top_margin = 4;
2627             left_margin = 7;
2628             filters = 0x61616161;
2629 
2630         }
2631         else if ((imHassy.SensorCode == 13) && imHassy.uncropped) { // Hasselblad H4D-40, H5D-40
2632             height -= 84;
2633             width -= 82;
2634             top_margin = 4;
2635             left_margin = 41;
2636             filters = 0x61616161;
2637 
2638         }
2639         else if ((imHassy.SensorCode == 11) && imHassy.uncropped) { // Hasselblad H5D-50
2640             height -= 84;
2641             width -= 82;
2642             top_margin = 4;
2643             left_margin = 41;
2644             filters = 0x61616161;
2645 
2646         }
2647         else if ((imHassy.SensorCode == 15) &&
2648             !imHassy.SensorSubCode && // Hasselblad H5D-50c
2649             imHassy.uncropped) {
2650             left_margin = 52;
2651             top_margin = 100;
2652             width = 8272;
2653             height = 6200;
2654             black = 256;
2655 
2656         }
2657         else if ((imHassy.SensorCode == 15) &&
2658             (imHassy.SensorSubCode == 2) && // various Hasselblad X1D cameras
2659             imHassy.uncropped) {
2660             top_margin = 96;
2661             height -= 96;
2662             left_margin = 48;
2663             width -= 106;
2664             maximum = 0xffff;
2665             tiff_bps = 16;
2666 
2667         }
2668         else if ((imHassy.SensorCode == 12) && imHassy.uncropped) { // Hasselblad H4D-60
2669             if (black > 500) { // (imHassy.format == LIBRAW_HF_FFF)
2670                 top_margin = 12;
2671                 left_margin = 44;
2672                 width = 8956;
2673                 height = 6708;
2674                 memset(cblack, 0, sizeof(cblack));
2675                 black = 512;
2676             }
2677             else { // (imHassy.format == LIBRAW_HF_3FR)
2678                 top_margin = 8;
2679                 left_margin = 40;
2680                 width = 8964;
2681                 height = 6716;
2682                 black += load_flags = 256;
2683                 maximum = 0x8101;
2684             }
2685 
2686         }
2687         else if ((imHassy.SensorCode == 17) && imHassy.uncropped) { // Hasselblad H6D-100c, A6D-100c
2688             left_margin = 64;
2689             width = 11608;
2690             top_margin = 108;
2691             height = raw_height - top_margin;
2692         }
2693 
2694         if (tiff_samples > 1)
2695         {
2696             is_raw = tiff_samples + 1;
2697             if (!shot_select && !half_size)
2698                 filters = 0;
2699         }
2700     }
2701     else if (makeIs(LIBRAW_CAMERAMAKER_Sinar))
2702     {
2703         if (!load_raw)
2704             load_raw = &LibRaw::unpacked_load_raw;
2705         if (is_raw > 1 && !shot_select)
2706             filters = 0;
2707         maximum = 0x3fff;
2708     }
2709 
2710     if (load_raw == &LibRaw::sinar_4shot_load_raw)
2711     {
2712         if (is_raw > 1 && !shot_select)
2713             filters = 0;
2714     }
2715     else if (makeIs(LIBRAW_CAMERAMAKER_Leaf))
2716     {
2717         maximum = 0x3fff;
2718         fseek(ifp, data_offset, SEEK_SET);
2719         if (ljpeg_start(&jh, 1) && jh.bits == 15)
2720             maximum = 0x1fff;
2721         if (tiff_samples > 1)
2722             filters = 0;
2723         if (tiff_samples > 1 || tile_length < raw_height)
2724         {
2725             load_raw = &LibRaw::leaf_hdr_load_raw;
2726             raw_width = tile_width;
2727         }
2728         if ((width | height) == 2048)
2729         {
2730             if (tiff_samples == 1)
2731             {
2732                 filters = 1;
2733                 strcpy(cdesc, "RBTG");
2734                 strcpy(model, "CatchLight");
2735                 strcpy(normalized_model, model);
2736                 top_margin = 8;
2737                 left_margin = 18;
2738                 height = 2032;
2739                 width = 2016;
2740             }
2741             else
2742             {
2743                 strcpy(model, "DCB2");
2744                 strcpy(normalized_model, model);
2745                 top_margin = 10;
2746                 left_margin = 16;
2747                 height = 2028;
2748                 width = 2022;
2749             }
2750         }
2751         else if (width + height == 3144 + 2060)
2752         {
2753             if (!model[0])
2754             {
2755                 strcpy(model, "Cantare");
2756                 strcpy(normalized_model, model);
2757             }
2758             if (width > height)
2759             {
2760                 top_margin = 6;
2761                 left_margin = 32;
2762                 height = 2048;
2763                 width = 3072;
2764                 filters = 0x61616161;
2765             }
2766             else
2767             {
2768                 left_margin = 6;
2769                 top_margin = 32;
2770                 width = 2048;
2771                 height = 3072;
2772                 filters = 0x16161616;
2773             }
2774             if (!cam_mul[0] || model[0] == 'V')
2775                 filters = 0;
2776             else
2777                 is_raw = tiff_samples;
2778         }
2779         else if (width == 2116) // Leaf "Valeo 6"
2780         {
2781             strcpy(model, "Valeo 6");
2782             strcpy(normalized_model, model);
2783             height -= 2 * (top_margin = 30);
2784             width -= 2 * (left_margin = 55);
2785             filters = 0x49494949;
2786         }
2787         else if (width == 3171) // Leaf "Valeo 6"
2788         {
2789             strcpy(model, "Valeo 6");
2790             strcpy(normalized_model, model);
2791             height -= 2 * (top_margin = 24);
2792             width -= 2 * (left_margin = 24);
2793             filters = 0x16161616;
2794         }
2795     }
2796     else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic))
2797     {
2798         if (raw_width > 0 &&
2799             ((flen - data_offset) / (raw_width * 8 / 7) == raw_height))
2800             load_raw = &LibRaw::panasonic_load_raw;
2801         if (!load_raw)
2802         {
2803             load_raw = &LibRaw::unpacked_load_raw;
2804             load_flags = 4;
2805         }
2806         zero_is_bad = 1;
2807         if ((height += 12) > raw_height)
2808             height = raw_height;
2809         for (i = 0; i < int(sizeof pana / sizeof *pana); i++)
2810             if (raw_width == pana[i][0] && raw_height == pana[i][1])
2811             {
2812                 left_margin = pana[i][2];
2813                 top_margin = pana[i][3];
2814                 width += pana[i][4];
2815                 height += pana[i][5];
2816             }
2817         if (!tiff_bps && pana_bpp >= 12 && pana_bpp <= 14)
2818             tiff_bps = pana_bpp;
2819 
2820         if (!strcmp(model, "DC-LX100M2") && raw_height == 3568 && raw_width == 4816 && filters == 3)
2821             filters = 4;
2822 
2823         filters = 0x01010101U *
2824             (uchar) "\x94\x61\x49\x16"[((filters - 1) ^ (left_margin & 1) ^
2825             (top_margin << 1)) &
2826             3];
2827 
2828     }
2829     else if (makeIs(LIBRAW_CAMERAMAKER_Contax) &&
2830         !strcmp(model, "N Digital")) {
2831         height = 2047;
2832         width = 3072;
2833         filters = 0x61616161;
2834         data_offset = 0x1a00;
2835         load_raw = &LibRaw::packed_load_raw;
2836 
2837     }
2838     else if (makeIs(LIBRAW_CAMERAMAKER_Sony)) {
2839         if (!strcmp(model, "DSC-F828")) { // Sony DSC-F828
2840             width = 3288;
2841             left_margin = 5;
2842             mask[1][3] = -17;
2843             data_offset = 862144;
2844             load_raw = &LibRaw::sony_load_raw;
2845             filters = 0x9c9c9c9c;
2846             colors = 4;
2847             strcpy(cdesc, "RGBE");
2848 
2849         }
2850         else if (!strcmp(model, "DSC-V3")) { // Sony DSC-V3
2851             width = 3109;
2852             left_margin = 59;
2853             mask[0][1] = 9;
2854             data_offset = 787392;
2855             load_raw = &LibRaw::sony_load_raw;
2856 
2857         }
2858         else if (raw_width == 3984) { // Sony DSC-R1;
2859             width = 3925;
2860             order = 0x4d4d;
2861 
2862         }
2863         else if (raw_width == 4288) { // Sony ILCE-7S, ILCE-7SM2, ILCE-7SM3, DSLR-A700, DSLR-A500;
2864             width -= 32;
2865         }
2866         else if (raw_width == 4600) { // Sony DSLR-A290, DSLR-A350, DSLR-A380;
2867             if (!strcmp(model, "DSLR-A350"))
2868                 height -= 4;
2869             black = 0;
2870 
2871         }
2872         else if (raw_width == 4928) {
2873             // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, SLT-A55,
2874             // NEX-5N, SLT-A37, SLT-A57, NEX-F3, NEX-6, NEX-5R, NEX-3N, NEX-5T;
2875             if (height < 3280)
2876                 width -= 8;
2877 
2878         }
2879         else if (raw_width == 5504) {
2880             // Sony ILCE-3000, SLT-A58, DSC-RX100M3, ILCE-QX1,
2881             // DSC-RX10M4, DSC-RX100M6, DSC-RX100, DSC-RX100M2, DSC-RX10,
2882             // ILCE-5000, DSC-RX100M4, DSC-RX10M2, DSC-RX10M3,
2883             // DSC-RX100M5, DSC-RX100M5A;
2884             width -= height > 3664 ? 8 : 32;
2885 
2886         }
2887         else if (raw_width == 6048) {
2888             // Sony SLT-A65, DSC-RX1, SLT-A77, DSC-RX1, ILCA-77M2,
2889             // ILCE-7M3, NEX-7, SLT-A99, ILCE-7, DSC-RX1R, ILCE-6000,
2890             // ILCE-5100, ILCE-7M2, ILCA-68, ILCE-6300, ILCE-9,
2891             // ILCE-6500, ILCE-6400;
2892             width -= 24;
2893             if (strstr(normalized_model, "RX1") ||
2894                 strstr(normalized_model, "A99"))
2895                 width -= 6;
2896 
2897         }
2898         else if (raw_width == 7392) { // Sony ILCE-7R;
2899             width -= 30;
2900 
2901         }
2902         else if (raw_width == 8000) {
2903             // Sony ILCE-7RM2, ILCE-7RM2, ILCE-7RM3, DSC-RX1RM2, ILCA-99M2;
2904             width -= 32;
2905 
2906         }
2907         else if (raw_width == 9600) { // Sony ILCE-7RM4
2908             width -= 32;
2909 
2910         }
2911         else if(unique_id == SonyID_ILCE_1)
2912         {
2913           if (raw_width == 8704 && raw_height == 6144) // ILCE-1 FF@Compressed
2914           {
2915             width = 8660;
2916             height = 5784;
2917           }
2918           else if (raw_width == 8672) // FF uncompressed/lossy
2919           {
2920             width -= 12;
2921           }
2922           else if (raw_width == 6144 && raw_height == 4096) // APSC/Lossless
2923           {
2924             width = 5636;
2925             height = 3768;
2926           }
2927           else if (raw_width == 5664) // APS-C/Uncompressed or lossy
2928           {
2929               width -= 28;
2930           }
2931         }
2932         else if (unique_id == SonyID_ILCE_7M4)
2933         {
2934           if (raw_width == 7168 && raw_height == 5120) // ILCE-1 FF@Compressed
2935           {
2936             width = 7028;
2937             height = 4688;
2938           }
2939           else if (raw_width == 7040) // FF uncompressed/lossy
2940           {
2941             width -= 12;
2942           }
2943           /* FIXME: need APS-C samples, both losslesscompressed and uncompressed or lossy */
2944         }
2945 
2946         else if (!strcmp(model, "DSLR-A100")) {
2947             if (width == 3880) {
2948                 height--;
2949                 width = ++raw_width;
2950             }
2951             else {
2952                 height -= 4;
2953                 width -= 4;
2954                 order = 0x4d4d;
2955                 load_flags = 2;
2956             }
2957             filters = 0x61616161;
2958         }
2959     }
2960 
2961     else if (!strcmp(model, "PIXL")) {
2962         height -= top_margin = 4;
2963         width -= left_margin = 32;
2964         gamma_curve(0, 7, 1, 255);
2965 
2966     }
2967     else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) {
2968 
2969         if (!strncasecmp(model, "EasyShare", 9)) {
2970             data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
2971             load_raw = &LibRaw::packed_load_raw;
2972 
2973         }
2974         else if (!strcmp(model, "C603") ||
2975             !strcmp(model, "C330") ||
2976             !strcmp(model, "12MP")) {
2977             order = 0x4949;
2978             if (filters && data_offset) {
2979                 fseek(ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
2980                 read_shorts(curve, 256);
2981             }
2982             else
2983                 gamma_curve(0, 3.875, 1, 255);
2984 
2985             load_raw = filters ? &LibRaw::eight_bit_load_raw
2986                 : strcmp(model, "C330") ? &LibRaw::kodak_c603_load_raw
2987                 : &LibRaw::kodak_c330_load_raw;
2988             load_flags = tiff_bps > 16;
2989             tiff_bps = 8;
2990 
2991         }
2992         else {
2993             if (!strncmp(model, "NC2000", 6) ||
2994                 !strncmp(model, "EOSDCS", 6) ||
2995                 !strncmp(model, "DCS4", 4)) {
2996                 width -= 4;
2997                 left_margin = 2;
2998 
2999             }
3000             else if (!strcmp(model, "DCS660M")) {
3001                 black = 214;
3002 
3003             }
3004             else if (!strcmp(model, "EOS D2000C")) {
3005                 filters = 0x61616161;
3006                 if (!black) black = curve[200];
3007             }
3008 
3009             if (filters == UINT_MAX) filters = 0x61616161;
3010 
3011             if (!strcmp(model + 4, "20X"))
3012                 strcpy(cdesc, "MYCY");
3013             if (!strcmp(model, "DC25")) {
3014                 data_offset = 15424;
3015             }
3016 
3017             if (!strncmp(model, "DC2", 3)) {
3018                 raw_height = 2 + (height = 242);
3019                 if (!strncmp(model, "DC290", 5))
3020                     iso_speed = 100;
3021                 if (!strncmp(model, "DC280", 5))
3022                     iso_speed = 70;
3023                 if (flen < 100000) {
3024                     raw_width = 256;
3025                     width = 249;
3026                     pixel_aspect = (4.0 * height) / (3.0 * width);
3027                 }
3028                 else {
3029                     raw_width = 512;
3030                     width = 501;
3031                     pixel_aspect = (493.0 * height) / (373.0 * width);
3032                 }
3033                 top_margin = left_margin = 1;
3034                 colors = 4;
3035                 filters = 0x8d8d8d8d;
3036                 simple_coeff(1);
3037                 pre_mul[1] = 1.179f;
3038                 pre_mul[2] = 1.209f;
3039                 pre_mul[3] = 1.036f;
3040                 load_raw = &LibRaw::eight_bit_load_raw;
3041             }
3042             else if (!strcmp(model, "DC40")) {
3043                 height = 512;
3044                 width = 768;
3045                 data_offset = 1152;
3046                 load_raw = &LibRaw::kodak_radc_load_raw;
3047                 tiff_bps = 12;
3048                 FORC4 cam_mul[c] = 1.0f;
3049 
3050             }
3051             else if (!strcmp(model, "DC50")) {
3052                 height = 512;
3053                 width = 768;
3054                 iso_speed = 84;
3055                 data_offset = 19712;
3056                 load_raw = &LibRaw::kodak_radc_load_raw;
3057                 FORC4 cam_mul[c] = 1.0f;
3058 
3059             }
3060             else if (!strcmp(model, "DC120")) {
3061                 raw_height = height = 976;
3062                 raw_width = width = 848;
3063                 iso_speed = 160;
3064                 pixel_aspect = height / 0.75 / width;
3065                 load_raw = tiff_compress == 7 ? &LibRaw::kodak_jpeg_load_raw
3066                     : &LibRaw::kodak_dc120_load_raw;
3067 
3068             }
3069             else if (!strcmp(model, "DCS200")) {
3070                 thumb_height = 128;
3071                 thumb_width = 192;
3072                 thumb_offset = 6144;
3073                 thumb_misc = 360;
3074                 iso_speed = 140;
3075                 thumb_format = LIBRAW_INTERNAL_THUMBNAIL_LAYER;
3076                 black = 17;
3077             }
3078         }
3079 
3080     }
3081     else if (makeIs(LIBRAW_CAMERAMAKER_Logitech) &&
3082         !strcmp(model, "Fotoman Pixtura")) {
3083         height = 512;
3084         width = 768;
3085         data_offset = 3632;
3086         load_raw = &LibRaw::kodak_radc_load_raw;
3087         filters = 0x61616161;
3088         simple_coeff(2);
3089 
3090     }
3091     else if (makeIs(LIBRAW_CAMERAMAKER_Apple) &&
3092         !strncmp(model, "QuickTake", 9)) {
3093         if (head[5]) {
3094             strcpy(model + 10, "200");
3095             strcpy(normalized_model, model);
3096         }
3097         fseek(ifp, 544, SEEK_SET);
3098         height = get2();
3099         width = get2();
3100         data_offset = (get4(), get2()) == 30 ? 738 : 736;
3101         if (height > width) {
3102             SWAP(height, width);
3103             fseek(ifp, data_offset - 6, SEEK_SET);
3104             flip = ~get2() & 3 ? 5 : 6;
3105         }
3106         filters = 0x61616161;
3107 
3108     }
3109     else if (makeIs(LIBRAW_CAMERAMAKER_Rollei) &&
3110         !load_raw) {
3111         switch (raw_width) {
3112         case 1316: // Rollei d530flex
3113             height = 1030;
3114             width = 1300;
3115             top_margin = 1;
3116             left_margin = 6;
3117             break;
3118         case 2568:
3119             height = 1960;
3120             width = 2560;
3121             top_margin = 2;
3122             left_margin = 8;
3123         }
3124         filters = 0x16161616;
3125         load_raw = &LibRaw::rollei_load_raw;
3126 
3127     }
3128     else if (!strcmp(model, "GRAS-50S5C")) {
3129         height = 2048;
3130         width = 2440;
3131         load_raw = &LibRaw::unpacked_load_raw;
3132         data_offset = 0;
3133         filters = 0x49494949;
3134         order = 0x4949;
3135         maximum = 0xfffC;
3136 
3137     }
3138     else if (!strcmp(model, "BB-500CL")) {
3139         height = 2058;
3140         width = 2448;
3141         load_raw = &LibRaw::unpacked_load_raw;
3142         data_offset = 0;
3143         filters = 0x94949494;
3144         order = 0x4949;
3145         maximum = 0x3fff;
3146 
3147     }
3148     else if (!strcmp(model, "BB-500GE")) {
3149         height = 2058;
3150         width = 2456;
3151         load_raw = &LibRaw::unpacked_load_raw;
3152         data_offset = 0;
3153         filters = 0x94949494;
3154         order = 0x4949;
3155         maximum = 0x3fff;
3156 
3157     }
3158     else if (!strcmp(model, "SVS625CL")) {
3159         height = 2050;
3160         width = 2448;
3161         load_raw = &LibRaw::unpacked_load_raw;
3162         data_offset = 0;
3163         filters = 0x94949494;
3164         order = 0x4949;
3165         maximum = 0x0fff;
3166     }
3167 }