Coverage Report

Created: 2026-11-12 07:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/identify.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2026 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5
 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6
 LibRaw do not use RESTRICTED code from dcraw.c
7
8
 LibRaw is free software; you can redistribute it and/or modify
9
 it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#include "../../internal/dcraw_defs.h"
20
#include "../../internal/libraw_cameraids.h"
21
22
// clang-format on
23
static const struct
24
{
25
    const int CorpId;
26
    const char *CorpName;
27
} CorpTable[] = {
28
    {LIBRAW_CAMERAMAKER_Agfa,           "AgfaPhoto"},
29
    {LIBRAW_CAMERAMAKER_Apple,          "Apple"},
30
    {LIBRAW_CAMERAMAKER_Broadcom,       "Broadcom"},
31
    {LIBRAW_CAMERAMAKER_Canon,          "Canon"},
32
    {LIBRAW_CAMERAMAKER_Casio,          "Casio"},
33
    {LIBRAW_CAMERAMAKER_CINE,           "CINE"},
34
    {LIBRAW_CAMERAMAKER_Epson,          "Epson"},
35
    {LIBRAW_CAMERAMAKER_Fujifilm,       "Fujifilm"},
36
    {LIBRAW_CAMERAMAKER_Mamiya,         "Mamiya"},
37
    {LIBRAW_CAMERAMAKER_Motorola,       "Motorola"},
38
    {LIBRAW_CAMERAMAKER_Kodak,          "Kodak"},
39
    {LIBRAW_CAMERAMAKER_Konica,         "Konica"},
40
    {LIBRAW_CAMERAMAKER_Minolta,        "Minolta"},
41
    {LIBRAW_CAMERAMAKER_Leica,          "Leica"},
42
    {LIBRAW_CAMERAMAKER_Nikon,          "Nikon"},
43
    {LIBRAW_CAMERAMAKER_Nokia,          "Nokia"},
44
    {LIBRAW_CAMERAMAKER_Olympus,        "Olympus"},
45
    {LIBRAW_CAMERAMAKER_OmDigital,      "OM Digital"},
46
    {LIBRAW_CAMERAMAKER_Ricoh,          "Ricoh"},
47
    {LIBRAW_CAMERAMAKER_Pentax,         "Pentax"},
48
    {LIBRAW_CAMERAMAKER_PhaseOne,       "Phase One"},
49
    {LIBRAW_CAMERAMAKER_PhaseOne,       "PhaseOne"},
50
    {LIBRAW_CAMERAMAKER_Samsung,        "Samsung"},
51
    {LIBRAW_CAMERAMAKER_Sigma,          "Sigma"},
52
    {LIBRAW_CAMERAMAKER_Sinar,          "Sinar"},
53
    {LIBRAW_CAMERAMAKER_Sony,           "Sony"},
54
    {LIBRAW_CAMERAMAKER_YI,             "YI"},
55
    // add corp. names below
56
    {LIBRAW_CAMERAMAKER_Alcatel,        "Alcatel"},
57
    {LIBRAW_CAMERAMAKER_Aptina,         "Aptina"},
58
    {LIBRAW_CAMERAMAKER_AVT,            "AVT"},
59
    {LIBRAW_CAMERAMAKER_Baumer,         "Baumer"},
60
    {LIBRAW_CAMERAMAKER_Clauss,         "Clauss"},
61
    {LIBRAW_CAMERAMAKER_Contax,         "Contax"},
62
    {LIBRAW_CAMERAMAKER_Creative,       "Creative"},
63
    {LIBRAW_CAMERAMAKER_DJI,            "DJI"},
64
    {LIBRAW_CAMERAMAKER_Foculus,        "Foculus"},
65
    {LIBRAW_CAMERAMAKER_Generic,        "Generic"},
66
    {LIBRAW_CAMERAMAKER_Gione,          "Gione"},
67
    {LIBRAW_CAMERAMAKER_GITUP,          "GITUP"},
68
    {LIBRAW_CAMERAMAKER_Hasselblad,     "Hasselblad"},
69
    {LIBRAW_CAMERAMAKER_HTC,            "HTC"},
70
    {LIBRAW_CAMERAMAKER_I_Mobile,       "I_Mobile"},
71
    {LIBRAW_CAMERAMAKER_Imacon,         "Imacon"},
72
    {LIBRAW_CAMERAMAKER_ISG,            "ISG"},
73
    {LIBRAW_CAMERAMAKER_JK_Imaging,     "JK Imaging"}, // Kodak
74
    {LIBRAW_CAMERAMAKER_Leaf,           "Leaf"},
75
    {LIBRAW_CAMERAMAKER_Lenovo,         "Lenovo"},
76
    {LIBRAW_CAMERAMAKER_LG,             "LG"},
77
    {LIBRAW_CAMERAMAKER_Logitech,       "Logitech"},
78
    {LIBRAW_CAMERAMAKER_Matrix,         "Matrix"},
79
    {LIBRAW_CAMERAMAKER_Meizu,          "Meizu"},
80
    {LIBRAW_CAMERAMAKER_Micron,         "Micron"},
81
    {LIBRAW_CAMERAMAKER_NGM,            "NGM"},
82
    {LIBRAW_CAMERAMAKER_OmniVison,      "OmniVison"},
83
    {LIBRAW_CAMERAMAKER_Panasonic,      "Panasonic"},
84
    {LIBRAW_CAMERAMAKER_Photron,        "Photron"},
85
    {LIBRAW_CAMERAMAKER_Pixelink,       "Pixelink"},
86
    {LIBRAW_CAMERAMAKER_Polaroid,       "Polaroid"},
87
    {LIBRAW_CAMERAMAKER_Rollei,         "Rollei"},
88
    {LIBRAW_CAMERAMAKER_RoverShot,      "RoverShot"},
89
    {LIBRAW_CAMERAMAKER_SMaL,           "SMaL"},
90
    {LIBRAW_CAMERAMAKER_ST_Micro,       "ST Micro"},
91
    {LIBRAW_CAMERAMAKER_THL,            "THL"},
92
    {LIBRAW_CAMERAMAKER_Xiaomi,         "Xiaomi"},
93
    {LIBRAW_CAMERAMAKER_XIAOYI,         "Xiayi"},
94
    {LIBRAW_CAMERAMAKER_Yuneec,         "Yuneec"},
95
    {LIBRAW_CAMERAMAKER_DXO,            "DxO"},
96
    {LIBRAW_CAMERAMAKER_RED,            "Red"},
97
    {LIBRAW_CAMERAMAKER_PhotoControl,   "Photo Control"},
98
    {LIBRAW_CAMERAMAKER_Google,         "Google"},
99
    {LIBRAW_CAMERAMAKER_GoPro,          "GoPro"},
100
    {LIBRAW_CAMERAMAKER_Parrot,         "Parrot"},
101
    {LIBRAW_CAMERAMAKER_Zeiss,          "Zeiss"},
102
    {LIBRAW_CAMERAMAKER_OnePlus,        "OnePlus"},
103
    {LIBRAW_CAMERAMAKER_VIVO,           "Vivo"},
104
    {LIBRAW_CAMERAMAKER_HMD_Global,     "HMD Global"},
105
    {LIBRAW_CAMERAMAKER_HUAWEI,         "Huawei"},
106
    {LIBRAW_CAMERAMAKER_RaspberryPi,    "RaspberryPi"},
107
};
108
// clang-format on
109
110
int LibRaw::setMakeFromIndex(unsigned makei)
111
174
{
112
174
  if (makei <= LIBRAW_CAMERAMAKER_Unknown || makei >= LIBRAW_CAMERAMAKER_TheLastOne) return 0;
113
114
5.95k
  for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
115
5.95k
    if ((unsigned)CorpTable[i].CorpId == makei)
116
174
    {
117
174
      strcpy(normalized_make, CorpTable[i].CorpName);
118
174
      maker_index = makei;
119
174
      return 1;
120
174
    }
121
0
  return 0;
122
174
}
123
124
const char *LibRaw::cameramakeridx2maker(unsigned maker)
125
0
{
126
0
    for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
127
0
        if((unsigned)CorpTable[i].CorpId == maker)
128
0
            return CorpTable[i].CorpName;
129
0
    return 0;
130
0
}
131
132
int LibRaw::simplify_make_model(unsigned *_maker_index, 
133
  char *_make, unsigned _make_buf_size, char *_model, unsigned _model_buf_size)
134
19.7k
{
135
19.7k
  if (!_make || _make_buf_size < 2 || !_model || _model_buf_size < 2)
136
0
    return -1;
137
138
19.7k
  unsigned mkindex = 0;
139
879k
    for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
140
871k
    {
141
871k
      if (strcasestr(_make, CorpTable[i].CorpName))
142
11.6k
      { /* Simplify company names */
143
11.6k
        mkindex = CorpTable[i].CorpId;
144
11.6k
        break;
145
11.6k
      }
146
871k
    }
147
148
19.7k
    if (mkindex == LIBRAW_CAMERAMAKER_HMD_Global && !strncasecmp(_model, "Nokia", 5))
149
0
    {
150
0
      mkindex = LIBRAW_CAMERAMAKER_Nokia;
151
0
    }
152
19.7k
    else if (mkindex == LIBRAW_CAMERAMAKER_JK_Imaging && !strncasecmp(_model, "Kodak", 5))
153
0
    {
154
0
      mkindex = LIBRAW_CAMERAMAKER_Kodak;
155
0
    }
156
19.7k
    else if (mkindex == LIBRAW_CAMERAMAKER_Ricoh && !strncasecmp(_model, "PENTAX", 6))
157
3
    {
158
3
      mkindex = LIBRAW_CAMERAMAKER_Pentax;
159
3
    }
160
161
879k
  for (int i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
162
871k
    {
163
871k
      if (mkindex == (unsigned)CorpTable[i].CorpId)
164
11.6k
      {
165
11.6k
        strncpy(_make, CorpTable[i].CorpName, _make_buf_size - 1);
166
11.6k
        _make[_make_buf_size - 1] = 0;
167
11.6k
        break;
168
11.6k
      }
169
871k
    }
170
171
19.7k
    char *cp = 0;
172
19.7k
    if ((mkindex == LIBRAW_CAMERAMAKER_Kodak || mkindex == LIBRAW_CAMERAMAKER_Leica) &&
173
753
        ((cp = strcasestr(_model, " DIGITAL CAMERA")) || (cp = strstr(_model, "FILE VERSION"))))
174
2
    {
175
2
      *cp = 0;
176
2
    }
177
178
19.7k
    remove_trailing_spaces(_make, _make_buf_size);
179
19.7k
    remove_trailing_spaces(_model, _model_buf_size);
180
181
19.7k
    int i = int(strnlen(_make, _make_buf_size - 1)); /* Remove make from model */
182
19.7k
    if (!strncasecmp(_model, _make, i) && _model[i++] == ' ')
183
55
      memmove(_model, _model + i, _model_buf_size - i);
184
185
19.7k
    if (mkindex == LIBRAW_CAMERAMAKER_Fujifilm && !strncmp(_model, "FinePix", 7))
186
5
    {
187
5
      memmove(_model, _model + 7, strlen(_model) - 6);
188
5
      if (_model[0] == ' ')
189
4
      {
190
4
        memmove(_model, _model + 1, strlen(_model));
191
4
      }
192
5
    }
193
19.7k
    else if ((mkindex == LIBRAW_CAMERAMAKER_Kodak || mkindex == LIBRAW_CAMERAMAKER_Konica) &&
194
747
             !strncmp(_model, "Digital Camera ", 15))
195
0
    {
196
0
      memmove(_model, _model + 15, strlen(_model) - 14);
197
0
    }
198
199
19.7k
    if (mkindex)
200
11.6k
    {
201
11.6k
      if (_maker_index)
202
11.6k
        *_maker_index = mkindex;
203
11.6k
      return 0; // maker index is set
204
11.6k
    }
205
8.07k
    return 1; // maker index is not set
206
19.7k
}
207
208
/*
209
   Identify which camera created this file, and set global variables
210
   accordingly.
211
 */
212
void LibRaw::identify()
213
33.1k
{
214
  // clang-format off
215
33.1k
  static const ushort canon[][11] = {
216
      // raw_width, raw_height, left_margin, top_margin,
217
      // width_decrement, height_decrement,
218
      // mask01, mask03, mask11, mask13,
219
      // CFA_filters.
220
33.1k
    { 1944, 1416, 0, 0, 48, 0 }, // 00 "PowerShot Pro90 IS"
221
33.1k
    { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, // 01 "PowerShot S30", "PowerShot G1"
222
33.1k
    { 2224, 1456, 48, 6, 0, 2 }, // 02 "EOS D30"
223
33.1k
    { 2376, 1728, 12, 6, 52, 2 }, // 03 "PowerShot G2", "PowerShot S40", "PowerShot G3", "PowerShot S45"
224
33.1k
    { 2672, 1968, 12, 6, 44, 2 }, // 04 "PowerShot G5", "PowerShot S50", "PowerShot S60"
225
33.1k
    { 3152, 2068, 64, 12, 0, 0, 16 }, // 05 "EOS D60", "EOS 10D", "EOS 300D"
226
33.1k
    { 3160, 2344, 44, 12, 4, 4 }, // 06 "PowerShot G6", "PowerShot S70"
227
33.1k
    { 3344, 2484, 4, 6, 52, 6 }, // 07 "PowerShot Pro1"
228
33.1k
    { 3516, 2328, 42, 14, 0, 0 }, // 08 "EOS 350D"
229
33.1k
    { 3596, 2360, 74, 12, 0, 0 }, // 09 "EOS-1D Mark II", "EOS 20D", "EOS-1D Mark II N", "EOS 30D"
230
33.1k
    { 3744, 2784, 52, 12, 8, 12 }, // 10 "PowerShot G11", "PowerShot S90", "PowerShot G12", "PowerShot S95"
231
33.1k
    { 3944, 2622, 30, 18, 6, 2 }, // 11 "EOS 40D"
232
33.1k
    { 3948, 2622, 42, 18, 0, 2 }, // 12 "EOS 400D", "EOS 1000D"
233
33.1k
    { 3984, 2622, 76, 20, 0, 2, 14 }, // 13 "EOS-1D Mark III"
234
33.1k
    { 4032, 2656, 112, 44, 10, 0 }, // 14 APS-C crop mode: "EOS 6D Mark II"??, "EOS RP"
235
33.1k
    { 4104, 3048, 48, 12, 24, 12 }, // 15 "PowerShot G9"
236
33.1k
    { 4116, 2178, 4, 2, 0, 0 },  // 16 ??
237
33.1k
    { 4152, 2772, 192, 12, 0, 0 }, // 17 "PowerShot SX1 IS"
238
33.1k
    { 4160, 3124, 104, 11, 8, 65 }, // 18 "PowerShot S100 (new)", "PowerShot S100V", "PowerShot G15", "PowerShot S110 (new)"
239
33.1k
    { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, // 19 "PowerShot SX50 HS"
240
33.1k
    { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, // 20 "PowerShot G16", "PowerShot S120"
241
33.1k
    { 4312, 2876, 22, 18, 0, 2 }, // 21 "EOS 450D"
242
33.1k
    { 4352, 2850, 144, 46, 0, 0 }, // 22 APS-C crop mode: "EOS R", "EOS Ra"
243
33.1k
    { 4352, 2874, 62, 18, 0, 0 }, // 23 "EOS 1100D"
244
33.1k
    { 4476, 2954, 90, 34, 0, 0 }, // 24 "EOS 5D"
245
33.1k
    { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, // 25 "PowerShot G10"
246
33.1k
    { 4480, 3366, 80, 50, 0, 0 }, // 26 "PowerShot G1 X Mark II"
247
33.1k
    { 4496, 3366, 80, 50, 12, 0 }, // 27 "PowerShot G1 X"
248
33.1k
    { 4768, 3516, 96, 16, 0, 0, 0, 16 }, // 28 "PowerShot SX60 HS"
249
33.1k
    { 4832, 3204, 62, 26, 0, 0 }, // 29 "EOS 500D"
250
33.1k
    { 4832, 3228, 62, 51, 0, 0 }, // 30 "EOS 50D"
251
33.1k
    { 5108, 3349, 98, 13, 0, 0 }, // 31 "EOS-1Ds Mark II"
252
33.1k
    { 5120, 3318, 142, 45, 62, 0 }, // 32  "EOS-1D Mark IV"
253
33.1k
    { 5280, 3528, 72, 52, 0, 0 }, // 33 "EOS M10", "EOS 650D", "EOS 700D", "EOS M", "EOS 100D", "EOS M2"
254
33.1k
    { 5344, 3516, 142, 51, 0, 0 }, // 34 "EOS 550D", "EOS 600D", "EOS 60D", "EOS 1200D", "EOS 1300D", "EOS 3000D"
255
33.1k
    { 5344, 3584, 126, 100, 0, 2 }, // 35 "EOS-1D X", "EOS-1D C"
256
33.1k
    { 5344, 3950, 98, 18, 0, 0, 0, 24, 0, 0 }, // 36 "PowerShot SX70 HS"
257
33.1k
    { 5360, 3516, 158, 51, 0, 0 }, // 37 "EOS 7D"
258
33.1k
    { 5568, 3708, 72, 38, 0, 0 }, // 38; "EOS 7D Mark II", "EOS 6D", "EOS 70D", "EOS-1D X MARK II"
259
33.1k
    { 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"
260
33.1k
    { 5712, 3774, 62, 20, 10, 2 }, // 40 "EOS-1Ds Mark III"
261
33.1k
    { 5792, 3804, 158, 51, 0, 0 }, // 41 "EOS 5D Mark II"
262
33.1k
    { 5920, 3950, 122, 80, 2, 0 }, // 42 "EOS 5D Mark III"
263
33.1k
    { 6096, 4051, 76, 35, 0, 0 }, // 43 "EOS 1500D"
264
33.1k
    { 6096, 4056, 72, 34, 0, 0 }, // 44 "EOS M3", "EOS 760D", "EOS 750D"
265
33.1k
    { 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", "EOS R100"
266
33.1k
    { 6384, 4224, 120, 44, 0, 0 }, // 46 "EOS 6D Mark II", "EOS RP"
267
33.1k
    { 6880, 4544, 136, 42, 0, 0 }, // 47 "EOS 5D Mark IV"
268
33.1k
    { 6888, 4546, 146, 48, 0, 0 }, // 48 "EOS R", "EOS Ra"
269
33.1k
    { 7128, 4732, 144, 72, 0, 0 }, // 49 "EOS M6 II", "EOS 90D"
270
33.1k
    { 8896, 5920, 160, 64, 0, 0 }, // 50 "EOS 5DS", "EOS 5DS R"
271
33.1k
    { 6192, 4152, 160, 120, 0, 0}, // EOS R3
272
33.1k
    { 6192, 4060, 144, 40, 0,0}, // EOS R10, R50, R50V
273
    //{ 6192, 4060, 168, 52, 24, 8, 16,48,32,0}, // EOS R10
274
33.1k
    { 6188, 4120, 154, 96, 12, 0, 16, 48, 32, 0}, // EOS R6mk2
275
33.1k
    { 3936, 2612, 154, 96, 0, 0}, // EOS R6mk2 APS
276
33.1k
    { 8480, 5650, 258, 162, 0, 0, 128, 2, 128, 0}, // EOS R5mk2, FF
277
33.1k
    { 5376, 3574, 258, 162, 0, 0, 128, 2, 128, 0}, // EOS R5mk2, APS
278
33.1k
    { 6160, 4144, 128, 120, 0, 0}, // EOS R1, FF
279
33.1k
    { 5928, 3944, 144, 80, 0, 0}, // PowerShot V1
280
33.1k
    { 7144, 4760, 158, 96, 0, 0}, // EOS C50 && EOS R6mk3
281
33.1k
    { 4512, 2994, 160, 96, 0, 0}, // EOS R6mk3 crop
282
33.1k
  };
283
284
33.1k
  static const libraw_custom_camera_t const_table[] = {
285
33.1k
    { 786432,   1024,  768, 0, 0,  0, 0,  0, 0x94, 0, 0, "AVT", "F-080C" },
286
33.1k
    { 1447680,  1392, 1040, 0, 0,  0, 0,  0, 0x94, 0, 0, "AVT", "F-145C" },
287
33.1k
    { 1920000,  1600, 1200, 0, 0,  0, 0,  0, 0x94, 0, 0, "AVT", "F-201C" },
288
33.1k
    { 5067304,  2588, 1958, 0, 0,  0, 0,  0, 0x94, 0, 0, "AVT", "F-510C" },
289
33.1k
    { 5067316,  2588, 1958, 0, 0,  0, 0,  0, 0x94, 0, 0, "AVT", "F-510C", 12 },
290
33.1k
    { 10134608, 2588, 1958, 0, 0,  0, 0,  9, 0x94, 0, 0, "AVT", "F-510C" },
291
33.1k
    { 10134620, 2588, 1958, 0, 0,  0, 0,  9, 0x94, 0, 0, "AVT", "F-510C", 12 },
292
33.1k
    { 16157136, 3272, 2469, 0, 0,  0, 0,  9, 0x94, 0, 0, "AVT", "F-810C" },
293
33.1k
    { 3995136,  1632, 1224, 0, 0,  0, 0,  8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" },
294
33.1k
    { 15980544, 3264, 2448, 0, 0,  0, 0,  8, 0x61, 0, 1, "AgfaPhoto", "DC-833m" },
295
33.1k
    { 9631728,  2532, 1902, 0, 0,  0, 0, 96, 0x61, 0, 0, "Alcatel", "5035D" },
296
33.1k
    { 31850496, 4608, 3456, 0, 0,  0, 0,  0, 0x94, 0, 0, "GITUP", "GIT2 4:3" },
297
33.1k
    { 23887872, 4608, 2592, 0, 0,  0, 0,  0, 0x94, 0, 0, "GITUP", "GIT2 16:9" },
298
33.1k
    { 32257024, 4624, 3488, 8, 2, 16, 2,  0, 0x94, 0, 0, "GITUP", "GIT2P 4:3" },
299
33.1k
    { 24192768, 4624, 2616, 8, 2, 16, 2,  0, 0x94, 0, 0, "GITUP", "GIT2P 16:9" },
300
33.1k
    { 18016000, 4000, 2252, 0, 0,  0, 0,  0, 0x94, 0, 0, "GITUP", "G3DUO 16:9" },
301
    //          {24000000, 4000, 3000, 0, 0, 0, 0, 0, 0x94, 0, 0, "GITUP",
302
      //          "G3DUO 4:3"}, // Conflict w/ Samsung WB550
303
304
      //   Android Raw dumps id start
305
      //   File Size in bytes Horizontal Res Vertical Flag then bayer order eg
306
      //   0x16 bbgr 0x94 rggb
307
33.1k
    {  1540857, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "Samsung", "S3" },
308
33.1k
    {  2658304, 1212, 1096,   0, 0, 0, 0,  1, 0x16, 0, 0, "LG", "G3FrontMipi" },
309
33.1k
    {  2842624, 1296, 1096,   0, 0, 0, 0,  1, 0x16, 0, 0, "LG", "G3FrontQCOM" },
310
33.1k
    {  2969600, 1976, 1200,   0, 0, 0, 0,  1, 0x16, 0, 0, "Xiaomi", "MI3wMipi" },
311
33.1k
    {  3170304, 1976, 1200,   0, 0, 0, 0,  1, 0x16, 0, 0, "Xiaomi", "MI3wQCOM" },
312
33.1k
    {  3763584, 1584, 1184,   0, 0, 0, 0, 96, 0x61, 0, 0, "I_Mobile", "I_StyleQ6" },
313
33.1k
    {  5107712, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "OmniVisi", "UltraPixel1" },
314
33.1k
    {  5382640, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "OmniVisi", "UltraPixel2" },
315
33.1k
    {  5664912, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "OmniVisi", "4688" },
316
33.1k
    {  5664912, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "OmniVisi", "4688" },
317
33.1k
    {  5364240, 2688, 1520,   0, 0, 0, 0,  1, 0x61, 0, 0, "OmniVisi", "4688" },
318
33.1k
    {  6299648, 2592, 1944,   0, 0, 0, 0,  1, 0x16, 0, 0, "OmniVisi", "OV5648" },
319
33.1k
    {  6721536, 2592, 1944,   0, 0, 0, 0,  0, 0x16, 0, 0, "OmniVisi", "OV56482" },
320
33.1k
    {  6746112, 2592, 1944,   0, 0, 0, 0,  0, 0x16, 0, 0, "HTC", "OneSV" },
321
33.1k
    {  9631728, 2532, 1902,   0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "5mp" },
322
33.1k
    {  9830400, 2560, 1920,   0, 0, 0, 0, 96, 0x61, 0, 0, "NGM", "ForwardArt" },
323
33.1k
    { 10186752, 3264, 2448,   0, 0, 0, 0,  1, 0x94, 0, 0, "Sony", "IMX219-mipi 8mp" },
324
33.1k
    { 10223360, 2608, 1944,   0, 0, 0, 0, 96, 0x16, 0, 0, "Sony", "IMX" },
325
33.1k
    { 10782464, 3282, 2448,   0, 0, 0, 0,  0, 0x16, 0, 0, "HTC", "MyTouch4GSlide" },
326
33.1k
    { 10788864, 3282, 2448,   0, 0, 0, 0,  0, 0x16, 0, 0, "Xperia", "L" },
327
33.1k
    { 15967488, 3264, 2446,   0, 0, 0, 0, 96, 0x16, 0, 0, "OmniVison", "OV8850" },
328
33.1k
    { 16224256, 4208, 3082,   0, 0, 0, 0,  1, 0x16, 0, 0, "LG", "G3MipiL" },
329
33.1k
    { 16424960, 4208, 3120,   0, 0, 0, 0,  1, 0x16, 0, 0, "IMX135", "MipiL" },
330
33.1k
    { 17326080, 4164, 3120,   0, 0, 0, 0,  1, 0x16, 0, 0, "LG", "G3LQCom" },
331
33.1k
    { 17522688, 4212, 3120,   0, 0, 0, 0,  0, 0x16, 0, 0, "Sony", "IMX135-QCOM" },
332
33.1k
    { 19906560, 4608, 3456,   0, 0, 0, 0,  1, 0x16, 0, 0, "Gione", "E7mipi" },
333
33.1k
    { 19976192, 5312, 2988,   0, 0, 0, 0,  1, 0x16, 0, 0, "LG", "G4" },
334
33.1k
    { 20389888, 4632, 3480,   0, 0, 0, 0,  1, 0x16, 0, 0, "Xiaomi", "RedmiNote3Pro" },
335
33.1k
    { 20500480, 4656, 3496,   0, 0, 0, 0,  1, 0x94, 0, 0, "Sony", "IMX298-mipi 16mp" },
336
33.1k
    { 21233664, 4608, 3456,   0, 0, 0, 0,  1, 0x16, 0, 0, "Gione", "E7qcom" },
337
33.1k
    { 26023936, 4192, 3104,   0, 0, 0, 0, 96, 0x94, 0, 0, "THL", "5000" },
338
33.1k
    { 26257920, 4208, 3120,   0, 0, 0, 0, 96, 0x94, 0, 0, "Sony", "IMX214" },
339
33.1k
    { 26357760, 4224, 3120,   0, 0, 0, 0, 96, 0x61, 0, 0, "OV", "13860" },
340
33.1k
    { 41312256, 5248, 3936,   0, 0, 0, 0, 96, 0x61, 0, 0, "Meizu", "MX4" },
341
33.1k
    { 42923008, 5344, 4016,   0, 0, 0, 0, 96, 0x61, 0, 0, "Sony", "IMX230" },
342
      //   Android Raw dumps id end
343
33.1k
    { 20137344, 3664, 2748,   0,  0,  0,  0, 64, 0x49, 0, 0, "Aptina", "MT9J003", 0xffff },
344
33.1k
    {  2868726, 1384, 1036,   0,  0,  0,  0, 64, 0x49, 0, 8, "Baumer", "TXG14", 1078 },
345
33.1k
    {  6553440, 2664, 1968,   4,  4, 44,  4, 40, 0x94, 0, 2, "Canon", "PowerShot A460" }, // chdk hack
346
33.1k
    {  9243240, 3152, 2346,  12,  7, 44, 13, 40, 0x49, 0, 2, "Canon", "PowerShot A470" }, // chdk hack
347
33.1k
    {  6653280, 2672, 1992,  10,  6, 42,  2, 40, 0x94, 0, 2, "Canon", "PowerShot A530" }, // chdk hack
348
33.1k
    {  6573120, 2672, 1968,  12,  8, 44,  0, 40, 0x94, 0, 2, "Canon", "PowerShot A610" }, // chdk hack
349
33.1k
    {  9219600, 3152, 2340,  36, 12,  4,  0, 40, 0x94, 0, 2, "Canon", "PowerShot A620" }, // chdk hack
350
33.1k
    { 10383120, 3344, 2484,  12,  6, 44,  6, 40, 0x94, 0, 2, "Canon", "PowerShot A630" }, // chdk hack
351
33.1k
    { 12945240, 3736, 2772,  12,  6, 52,  6, 40, 0x94, 0, 2, "Canon", "PowerShot A640" }, // chdk hack
352
33.1k
    { 15636240, 4104, 3048,  48, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot A650 IS" }, // chdk hack
353
33.1k
    { 10341600, 3336, 2480,   6,  5, 32,  3, 40, 0x94, 0, 2, "Canon", "PowerShot A720 IS" }, // chdk hack
354
33.1k
    { 24724224, 4704, 3504,   8, 16, 56,  8, 40, 0x49, 0, 2, "Canon", "PowerShot A3300 IS" }, // chdk hack
355
33.1k
    { 18763488, 4104, 3048,  10, 22, 82, 22,  8, 0x49, 0, 0, "Canon", "PowerShot D10" }, // ? chdk hack ?
356
33.1k
    { 19493760, 4160, 3124, 104, 12,  8, 66, 40, 0x49, 0, 2,  "Canon", "PowerShot S100" }, // chdk hack CRW
357
33.1k
    {  7710960, 2888, 2136,  44,  8,  4,  0, 40, 0x94, 0, 2, "Canon", "PowerShot S3 IS" }, // chdk hack
358
33.1k
    {  5298000, 2400, 1766,  12, 12, 44,  2, 40, 0x94, 0, 2, "Canon", "PowerShot SD300" }, // chdk hack
359
33.1k
    { 18653760, 4080, 3048,  24, 12, 24, 12, 40, 0x94, 0, 2, "Canon", "PowerShot SX20 IS" }, // chdk hack
360
33.1k
    { 21936096, 4464, 3276,  25, 10, 73, 12, 40, 0x16, 0, 2, "Canon", "PowerShot SX30 IS" }, // chdk hack
361
33.1k
    { 19167840, 4176, 3060,  96, 16,  8,  0, 40, 0x94, 0, 2, "Canon", "PowerShot SX40 HS" }, // chdk hack CR2
362
33.1k
    { 15467760, 3720, 2772,   6, 12, 30,  0, 40, 0x94, 0, 2, "Canon", "PowerShot SX110 IS" }, // chdk hack
363
33.1k
    { 15534576, 3728, 2778,  12,  9, 44,  9, 40, 0x94, 0, 2, "Canon", "PowerShot SX120 IS" }, // chdk hack
364
33.1k
    { 19131120, 4168, 3060,  92, 16,  4,  1, 40, 0x94, 0, 2, "Canon", "PowerShot SX220 HS" }, // chdk hack
365
33.1k
    { 31663200, 5344, 3950,  96, 18,  0,  0, 40, 0x94, 0, 2, "Canon", "PowerShot SX710 HS" }, // chdk hack
366
33.1k
    { 30858240, 5248, 3920,   8, 16, 56, 16, 40, 0x94, 0, 2, "Canon", "IXUS 160" }, // chdk hack
367
33.1k
    {  1976352, 1632, 1211,   0,  2,  0,  1,  0, 0x94, 0, 1, "Casio", "QV-2000UX" },
368
33.1k
    {  3217760, 2080, 1547,   0,  0, 10,  1,  0, 0x94, 0, 1, "Casio", "QV-3*00EX" },
369
33.1k
    {  6218368, 2585, 1924,   0,  0,  9,  0,  0, 0x94, 0, 1, "Casio", "QV-5700" },
370
33.1k
    {  7816704, 2867, 2181,   0,  0, 34, 36,  0, 0x16, 0, 1, "Casio", "EX-Z60" },
371
33.1k
    {  2937856, 1621, 1208,   0,  0,  1,  0,  0, 0x94, 7, 13, "Casio", "EX-S20" },
372
33.1k
    {  4948608, 2090, 1578,   0,  0, 32, 34,  0, 0x94, 7, 1, "Casio", "EX-S100" },
373
33.1k
    {  6054400, 2346, 1720,   2,  0, 32,  0,  0, 0x94, 7, 1, "Casio", "QV-R41" },
374
33.1k
    {  7426656, 2568, 1928,   0,  0,  0,  0,  0, 0x94, 0, 1, "Casio", "EX-P505" },
375
33.1k
    {  7530816, 2602, 1929,   0,  0, 22,  0,  0, 0x94, 7, 1, "Casio", "QV-R51" },
376
33.1k
    {  7542528, 2602, 1932,   0,  0, 32,  0,  0, 0x94, 7, 1, "Casio", "EX-Z50" },
377
33.1k
    {  7562048, 2602, 1937,   0,  0, 25,  0,  0, 0x16, 7, 1, "Casio", "EX-Z500" },
378
33.1k
    {  7753344, 2602, 1986,   0,  0, 32, 26,  0, 0x94, 7, 1, "Casio", "EX-Z55" },
379
33.1k
    {  9313536, 2858, 2172,   0,  0, 14, 30,  0, 0x94, 7, 1, "Casio", "EX-P600" },
380
33.1k
    { 10834368, 3114, 2319,   0,  0, 27,  0,  0, 0x94, 0, 1, "Casio", "EX-Z750" },
381
33.1k
    { 10843712, 3114, 2321,   0,  0, 25,  0,  0, 0x94, 0, 1, "Casio", "EX-Z75" },
382
33.1k
    { 10979200, 3114, 2350,   0,  0, 32, 32,  0, 0x94, 7, 1, "Casio", "EX-P700" },
383
33.1k
    { 12310144, 3285, 2498,   0,  0,  6, 30,  0, 0x94, 0, 1, "Casio", "EX-Z850" },
384
33.1k
    { 12489984, 3328, 2502,   0,  0, 47, 35,  0, 0x94, 0, 1, "Casio", "EX-Z8" },
385
33.1k
    { 15499264, 3754, 2752,   0,  0, 82,  0,  0, 0x94, 0, 1, "Casio", "EX-Z1050" },
386
33.1k
    { 18702336, 4096, 3044,   0,  0, 24,  0, 80, 0x94, 7, 1, "Casio", "EX-ZR100" },
387
33.1k
    {  7684000, 2260, 1700,   0,  0,  0,  0, 13, 0x94, 0, 1, "Casio", "QV-4000" },
388
33.1k
    {   787456, 1024,  769,   0,  1,  0,  0,  0, 0x49, 0, 0, "Creative", "PC-CAM 600" },
389
33.1k
    { 28829184, 4384, 3288,   0,  0,  0,  0, 36, 0x61, 0, 0, "DJI" },
390
33.1k
    { 15151104, 4608, 3288,   0,  0,  0,  0,  0, 0x94, 0, 0, "Matrix" },
391
33.1k
    {  3840000, 1600, 1200,   0,  0,  0,  0, 65, 0x49, 0, 0, "Foculus", "531C" },
392
33.1k
    {   307200,  640,  480,   0,  0,  0,  0,  0, 0x94, 0, 0, "Generic" },
393
33.1k
    {    62464,  256,  244,   1,  1,  6,  1,  0, 0x8d, 0, 0, "Kodak", "DC20" },
394
33.1k
    {   124928,  512,  244,   1,  1, 10,  1,  0, 0x8d, 0, 0, "Kodak", "DC20" },
395
33.1k
    {  1652736, 1536, 1076,   0, 52,  0,  0,  0, 0x61, 0, 0, "Kodak", "DCS200" },
396
33.1k
    {  4159302, 2338, 1779,   1, 33,  1,  2,  0, 0x94, 0, 0, "Kodak", "C330" },
397
33.1k
    {  4162462, 2338, 1779,   1, 33,  1,  2,  0, 0x94, 0, 0, "Kodak", "C330", 3160 },
398
33.1k
    {  2247168, 1232,  912,   0,  0, 16,  0,  0, 0x00, 0, 0, "Kodak", "C330" },
399
33.1k
    {  3370752, 1232,  912,   0,  0, 16,  0,  0, 0x00, 0, 0, "Kodak", "C330" },
400
33.1k
    {  6163328, 2864, 2152,   0,  0,  0,  0,  0, 0x94, 0, 0, "Kodak", "C603" },
401
33.1k
    {  6166488, 2864, 2152,   0,  0,  0,  0,  0, 0x94, 0, 0, "Kodak", "C603", 3160 },
402
33.1k
    {   460800,  640,  480,   0,  0,  0,  0,  0, 0x00, 0, 0, "Kodak", "C603" },
403
33.1k
    {  9116448, 2848, 2134,   0,  0,  0,  0,  0, 0x00, 0, 0, "Kodak", "C603" },
404
33.1k
    { 12241200, 4040, 3030,   2,  0,  0, 13,  0, 0x49, 0, 0, "Kodak", "12MP" },
405
33.1k
    { 12272756, 4040, 3030,   2,  0,  0, 13,  0, 0x49, 0, 0, "Kodak", "12MP", 31556 },
406
33.1k
    { 18000000, 4000, 3000,   0,  0,  0,  0,  0, 0x00, 0, 0, "Kodak", "12MP" },
407
33.1k
    {   614400,  640,  480,   0,  3,  0,  0, 64, 0x94, 0, 0, "Kodak", "KAI-0340" },
408
33.1k
    { 15360000, 3200, 2400,   0,  0,  0,  0, 96, 0x16, 0, 0, "Lenovo", "A820" },
409
33.1k
    {  3884928, 1608, 1207,   0,  0,  0,  0, 96, 0x16, 0, 0, "Micron", "2010", 3212 },
410
33.1k
    {  1138688, 1534,  986,   0,  0,  0,  0,  0, 0x61, 0, 0, "Minolta", "RD175", 513 },
411
33.1k
    {  1581060, 1305,  969,   0,  0, 18,  6,  6, 0x1e, 4, 1, "Nikon", "E900" }, // "diag raw" hack
412
33.1k
    {  2465792, 1638, 1204,   0,  0, 22,  1,  6, 0x4b, 5, 1, "Nikon", "E950" }, // "diag raw" hack; possibly also Nikon E700, E800, E775;
413
                                                                          // Olympus C-2020Z
414
33.1k
    {  2940928, 1616, 1213,   0,  0,  0,  7, 30, 0x94, 0, 1, "Nikon", "E2100" }, // "diag raw" hack; also Nikon E2500
415
33.1k
    {  4771840, 2064, 1541,   0,  0,  0,  1,  6, 0xe1, 0, 1, "Nikon", "E990" }, // "diag raw" hack; possibly also Nikon E880, E885, E995;
416
                                                                         // Olympus C-3030Z
417
33.1k
    {  4775936, 2064, 1542,   0,  0,  0,  0, 30, 0x94, 0, 1, "Nikon", "E3700" }, // "diag raw" hack; Nikon E3100, E3200, E3500;
418
                                                                           // Pentax "Optio 33WR"; possibly also Olympus C-740UZ
419
33.1k
    {  5865472, 2288, 1709,   0,  0,  0,  1,  6, 0xb4, 0, 1, "Nikon", "E4500" }, // "diag raw" hack; possibly also Olympus C-4040Z
420
33.1k
    {  5869568, 2288, 1710,   0,  0,  0,  0,  6, 0x16, 0, 1, "Nikon", "E4300" }, // "diag raw" hack; also Minolta "DiMAGE Z2"
421
33.1k
    {  7438336, 2576, 1925,   0,  0,  0,  1,  6, 0xb4, 0, 1, "Nikon", "E5000" }, // also Nikon E5700
422
33.1k
    {  8998912, 2832, 2118,   0,  0,  0,  0, 30, 0x94, 7, 1, "Nikon", "COOLPIX S6" }, // "diag raw" hack
423
33.1k
    {  5939200, 2304, 1718,   0,  0,  0,  0, 30, 0x16, 0, 0, "Olympus", "C-770UZ" }, // possibly also Olympus C-4100Z, C-765UZ
424
33.1k
    {  3178560, 2064, 1540,   0,  0,  0,  0,  0, 0x94, 0, 1, "Pentax", "Optio S V1.01" },
425
33.1k
    {  4841984, 2090, 1544,   0,  0, 22,  0,  0, 0x94, 7, 1, "Pentax", "Optio S" },
426
33.1k
    {  6114240, 2346, 1737,   0,  0, 22,  0,  0, 0x94, 7, 1, "Pentax", "Optio S4" },
427
33.1k
    { 10702848, 3072, 2322,   0,  0,  0, 21, 30, 0x94, 0, 1, "Pentax", "Optio 750Z" },
428
33.1k
    {  4147200, 1920, 1080,   0,  0,  0,  0,  0, 0x49, 0, 0, "Photron", "BC2-HD" },
429
33.1k
    {  4151666, 1920, 1080,   0,  0,  0,  0,  0, 0x49, 0, 0, "Photron", "BC2-HD", 8 },
430
33.1k
    { 13248000, 2208, 3000,   0,  0,  0,  0, 13, 0x61, 0, 0, "Pixelink", "A782" },
431
33.1k
    {  6291456, 2048, 1536,   0,  0,  0,  0, 96, 0x61, 0, 0, "RoverShot", "3320AF" },
432
33.1k
    {   311696,  644,  484,   0,  0,  0,  0,  0, 0x16, 0, 8, "ST Micro", "STV680 VGA" },
433
33.1k
    { 16098048, 3288, 2448,   0,  0, 24,  0,  9, 0x94, 0, 1, "Samsung", "S85" }, // hack
434
33.1k
    { 16215552, 3312, 2448,   0,  0, 48,  0,  9, 0x94, 0, 1, "Samsung", "S85" }, // hack
435
33.1k
    { 20487168, 3648, 2808,   0,  0,  0,  0, 13, 0x94, 5, 1, "Samsung", "WB550" },
436
33.1k
    { 24000000, 4000, 3000,   0,  0,  0,  0, 13, 0x94, 5, 1, "Samsung", "WB550" },
437
33.1k
    { 12582980, 3072, 2048,   0,  0,  0,  0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 23; same res. as Leaf Volare & Cantare
438
33.1k
    { 33292868, 4080, 4080,   0,  0,  0,  0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 44
439
33.1k
    { 44390468, 4080, 5440,   0,  0,  0,  0, 33, 0x61, 0, 0, "Sinar", "", 68 }, // Sinarback 54
440
33.1k
    {  1409024, 1376, 1024,   0,  0,  1,  0,  0, 0x49, 0, 0, "Sony", "XCD-SX910CR" },
441
33.1k
    {  2818048, 1376, 1024,   0,  0,  1,  0, 97, 0x49, 0, 0, "Sony", "XCD-SX910CR" },
442
33.1k
  };
443
444
33.1k
  libraw_custom_camera_t
445
33.1k
      table[64 + sizeof(const_table) / sizeof(const_table[0])];
446
447
448
  // clang-format on
449
450
33.1k
  char head[64] = {0}, *cp;
451
33.1k
  int hlen, zero_fsize = 1, i, c;
452
33.1k
  INT64 flen, fsize;
453
33.1k
  struct jhead jh;
454
455
33.1k
  unsigned camera_count =
456
33.1k
      parse_custom_cameras(64, table, imgdata.rawparams.custom_camera_strings);
457
4.89M
  for (int q = 0; q < int(sizeof(const_table) / sizeof(const_table[0])); q++)
458
4.86M
    memmove(&table[q + camera_count], &const_table[q], sizeof(const_table[0]));
459
33.1k
  camera_count += sizeof(const_table) / sizeof(const_table[0]);
460
461
33.1k
  tiff_flip = flip = filters = UINT_MAX; /* unknown */
462
33.1k
  raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0;
463
33.1k
  maximum = height = width = top_margin = left_margin = 0;
464
33.1k
  cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0;
465
33.1k
  iso_speed = shutter = aperture = focal_len = 0;
466
33.1k
  unique_id = 0ULL;
467
33.1k
  tiff_nifds = 0;
468
33.1k
  is_NikonTransfer = 0;
469
33.1k
  is_Olympus = 0;
470
33.1k
  OlympusDNG_SubDirOffsetValid = 0;
471
33.1k
  is_Sony = 0;
472
33.1k
  is_pana_raw = 0;
473
33.1k
  maker_index = LIBRAW_CAMERAMAKER_Unknown;
474
33.1k
  FujiCropMode = 0;
475
33.1k
  is_PentaxRicohMakernotes = 0;
476
33.1k
  normalized_model[0] = 0;
477
33.1k
  normalized_make[0] = 0;
478
33.1k
  CM_found = 0;
479
33.1k
  memset(tiff_ifd, 0, sizeof tiff_ifd);
480
33.1k
  libraw_internal_data.unpacker_data.crx_track_selected = -1;
481
33.1k
  libraw_internal_data.unpacker_data.crx_track_count = -1;
482
33.1k
  libraw_internal_data.unpacker_data.CR3_CTMDtag = 0;
483
33.1k
  imHassy.nIFD_CM[0] = imHassy.nIFD_CM[1] = -1;
484
33.1k
  imKodak.ISOCalibrationGain = 1.0f;
485
33.1k
  imCommon.CameraTemperature = imCommon.SensorTemperature =
486
33.1k
      imCommon.SensorTemperature2 = imCommon.LensTemperature =
487
33.1k
          imCommon.AmbientTemperature = imCommon.BatteryTemperature =
488
33.1k
              imCommon.exifAmbientTemperature = -1000.0f;
489
490
33.1k
  imCanon.AutoRotateMode = 1; // Camera+Computer
491
33.1k
  imCanon.AsShotCT = 5200; // 
492
493
33.1k
  libraw_internal_data.unpacker_data.ifd0_offset = -1LL;
494
132k
  FORC4 imgdata.color.as_shot_wb_corr[c] = 1.0f;
495
496
33.1k
  imgdata.color.ExifColorSpace = LIBRAW_COLORSPACE_Unknown;
497
364k
  for (i = 0; i < LIBRAW_IFD_MAXCOUNT; i++)
498
331k
  {
499
331k
    tiff_ifd[i].dng_color[0].illuminant = tiff_ifd[i].dng_color[1].illuminant =
500
331k
        0xffff;
501
1.65M
    for (int q = 0; q < 4; q++)
502
1.32M
      tiff_ifd[i].dng_levels.analogbalance[q] = 1.0f;
503
331k
  }
504
505
33.1k
  memset(gpsdata, 0, sizeof gpsdata);
506
33.1k
  memset(cblack, 0, sizeof cblack);
507
33.1k
  memset(white, 0, sizeof white);
508
33.1k
  memset(mask, 0, sizeof mask);
509
33.1k
  thumb_offset = thumb_length = thumb_width = thumb_height = 0;
510
33.1k
  load_raw = 0;
511
33.1k
  thumb_format = LIBRAW_INTERNAL_THUMBNAIL_JPEG; // default to JPEG
512
33.1k
  data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0;
513
33.1k
  kodak_cbpp = zero_after_ff = dng_version = load_flags = 0;
514
33.1k
  timestamp = shot_order = tiff_samples = black = is_foveon = 0;
515
33.1k
  mix_green = profile_length = data_error = zero_is_bad = 0;
516
33.1k
  pixel_aspect = is_raw = raw_color = 1;
517
33.1k
  tile_width = tile_length = 0;
518
33.1k
  metadata_blocks = 0;
519
520
165k
  for (i = 0; i < 4; i++)
521
132k
  {
522
132k
    cam_mul[i] = i == 1;
523
132k
    pre_mul[i] = i < 3;
524
397k
    FORC3 cmatrix[c][i] = 0;
525
397k
    FORC3 rgb_cam[c][i] = c == i;
526
132k
  }
527
33.1k
  colors = 3;
528
2.16G
  for (i = 0; i < 0x10000; i++)
529
2.16G
    curve[i] = i;
530
531
33.1k
  order = get2();
532
33.1k
  hlen = get4();
533
33.1k
  fseek(ifp, 0, SEEK_SET);
534
535
33.1k
  if (fread(head, 1, 64, ifp) < 64)
536
57
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
537
33.0k
  libraw_internal_data.unpacker_data.lenRAFData = 0;
538
33.0k
  libraw_internal_data.unpacker_data.posRAFData = 0;
539
540
33.0k
  fseek(ifp, 0, SEEK_END);
541
33.0k
  flen = fsize = ftell(ifp);
542
543
33.0k
  bool checkcr3 = true;
544
33.0k
  if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CR3_DYNAMIC_FRAME_LIMIT)
545
0
  {
546
0
    if (!memcmp((unsigned char *)head + 4, "ftypcrx ", 8))
547
0
      checkcr3 = false;
548
0
  }
549
550
33.0k
  if(checkcr3 && fsize > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE && fsize > LIBRAW_MAX_DNG_RAW_FILE_SIZE 
551
0
    && fsize > LIBRAW_MAX_CR3_RAW_FILE_SIZE)
552
0
      throw LIBRAW_EXCEPTION_TOOBIG;
553
554
33.0k
  if ((cp = (char *)memmem(head, 32, (char *)"MMMM", 4)) ||
555
32.3k
      (cp = (char *)memmem(head, 32, (char *)"IIII", 4)))
556
1.75k
  {
557
1.75k
    parse_phase_one(int(cp - head));
558
1.75k
    if (cp - head && parse_tiff(0))
559
804
      apply_tiff();
560
1.75k
  }
561
31.2k
  else if (order == 0x4949 || order == 0x4d4d)
562
24.6k
  {
563
24.6k
    if (!memcmp(head + 6, "HEAPCCDR", 8))
564
511
    {
565
511
      data_offset = hlen;
566
511
      parse_ciff(INT64(hlen), int(flen - hlen), 0);
567
511
      load_raw = &LibRaw::canon_load_raw;
568
511
    }
569
24.1k
    else if (parse_tiff(0))
570
12.7k
      apply_tiff();
571
24.6k
  }
572
6.60k
  else if (!memcmp(head, "\xff\xd8\xff\xe1", 4) && !memcmp(head + 6, "Exif", 4))
573
93
  {
574
93
    fseek(ifp, 4, SEEK_SET);
575
93
    data_offset = 4 + get2();
576
93
    fseek(ifp, data_offset, SEEK_SET);
577
93
    if (fgetc(ifp) != 0xff)
578
88
      parse_tiff(12);
579
93
    thumb_offset = 0;
580
93
  }
581
6.51k
  else if (!memcmp(head + 25, "ARECOYK", 7)) // 'KYOCERA' right-to-left
582
44
  {
583
44
    strcpy(make, "Contax");
584
44
    strcpy(model, "N Digital");
585
44
    parse_kyocera();
586
44
  }
587
6.46k
  else if (!strcmp(head, "PXN"))
588
3
  {
589
3
    strcpy(make, "Logitech");
590
3
    strcpy(model, "Fotoman Pixtura");
591
3
  }
592
6.46k
  else if (!strcmp(head, "qktk"))
593
125
  {
594
125
    strcpy(make, "Apple");
595
125
    strcpy(model, "QuickTake 100");
596
125
    load_raw = &LibRaw::quicktake_100_load_raw;
597
125
  }
598
6.33k
  else if (!strcmp(head, "qktn"))
599
108
  {
600
108
    strcpy(make, "Apple");
601
108
    strcpy(model, "QuickTake 150");
602
108
    load_raw = &LibRaw::kodak_radc_load_raw;
603
108
  }
604
6.23k
  else if (!memcmp(head, "FUJIFILM", 8))
605
3.12k
  {
606
3.12k
    memcpy(imFuji.SerialSignature, head + 0x10, 0x0c);
607
3.12k
    imFuji.SerialSignature[0x0c] = 0;
608
3.12k
    memcpy(imFuji.SensorID, imFuji.SerialSignature + 0x06, 0x04);
609
3.12k
    imFuji.SensorID[0x04] = 0;
610
3.12k
    strncpy(model, head + 0x1c, 0x20);
611
3.12k
    model[0x20] = 0;
612
3.12k
    c = 11;
613
5.07k
    while (imFuji.SerialSignature[c] > 0 && isdigit(imFuji.SerialSignature[c]) && (c>0))
614
1.94k
      c--;
615
3.12k
  if(c < 11)
616
663
    unique_id = (unsigned long long)atoi(imFuji.SerialSignature+c+1);
617
3.12k
    memcpy(imFuji.RAFVersion, head + 0x3c, 4);
618
3.12k
    imFuji.RAFVersion[4] = 0;
619
3.12k
    fseek(ifp, 84, SEEK_SET);
620
3.12k
    thumb_offset = get4();
621
3.12k
    thumb_length = get4();
622
3.12k
    fseek(ifp, 92, SEEK_SET);
623
3.12k
    parse_fuji(get4());
624
3.12k
    if (thumb_offset > 120)
625
1.66k
    {
626
1.66k
      fseek(ifp, 120, SEEK_SET);
627
1.66k
      is_raw += (i = get4()) ? 1 : 0;
628
1.66k
      if (is_raw == 2 && shot_select)
629
0
        parse_fuji(i);
630
1.66k
    }
631
3.12k
    load_raw = &LibRaw::unpacked_load_raw;
632
3.12k
    fseek(ifp, 100 + 28 * (shot_select > 0), SEEK_SET);
633
3.12k
    parse_tiff(data_offset = get4());
634
3.12k
    parse_tiff(thumb_offset + 12);
635
3.12k
    parse_fuji_thumbnail(thumb_offset);
636
3.12k
    apply_tiff();
637
3.12k
  }
638
3.10k
  else if (!memcmp(head, "RIFF", 4))
639
77
  {
640
77
    fseek(ifp, 0, SEEK_SET);
641
77
    parse_riff(100);
642
77
  }
643
3.02k
  else if (!memcmp(head + 4, "ftypqt   ", 9))
644
673
  {
645
673
    fseek(ifp, 0, SEEK_SET);
646
  // Use existing variable that definitely not used in parse_qt/parse_jpeg to avoid ABI change
647
673
  short cr3save = libraw_internal_data.unpacker_data.CR3_Version;
648
673
  libraw_internal_data.unpacker_data.CR3_Version = 32;
649
673
    parse_qt(fsize);
650
673
  libraw_internal_data.unpacker_data.CR3_Version = cr3save;
651
673
    is_raw = 0;
652
673
  }
653
2.35k
  else if (!memcmp(head, "\0\001\0\001\0@", 6))
654
506
  {
655
506
    fseek(ifp, 6, SEEK_SET);
656
506
    fread(make, 1, 8, ifp);
657
506
    fread(model, 1, 8, ifp);
658
506
    fread(model2, 1, 16, ifp);
659
506
    data_offset = get2();
660
506
    get2();
661
506
    raw_width = get2();
662
506
    raw_height = get2();
663
506
    load_raw = &LibRaw::nokia_load_raw;
664
506
    filters = 0x61616161;
665
506
  }
666
1.84k
  else if (!memcmp(head, "NOKIARAW", 8))
667
10
  {
668
10
    strcpy(make, "NOKIA");
669
10
    order = 0x4949;
670
10
    fseek(ifp, 300, SEEK_SET);
671
10
    data_offset = get4();
672
10
    i = get4(); // bytes count
673
10
    width = get2();
674
10
    height = get2();
675
676
    // Data integrity check
677
10
    if (width < 1 || width > 16000 || height < 1 || height > 16000 ||
678
6
        i < (width * height) || i > (2 * width * height))
679
7
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
680
681
3
    switch (tiff_bps = i * 8 / (width * height))
682
3
    {
683
1
    case 8:
684
1
      load_raw = &LibRaw::eight_bit_load_raw;
685
1
      break;
686
1
    case 10:
687
1
      load_raw = &LibRaw::nokia_load_raw;
688
1
      break;
689
0
    case 0:
690
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
691
0
      break;
692
3
    }
693
3
    raw_height = height + (top_margin = i / (width * tiff_bps / 8) - height);
694
3
    mask[0][3] = 1;
695
3
    filters = 0x61616161;
696
3
  }
697
1.83k
  else if (!memcmp(head, "DSC-Image", 9))
698
132
    parse_rollei();
699
1.70k
  else if (!memcmp(head, "PWAD", 4))
700
364
    parse_sinar_ia();
701
1.34k
  else if (!memcmp(head, "\0MRM", 4))
702
380
    parse_minolta(0);
703
962
  else if (!memcmp(head, "FOVb", 4))
704
1
  {
705
1
    parse_x3f(); /* Does nothing if USE_X3FTOOLS is not defined */
706
1
  }
707
961
  else if (!memcmp(head, "CI", 2))
708
38
    parse_cine();
709
#ifdef USE_6BY9RPI
710
  else if (!memcmp(head, "BRCM", 4)) {
711
  fseek(ifp, 0, SEEK_SET);
712
  strcpy(make, "RaspberryPi");
713
  strcpy(model, "Pi");
714
  parse_raspberrypi();
715
  }
716
#endif
717
923
  else if (!memcmp(head + 4, "ftypcrx ", 8))
718
491
  {
719
491
    int err;
720
491
    UINT64 szAtomList;
721
491
    short nesting = -1;
722
491
    short nTrack = -1;
723
491
    short TrackType;
724
491
    char AtomNameStack[129];
725
491
    strcpy(make, "Canon");
726
727
491
    szAtomList = ifp->size();
728
491
    err = parseCR3(0ULL, szAtomList, nesting, AtomNameStack, nTrack, TrackType,szAtomList);
729
491
    libraw_internal_data.unpacker_data.crx_track_count = nTrack;
730
491
    if ((err == 0 || err == -14) &&
731
132
        nTrack >= 0) // no error, or too deep nesting
732
62
      selectCRXTrack();
733
491
  }
734
735
33.0k
  if (dng_version)
736
4.10k
  {
737
4.10k
      if (fsize > LIBRAW_MAX_DNG_RAW_FILE_SIZE)
738
0
          throw LIBRAW_EXCEPTION_TOOBIG;
739
4.10k
  }
740
28.9k
  else if (load_raw == &LibRaw::crxLoadRaw)
741
0
  {
742
0
    if (checkcr3 && fsize > LIBRAW_MAX_CR3_RAW_FILE_SIZE)
743
0
      throw LIBRAW_EXCEPTION_TOOBIG;
744
0
  }
745
28.9k
  else
746
28.9k
  {
747
28.9k
    if (fsize > LIBRAW_MAX_NONDNG_RAW_FILE_SIZE)
748
0
      throw LIBRAW_EXCEPTION_TOOBIG;
749
28.9k
  }
750
751
33.0k
  if (make[0] == 0)
752
722k
    for (zero_fsize = i = 0; i < (int)camera_count; i++)
753
717k
      if (fsize == (INT64)table[i].fsize)
754
0
      {
755
0
        strcpy(make, table[i].t_make);
756
0
        strcpy(model, table[i].t_model);
757
0
        flip = table[i].flags >> 2;
758
0
        zero_is_bad = table[i].flags & 2;
759
0
        data_offset = table[i].offset == 0xffff ? 0 : table[i].offset;
760
0
        raw_width = table[i].rw;
761
0
        raw_height = table[i].rh;
762
0
        left_margin = table[i].lm;
763
0
        top_margin = table[i].tm;
764
0
        width = raw_width - left_margin - table[i].rm;
765
0
        height = raw_height - top_margin - table[i].bm;
766
0
        filters = 0x1010101U * table[i].cf;
767
0
        colors = 4 - !((filters & filters >> 1) & 0x5555);
768
0
        load_flags = table[i].lf & 0xff;
769
0
        if (table[i].lf & 0x100) /* Monochrome sensor dump */
770
0
        {
771
0
          colors = 1;
772
0
          filters = 0;
773
0
        }
774
0
        switch (tiff_bps = unsigned((fsize - data_offset) * 8LL / (INT64(raw_width) * INT64(raw_height))))
775
0
        {
776
0
        case 6:
777
0
          load_raw = &LibRaw::minolta_rd175_load_raw;
778
0
          ilm.CameraMount = LIBRAW_MOUNT_Minolta_A;
779
0
          break;
780
0
        case 8:
781
0
          load_raw = &LibRaw::eight_bit_load_raw;
782
0
          break;
783
0
        case 10:
784
0
          if ((fsize - data_offset) / INT64(raw_height) * 3LL >= INT64(raw_width) * 4LL)
785
0
          {
786
0
            load_raw = &LibRaw::android_loose_load_raw;
787
0
            break;
788
0
          }
789
0
          else if (load_flags & 1)
790
0
          {
791
0
            load_raw = &LibRaw::android_tight_load_raw;
792
0
            break;
793
0
          }
794
0
        case 12:
795
0
          load_flags |= 128;
796
0
          load_raw = &LibRaw::packed_load_raw;
797
0
          break;
798
0
        case 16:
799
0
          order = 0x4949 | 0x404 * (load_flags & 1);
800
0
          tiff_bps -= load_flags >> 4;
801
0
          tiff_bps -= load_flags = load_flags >> 1 & 7;
802
0
          load_raw = table[i].offset == 0xffff
803
0
                         ? &LibRaw::unpacked_load_raw_reversed
804
0
                         : &LibRaw::unpacked_load_raw;
805
0
        }
806
0
        maximum = (1 << tiff_bps) - (1 << table[i].max);
807
0
        break;
808
0
      }
809
33.0k
  if (zero_fsize)
810
14.8k
    fsize = 0;
811
33.0k
  if (make[0] == 0 && fsize < 25000000LL)
812
4.87k
    parse_smal(0, flen);
813
33.0k
  if (make[0] == 0)
814
4.73k
  {
815
4.73k
    parse_jpeg(0);
816
#ifdef USE_6BY9RPI
817
  if (!(strncmp(model, "ov", 2) && strncmp(model, "RP_", 3) && strncmp(model, "imx477", 6))) {
818
    //Assume that this isn't a raw unless the header can be found
819
    is_raw = 0;
820
821
    if (!strncasecmp(model, "RP_testc",8) 
822
            || !strncasecmp(model, "imx477", 6) //  from PyDNG
823
        || !strncasecmp(model, "RP_imx477",9)) {
824
      const long offsets[] = {
825
        //IMX477 offsets
826
        3375104,  //2028x1080 12bit
827
        4751360,  //2028x1520 12bit
828
        18711040, //4056x3040 12bit
829
        1015808,  //1012x760 10bit
830
        -1        //Marker for end of table
831
      };
832
      int offset_idx;
833
      for (offset_idx=0; offsets[offset_idx]!=-1; offset_idx++) {
834
        if(!fseek (ifp, -offsets[offset_idx], SEEK_END) &&
835
           fread (head, 1, 32, ifp) && !strncmp(head,"BRCM", 4)) {
836
          fseek(ifp, -32, SEEK_CUR);
837
          strcpy (make, "RaspberryPi");
838
                    strcpy(model, "RP_imx477"); // Force single model
839
          black = (offset_idx == 3) ? 64 : 256;
840
          parse_raspberrypi();
841
          break;
842
        }
843
      }
844
    }
845
    else if (!strncasecmp(model, "RP_imx", 6)) {
846
      const long offsets[] = {
847
        //IMX219 offsets
848
        10270208, //8MPix 3280x2464
849
        2678784,  //1920x1080
850
        2628608,  //1640x1232
851
        1963008,  //1640x922
852
        1233920,  //1280x720
853
        445440,   //640x480
854
        -1        //Marker for end of table
855
      };
856
      int offset_idx;
857
      for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) {
858
        if (!fseek(ifp, -offsets[offset_idx], SEEK_END) &&
859
          fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) {
860
861
          fseek(ifp, -32, SEEK_CUR);
862
          strcpy(make, "RaspberryPi");
863
                    black = 66;
864
          parse_raspberrypi();
865
          break;
866
        }
867
      }
868
    }
869
    else if (!strncasecmp(model, "RP_OV", 5) || !strncasecmp(model, "ov5647", 6)) {
870
      const long offsets[] = {
871
          6404096,  //5MPix 2592x1944
872
          2717696,  //1920x1080
873
          1625600,  //1296x972
874
          1233920,  //1296x730
875
          445440,   //640x480
876
          -1        //Marker for end of table
877
      };
878
      int offset_idx;
879
      for (offset_idx = 0; offsets[offset_idx] != -1; offset_idx++) {
880
        if (!fseek(ifp, -offsets[offset_idx], SEEK_END) &&
881
          fread(head, 1, 32, ifp) && !strncmp(head, "BRCM", 4)) {
882
          fseek(ifp, -32, SEEK_CUR);
883
          strcpy(make, "RaspberryPi");
884
                    strcpy(model, "ov5647"); // Force single model
885
                    width = raw_width;
886
          //Defaults
887
          raw_width = 2611;
888
          filters = 0x16161616;
889
                    black = 16;
890
          parse_raspberrypi();
891
          break;
892
        }
893
      }
894
    }
895
  }// else is_raw = 0;
896
#else
897
4.73k
    fseek(ifp, 0, SEEK_END);
898
4.73k
    int sz = ftell(ifp);
899
4.73k
    if (!strncmp(model, "RP_imx219", 9) && sz >= 0x9cb600 &&
900
0
        !fseek(ifp, -0x9cb600, SEEK_END) && fread(head, 1, 0x20, ifp) &&
901
0
        !strncmp(head, "BRCM", 4))
902
0
    {
903
0
      strcpy(make, "Broadcom");
904
0
      strcpy(model, "RPi IMX219");
905
0
      if (raw_height > raw_width)
906
0
        flip = 5;
907
0
      data_offset = ftell(ifp) + 0x8000 - 0x20;
908
0
      parse_broadcom();
909
0
      black = 66;
910
0
      maximum = 0x3ff;
911
0
      load_raw = &LibRaw::broadcom_load_raw;
912
0
      thumb_offset = 0;
913
0
      thumb_length = sz - 0x9cb600 - 1;
914
0
    }
915
4.73k
    else if (!(strncmp(model, "ov5647", 6) && strncmp(model, "RP_OV5647", 9)) &&
916
16
             sz >= 0x61b800 && !fseek(ifp, -0x61b800, SEEK_END) &&
917
0
             fread(head, 1, 0x20, ifp) && !strncmp(head, "BRCM", 4))
918
0
    {
919
0
      strcpy(make, "Broadcom");
920
0
      if (!strncmp(model, "ov5647", 6))
921
0
        strcpy(model, "RPi OV5647 v.1");
922
0
      else
923
0
        strcpy(model, "RPi OV5647 v.2");
924
0
      if (raw_height > raw_width)
925
0
        flip = 5;
926
0
      data_offset = ftell(ifp) + 0x8000 - 0x20;
927
0
      parse_broadcom();
928
0
      black = 16;
929
0
      maximum = 0x3ff;
930
0
      load_raw = &LibRaw::broadcom_load_raw;
931
0
      thumb_offset = 0;
932
0
      thumb_length = sz - 0x61b800 - 1;
933
0
    }
934
4.73k
    else
935
4.73k
      is_raw = 0;
936
4.73k
#endif
937
4.73k
  }
938
939
  // make sure strings are terminated
940
33.0k
  desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
941
942
33.0k
#if 1
943
33.0k
  unsigned mkindex = 0;
944
33.0k
  if (simplify_make_model(&mkindex, make, sizeof(make), model, sizeof(model)) == 0)
945
11.6k
  {
946
11.6k
    maker_index = mkindex;
947
11.6k
  }
948
#else
949
950
  for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++)
951
  {
952
    if (strcasestr(make, CorpTable[i].CorpName))
953
    { /* Simplify company names */
954
      maker_index = CorpTable[i].CorpId;
955
      break;
956
    }
957
  }
958
959
  if (makeIs(LIBRAW_CAMERAMAKER_HMD_Global) && !strncasecmp(model, "Nokia", 5)) {
960
    maker_index = LIBRAW_CAMERAMAKER_Nokia;
961
  }  else if (makeIs(LIBRAW_CAMERAMAKER_JK_Imaging) && !strncasecmp(model, "Kodak", 5)) {
962
    maker_index = LIBRAW_CAMERAMAKER_Kodak;
963
  } else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) && !strncasecmp(model, "PENTAX", 6)) {
964
    maker_index = LIBRAW_CAMERAMAKER_Pentax;
965
  }
966
967
  for (i = 0; i < int(sizeof CorpTable / sizeof *CorpTable); i++) {
968
    if (maker_index == (unsigned)CorpTable[i].CorpId) {
969
      strcpy(make, CorpTable[i].CorpName);
970
      break;
971
    }
972
  }
973
974
  if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Leica)) &&
975
      ((cp = strcasestr(model, " DIGITAL CAMERA")) ||
976
       (cp = strstr(model, "FILE VERSION")))) {
977
    *cp = 0;
978
  }
979
980
  remove_trailing_spaces(make, sizeof(make));
981
  remove_trailing_spaces(model, sizeof(model));
982
983
  i = int(strbuflen(make)); /* Remove make from model */
984
  if (!strncasecmp(model, make, i) && model[i++] == ' ')
985
    memmove(model, model + i, 64 - i);
986
987
  if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm) && !strncmp(model, "FinePix", 7)) {
988
    memmove(model, model + 7, strlen(model) - 6);
989
    if (model[0] == ' ') {
990
      memmove(model, model + 1, strlen(model));
991
    }
992
  } else if ((makeIs(LIBRAW_CAMERAMAKER_Kodak) || makeIs(LIBRAW_CAMERAMAKER_Konica)) &&
993
             !strncmp(model, "Digital Camera ", 15)) {
994
    memmove(model, model + 15, strlen(model) - 14);
995
  }
996
#endif
997
998
33.0k
  desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0;
999
33.0k
  if (!is_raw)
1000
8.41k
    goto notraw;
1001
1002
24.6k
  if (!height)
1003
10.8k
    height = raw_height;
1004
24.6k
  if (!width)
1005
10.8k
    width = raw_width;
1006
1007
24.6k
  identify_finetune_pentax();
1008
1009
1010
24.6k
  if (dng_version)
1011
547
  {
1012
547
    if (filters == UINT_MAX)
1013
148
      filters = 0;
1014
547
    if (!filters)
1015
512
      colors = tiff_samples;
1016
547
    switch (tiff_compress)
1017
547
    {
1018
484
    case 0: // Compression not set, assuming uncompressed
1019
505
    case 1:
1020
      // Uncompressed float: decoder set in apply_tiff for valid files; not set for non-valid with sampleformat==3
1021
505
      if ((load_raw != &LibRaw::uncompressed_fp_dng_load_raw)  && (tiff_sampleformat != 3))
1022
335
        load_raw = &LibRaw::packed_dng_load_raw;
1023
505
      break;
1024
3
    case 7:
1025
3
      load_raw = &LibRaw::lossless_dng_load_raw;
1026
3
      break;
1027
29
    case 8:
1028
29
        if (tiff_sampleformat == 3 && tiff_bps > 8 && (tiff_bps % 8 == 0) && tiff_bps <= 32)
1029
6
            load_raw = &LibRaw::deflate_dng_load_raw;
1030
23
        else if((tiff_sampleformat == 0 || tiff_sampleformat == 1) && tiff_bps>=8 && tiff_bps <=16)
1031
16
          load_raw = &LibRaw::deflate_dng_load_raw;
1032
29
        break;
1033
3
    case 9:
1034
3
        load_raw = &LibRaw::vc5_dng_load_raw_placeholder;
1035
3
        break;
1036
0
    case 52546:
1037
0
      load_raw = &LibRaw::jxl_dng_load_raw_placeholder;
1038
0
      break;
1039
1
    case 34892:
1040
1
      load_raw = &LibRaw::lossy_dng_load_raw;
1041
1
      break;
1042
6
    default:
1043
6
      load_raw = 0;
1044
547
    }
1045
547
    GetNormalizedModel();
1046
547
    if (makeIs(LIBRAW_CAMERAMAKER_Leica)) {
1047
5
      if (!strcmp(model, "SL2")) 
1048
0
              height -= 3;
1049
5
          if (!strncasecmp(model, "Q2 MONO",7))
1050
0
              height -= 18;
1051
5
    }
1052
1053
542
    else if (makeIs(LIBRAW_CAMERAMAKER_Olympus) &&
1054
20
        (OlyID == OlyID_STYLUS_1) && // don't use normalized_model below, it is 'Stylus 1'
1055
2
        (strchr(model+6, 's') ||
1056
1
         strchr(model+6, 'S')))
1057
1
    {
1058
1
      width -= 16;
1059
1
    }
1060
547
    goto dng_skip;
1061
547
  }
1062
1063
24.0k
  if (makeIs(LIBRAW_CAMERAMAKER_Canon) && !fsize && tiff_bps != 15)
1064
1.30k
  {
1065
1.30k
      bool fromtable = false;
1066
1.30k
    if (!load_raw)
1067
1.13k
      load_raw = &LibRaw::lossless_jpeg_load_raw;
1068
80.9k
    for (i = 0; i < int(sizeof canon / sizeof *canon); i++)
1069
79.6k
      if (raw_width == canon[i][0] && raw_height == canon[i][1])
1070
0
      {
1071
0
        width = raw_width - (left_margin = canon[i][2]);
1072
0
        height = raw_height - (top_margin = canon[i][3]);
1073
0
        width -= canon[i][4];
1074
0
        height -= canon[i][5];
1075
0
        mask[0][1] = canon[i][6];
1076
0
        mask[0][3] = -canon[i][7];
1077
0
        mask[1][1] = canon[i][8];
1078
0
        mask[1][3] = -canon[i][9];
1079
0
        if (canon[i][10])
1080
0
          filters = canon[i][10] * 0x01010101U;
1081
0
        fromtable = true;
1082
0
      }
1083
1.30k
    if ((unique_id | 0x20000ULL) ==
1084
1.30k
        0x2720000ULL) // "PowerShot G11", "PowerShot S90": 0x2700000, 0x2720000
1085
                      // possibly "PowerShot SX120 IS" (if not chdk hack?): 0x2710000
1086
0
    {
1087
0
      left_margin = 8;
1088
0
      top_margin = 16;
1089
0
    }
1090
1.30k
    if(!fromtable && imCanon.AverageBlackLevel) // not known, but metadata known
1091
84
    {
1092
336
        FORC4 cblack[c] = imCanon.ChannelBlackLevel[c];
1093
84
        black = cblack[4] = cblack[5] = 0;
1094
        // Prevent automatic BL calculation
1095
84
        mask[0][3] = 1;
1096
84
        mask[0][1] = 2;
1097
1098
84
        if ((imCanon.SensorWidth == raw_width) &&
1099
70
            (imCanon.SensorHeight == raw_height))
1100
66
        {
1101
66
            left_margin = (imCanon.DefaultCropAbsolute.l+1) & 0xfffe; // round to 2
1102
66
            width = imCanon.DefaultCropAbsolute.r - left_margin;
1103
66
            top_margin = (imCanon.DefaultCropAbsolute.t +1)  & 0xfffe;
1104
66
            height = imCanon.DefaultCropAbsolute.b - top_margin;
1105
66
        }
1106
84
    }
1107
1.30k
  }
1108
1109
24.0k
  identify_finetune_by_filesize(fsize);
1110
1111
24.0k
  if (!strcmp(model, "KAI-0340") && find_green(16, 16, 3840, 5120) < 25)
1112
47
  {
1113
47
    height = 480;
1114
47
    top_margin = filters = 0;
1115
47
    strcpy(model, "C603");
1116
47
  }
1117
1118
24.0k
  GetNormalizedModel();
1119
1120
24.0k
  identify_finetune_dcr(head, fsize, flen);
1121
1122
  /* Early reject for damaged images */
1123
24.0k
  if (!load_raw || height < 22 || width < 22 ||
1124
5.27k
      (tiff_bps > 16 &&
1125
12
       (load_raw != &LibRaw::deflate_dng_load_raw &&
1126
12
        load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) ||
1127
5.26k
      tiff_samples > 4 || colors > 4 ||
1128
5.25k
      colors < 1
1129
      /* alloc in unpack() may be fooled by size adjust */
1130
5.25k
      || ((int)width + (int)left_margin > 65535) ||
1131
5.24k
      ((int)height + (int)top_margin > 65535))
1132
5.51k
  {
1133
5.51k
    is_raw = 0;
1134
5.51k
    RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1135
5.51k
    return;
1136
5.51k
  }
1137
18.5k
  if (!model[0])
1138
2.78k
  {
1139
2.78k
    sprintf(model, "%dx%d", width, height);
1140
2.78k
    strcpy(normalized_model, model);
1141
2.78k
  }
1142
1143
18.5k
  if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_ZEROFILTERS_FOR_MONOCHROMETIFFS) &&
1144
5.23k
      (filters == UINT_MAX)) // Default dcraw behaviour
1145
3.10k
    filters = 0x94949494;
1146
15.4k
  else if (filters == UINT_MAX)
1147
0
  {
1148
0
    if (tiff_nifds > 0 && tiff_samples == 1)
1149
0
    {
1150
0
      colors = 1;
1151
0
      filters = 0;
1152
0
    }
1153
0
    else
1154
0
      filters = 0x94949494;
1155
0
  }
1156
1157
18.5k
  if (thumb_offset && !thumb_height)
1158
815
  {
1159
815
    fseek(ifp, thumb_offset, SEEK_SET);
1160
815
    if (ljpeg_start(&jh, 1))
1161
0
    {
1162
0
      thumb_width = jh.wide;
1163
0
      thumb_height = jh.high;
1164
0
    }
1165
815
  }
1166
1167
18.5k
dng_skip:
1168
5.78k
  if (dng_version)
1169
547
    identify_process_dng_fields();
1170
1171
  /* Early reject for damaged images again (after dng fields processing) */
1172
5.78k
  if (!load_raw || height < 22 || width < 22 ||
1173
5.66k
      (tiff_bps > 16 &&
1174
146
       (load_raw != &LibRaw::deflate_dng_load_raw &&
1175
141
        load_raw != &LibRaw::uncompressed_fp_dng_load_raw )) ||
1176
5.60k
      ((load_raw == &LibRaw::deflate_dng_load_raw || load_raw == &LibRaw::uncompressed_fp_dng_load_raw)
1177
181
        && (tiff_bps < 16 || tiff_bps > 32 || (tiff_bps % 8))   )
1178
5.60k
      ||tiff_samples > 4 || colors > 4 || colors < 1)
1179
207
  {
1180
207
    is_raw = 0;
1181
207
    RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1182
207
    return;
1183
207
  }
1184
5.57k
  {
1185
    // Check cam_mul range
1186
5.57k
    int cmul_ok = 1;
1187
16.3k
    FORCC if (cam_mul[c] <= 0.001f) cmul_ok = 0;
1188
5.57k
    ;
1189
1190
5.57k
    if (cmul_ok)
1191
62
    {
1192
62
      double cmin = cam_mul[0], cmax;
1193
62
      double cnorm[4];
1194
180
      FORCC cmin = MIN(cmin, cam_mul[c]);
1195
180
      FORCC cnorm[c] = cam_mul[c] / cmin;
1196
62
      cmax = cmin = cnorm[0];
1197
62
      FORCC
1198
180
      {
1199
180
        cmin = MIN(cmin, cnorm[c]);
1200
180
        cmax = MAX(cmax, cnorm[c]);
1201
180
      }
1202
62
      if (cmin <= 0.01f || cmax > 100.f)
1203
13
        cmul_ok = false;
1204
62
    }
1205
5.57k
    if (!cmul_ok)
1206
5.53k
    {
1207
5.53k
      if (cam_mul[0] > 0)
1208
87
        cam_mul[0] = 0;
1209
5.53k
      cam_mul[3] = 0;
1210
5.53k
    }
1211
5.57k
  }
1212
5.57k
  if ((use_camera_matrix & (((use_camera_wb || dng_version)?1:0) | 0x2)) &&
1213
340
      cmatrix[0][0] > 0.125)
1214
1
  {
1215
1
    memcpy(rgb_cam, cmatrix, sizeof cmatrix);
1216
1
    raw_color = 0;
1217
1
  }
1218
5.57k
  if (raw_color && !CM_found)
1219
5.54k
    CM_found = adobe_coeff(maker_index, normalized_model);
1220
31
  else if ((imgdata.color.cam_xyz[0][0] < 0.01) && !CM_found)
1221
21
    CM_found = adobe_coeff(maker_index, normalized_model, 1);
1222
1223
5.57k
  if (load_raw == &LibRaw::kodak_radc_load_raw)
1224
116
    if ((raw_color) && !CM_found)
1225
5
    CM_found = adobe_coeff(LIBRAW_CAMERAMAKER_Apple, "Quicktake");
1226
1227
5.57k
  if ((maker_index != LIBRAW_CAMERAMAKER_Unknown) && normalized_model[0])
1228
3.88k
    SetStandardIlluminants (maker_index, normalized_model);
1229
1230
  // Clear erroneous fuji_width if not set through parse_fuji or for DNG
1231
5.57k
  if (fuji_width && !dng_version &&
1232
140
      !(imgdata.process_warnings & LIBRAW_WARN_PARSEFUJI_PROCESSED))
1233
2
    fuji_width = 0;
1234
1235
5.57k
  if (fuji_width)
1236
143
  {
1237
143
    fuji_width = width >> int(!fuji_layout);
1238
143
    filters = fuji_width & 1 ? 0x94949494 : 0x49494949;
1239
143
    width = (height >> fuji_layout) + fuji_width;
1240
143
    height = width - 1;
1241
143
    pixel_aspect = 1;
1242
  // Prevent incorrect-sized fuji-rotated files
1243
143
  if (INT64(width)*INT64(height) > INT64(raw_width) * INT64(raw_height) * 8LL)
1244
7
    is_raw = 0;
1245
1246
  // All 'fuji-rotated' images are 6Mpix or less, so 8k x 8k limit is OK
1247
143
  if(width > 8192 || height > 8192 || raw_width > 8192 || raw_height > 8192)
1248
8
      is_raw = 0;
1249
143
  }
1250
5.43k
  else
1251
5.43k
  {
1252
5.43k
    if (raw_height < height)
1253
368
      raw_height = height;
1254
5.43k
    if (raw_width < width)
1255
393
      raw_width = width;
1256
5.43k
  }
1257
5.57k
  if (!tiff_bps)
1258
4.86k
    tiff_bps = 12;
1259
5.57k
  if (!maximum)
1260
3.14k
  {
1261
3.14k
    maximum = (1 << tiff_bps) - 1;
1262
3.14k
    if (maximum < 0x10000 && curve[maximum] > 0 &&
1263
3.05k
        load_raw == &LibRaw::sony_arw2_load_raw)
1264
27
      maximum = curve[maximum];
1265
3.14k
  }
1266
5.57k
  if (maximum > 0xffff)
1267
93
    maximum = 0xffff;
1268
5.57k
  if (!load_raw || height < 22 || width < 22 ||
1269
5.57k
      (tiff_bps > 16 &&
1270
89
       (load_raw != &LibRaw::deflate_dng_load_raw &&
1271
84
        load_raw != &LibRaw::uncompressed_fp_dng_load_raw)) ||
1272
5.57k
      tiff_samples > 6 || colors > 4 || colors == 2)
1273
40
    is_raw = 0;
1274
1275
5.57k
  if (raw_width < 22 || raw_width > 64000 || raw_height < 22 ||
1276
5.26k
      pixel_aspect < 0.1 || pixel_aspect > 10. ||
1277
5.25k
      raw_height > 64000)
1278
375
    is_raw = 0;
1279
5.57k
   if(raw_width <= left_margin || raw_height <= top_margin)
1280
9
       is_raw = 0;
1281
5.57k
   if (dng_version && (tiff_samples < 1 || tiff_samples > 4))
1282
3
       is_raw = 0; // we do not handle DNGs with more than 4 values per pixel
1283
1284
5.57k
#ifdef NO_JPEG
1285
5.57k
  if (load_raw == &LibRaw::kodak_jpeg_load_raw ||
1286
5.57k
      load_raw == &LibRaw::lossy_dng_load_raw)
1287
1
  {
1288
1
    is_raw = 0;
1289
1
    imgdata.process_warnings |= LIBRAW_WARN_NO_JPEGLIB;
1290
1
  }
1291
5.57k
#endif
1292
5.57k
  if (!cdesc[0])
1293
5.57k
    strcpy(cdesc, colors == 3 ? "RGBG" : "GMCY");
1294
5.57k
  if (!raw_height)
1295
3
    raw_height = height;
1296
5.57k
  if (!raw_width)
1297
1
    raw_width = width;
1298
5.57k
  if (filters > 999 && colors == 3)
1299
4.33k
    filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) &
1300
4.33k
               filters << 1;
1301
13.9k
notraw:
1302
13.9k
  if (flip == (int)UINT_MAX)
1303
13.5k
    flip = tiff_flip;
1304
13.9k
  if (flip == (int)UINT_MAX)
1305
10.1k
    flip = 0;
1306
1307
  // Convert from degrees to bit-field if needed
1308
13.9k
  if (flip > 89 || flip < -89)
1309
256
  {
1310
256
    switch ((flip + 3600) % 360)
1311
256
    {
1312
103
    case 270:
1313
103
      flip = 5;
1314
103
      break;
1315
82
    case 180:
1316
82
      flip = 3;
1317
82
      break;
1318
21
    case 90:
1319
21
      flip = 6;
1320
21
      break;
1321
256
    }
1322
256
  }
1323
1324
13.9k
  if (pana_bpp)
1325
125
    imgdata.color.raw_bps = pana_bpp;
1326
13.8k
  else if ((load_raw == &LibRaw::phase_one_load_raw) ||
1327
13.6k
       (load_raw == &LibRaw::phase_one_load_raw_s) ||
1328
13.3k
           (load_raw == &LibRaw::phase_one_load_raw_c))
1329
674
    imgdata.color.raw_bps = ph1.format;
1330
13.1k
  else
1331
13.1k
    imgdata.color.raw_bps = tiff_bps;
1332
1333
13.9k
  RUN_CALLBACK(LIBRAW_PROGRESS_IDENTIFY, 1, 2);
1334
13.9k
}
1335
1336
void LibRaw::identify_process_dng_fields()
1337
547
{
1338
547
  if (!dng_version) return;
1339
1340
  // Cleanup inset_crops if set by makernotes parser
1341
547
  imgdata.sizes.raw_inset_crops[0].cleft = imgdata.sizes.raw_inset_crops[0].ctop =
1342
547
        imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[1].ctop = 0xffff;
1343
547
    imgdata.sizes.raw_inset_crops[0].cwidth = imgdata.sizes.raw_inset_crops[0].cheight =
1344
547
        imgdata.sizes.raw_inset_crops[1].cwidth = imgdata.sizes.raw_inset_crops[1].cheight = 0;
1345
1346
1347
547
  int c;
1348
547
  {
1349
    /* copy DNG data from per-IFD field to color.dng */
1350
547
    int iifd = find_ifd_by_offset(data_offset);
1351
547
    int pifd = find_ifd_by_offset(thumb_offset);
1352
1353
1354
547
#define IFDCOLORINDEX(ifd, subset, bit)                                        \
1355
6.27k
  (tiff_ifd[ifd].dng_color[subset].parsedfields & bit)                         \
1356
6.27k
      ? ifd                                                                    \
1357
6.27k
      : ((tiff_ifd[0].dng_color[subset].parsedfields & bit) ? 0 : -1)
1358
1359
547
#define IFDLEVELINDEX(ifd, bit)                                                \
1360
5.31k
  (tiff_ifd[ifd].dng_levels.parsedfields & bit)                                \
1361
5.31k
      ? ifd                                                                    \
1362
5.31k
      : ((tiff_ifd[0].dng_levels.parsedfields & bit) ? 0 : -1)
1363
1364
547
#define COPYARR(to, from) memmove(&to, &from, sizeof(from))
1365
1366
547
    if (iifd < (int)tiff_nifds && iifd >= 0)
1367
448
    {
1368
448
      int sidx;
1369
      // Per field, not per structure
1370
448
      if (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_DONT_CHECK_DNG_ILLUMINANT))
1371
448
      {
1372
448
        int illidx[2], cmidx[2], calidx[2], abidx;
1373
1.34k
        for (int i = 0; i < 2; i++)
1374
896
        {
1375
896
          illidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_ILLUMINANT);
1376
896
          cmidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_COLORMATRIX);
1377
896
          calidx[i] = IFDCOLORINDEX(iifd, i, LIBRAW_DNGFM_CALIBRATION);
1378
896
        }
1379
448
        abidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE);
1380
        // Data found, all in same ifd, illuminants are inited
1381
448
        if (illidx[0] >= 0 && illidx[0] < (int)tiff_nifds &&
1382
3
          illidx[0] == illidx[1] && illidx[0] == cmidx[0] &&
1383
1
          illidx[0] == cmidx[1] &&
1384
0
          tiff_ifd[illidx[0]].dng_color[0].illuminant > 0 &&
1385
0
          tiff_ifd[illidx[0]].dng_color[1].illuminant > 0)
1386
0
        {
1387
0
          sidx = illidx[0]; // => selected IFD
1388
0
          double cc[4][4], cm[4][3], cam_xyz[4][3];
1389
          // CM -> Color Matrix
1390
          // CC -> Camera calibration
1391
0
          for (int j = 0; j < 4; j++)
1392
0
            for (int i = 0; i < 4; i++)
1393
0
              cc[j][i] = i == j;
1394
0
          int colidx = -1;
1395
1396
          // IS D65 here?
1397
0
          for (int i = 0; i < 2; i++)
1398
0
          {
1399
0
            if (tiff_ifd[sidx].dng_color[i].illuminant == LIBRAW_WBI_D65)
1400
0
            {
1401
0
              colidx = i;
1402
0
              break;
1403
0
            }
1404
0
          }
1405
1406
          // Other daylight-type ill
1407
0
          if (colidx < 0)
1408
0
            for (int i = 0; i < 2; i++)
1409
0
            {
1410
0
              int ill = tiff_ifd[sidx].dng_color[i].illuminant;
1411
0
              if (ill == LIBRAW_WBI_Daylight || ill == LIBRAW_WBI_D55 ||
1412
0
                ill == LIBRAW_WBI_D75 || ill == LIBRAW_WBI_D50 ||
1413
0
                ill == LIBRAW_WBI_Flash)
1414
0
              {
1415
0
                colidx = i;
1416
0
                break;
1417
0
              }
1418
0
            }
1419
0
          if (colidx >= 0) // Selected
1420
0
          {
1421
            // Init camera matrix from DNG
1422
0
            FORCC for (int j = 0; j < 3; j++) cm[c][j] =
1423
0
              tiff_ifd[sidx].dng_color[colidx].colormatrix[c][j];
1424
1425
0
            if (calidx[colidx] == sidx)
1426
0
            {
1427
0
              for (int i = 0; i < colors && i < 4; i++)
1428
0
                FORCC
1429
0
                cc[i][c] = tiff_ifd[sidx].dng_color[colidx].calibration[i][c];
1430
0
            }
1431
1432
0
            if (abidx == sidx)
1433
0
              for (int i = 0; i < colors && i < 4; i++)
1434
0
                FORCC cc[i][c] *= tiff_ifd[sidx].dng_levels.analogbalance[i];
1435
0
            int j;
1436
0
            FORCC for (int i = 0; i < 3; i++)
1437
0
                            for (cam_xyz[c][i] = j = 0; j < colors && j < 4; j++)
1438
0
                  cam_xyz[c][i] +=
1439
0
                      cc[c][j] * cm[j][i]; // add AsShotXY later * xyz[i];
1440
0
            cam_xyz_coeff(cmatrix, cam_xyz);
1441
0
          }
1442
0
        }
1443
448
      }
1444
1445
448
      bool noFujiDNGCrop = makeIs(LIBRAW_CAMERAMAKER_Fujifilm)
1446
5
        && (!strcmp(normalized_model, "S3Pro")
1447
4
          || !strcmp(normalized_model, "S5Pro")
1448
3
          || !strcmp(normalized_model, "S2Pro"));
1449
1450
448
      if (!noFujiDNGCrop) // Promote DNG Crops to raw_inset_crops
1451
446
      {
1452
446
        sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPORIGIN);
1453
446
        int sidx2 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_CROPSIZE);
1454
446
                if (sidx >= 0 && sidx == sidx2 &&
1455
4
                    tiff_ifd[sidx].dng_levels.default_crop[2] > 0 &&
1456
4
                    tiff_ifd[sidx].dng_levels.default_crop[3] > 0)
1457
4
                {
1458
4
                    int lm = tiff_ifd[sidx].dng_levels.default_crop[0];
1459
4
                    int tm = tiff_ifd[sidx].dng_levels.default_crop[1];
1460
4
                    int ww = tiff_ifd[sidx].dng_levels.default_crop[2];
1461
4
                    int hh = tiff_ifd[sidx].dng_levels.default_crop[3];
1462
4
                    if ((lm + ww < int(raw_width) + int(left_margin))
1463
1
                        && (tm + hh < int(raw_height) + int(top_margin))) // Crop data is correct
1464
1
                    {
1465
1
                        imgdata.sizes.raw_inset_crops[0].cleft = left_margin + lm;
1466
1
                        imgdata.sizes.raw_inset_crops[0].cwidth = ww;
1467
1
                        imgdata.sizes.raw_inset_crops[0].ctop = top_margin + tm;
1468
1
                        imgdata.sizes.raw_inset_crops[0].cheight = hh;
1469
1470
1
                        int sidx3 = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_USERCROP);
1471
1
                        if (sidx3 >= 0 && sidx3 == sidx) // No need to check values range, it is checked at parse
1472
0
                        {
1473
0
                            int dt = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[0]);
1474
0
                            int dl = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[1]);
1475
0
                            int db = int(imgdata.sizes.raw_inset_crops[0].cheight * tiff_ifd[sidx].dng_levels.user_crop[2]);
1476
0
                            int dr = int(imgdata.sizes.raw_inset_crops[0].cwidth * tiff_ifd[sidx].dng_levels.user_crop[3]);
1477
1478
0
                            int dh = db - dt;
1479
0
                            int dw = dr - dl;
1480
1481
0
                            if (dh > 0 && dw > 0
1482
0
                                && dh < imgdata.sizes.raw_inset_crops[0].cheight // No need to repeat crop for 0,0,1,1
1483
0
                                && dw < imgdata.sizes.raw_inset_crops[0].cwidth)
1484
0
                            {
1485
0
                                imgdata.sizes.raw_inset_crops[1].cleft = imgdata.sizes.raw_inset_crops[0].cleft + dl;
1486
0
                                imgdata.sizes.raw_inset_crops[1].cwidth = dw;
1487
0
                                imgdata.sizes.raw_inset_crops[1].ctop = imgdata.sizes.raw_inset_crops[0].ctop + dt;
1488
0
                                imgdata.sizes.raw_inset_crops[1].cheight = dh;
1489
0
                            }
1490
0
                        }
1491
1492
1
                    }
1493
4
                }
1494
446
      }
1495
448
      if (!(imgdata.color.dng_color[0].parsedfields &
1496
448
        LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes)
1497
448
      {
1498
448
        sidx = IFDCOLORINDEX(iifd, 0, LIBRAW_DNGFM_FORWARDMATRIX);
1499
448
        if (sidx >= 0)
1500
1
          COPYARR(imgdata.color.dng_color[0].forwardmatrix,
1501
448
            tiff_ifd[sidx].dng_color[0].forwardmatrix);
1502
448
      }
1503
448
      if (!(imgdata.color.dng_color[1].parsedfields &
1504
448
        LIBRAW_DNGFM_FORWARDMATRIX)) // Not set already (Leica makernotes)
1505
448
      {
1506
448
        sidx = IFDCOLORINDEX(iifd, 1, LIBRAW_DNGFM_FORWARDMATRIX);
1507
448
        if (sidx >= 0)
1508
0
          COPYARR(imgdata.color.dng_color[1].forwardmatrix,
1509
448
            tiff_ifd[sidx].dng_color[1].forwardmatrix);
1510
448
      }
1511
1.34k
      for (int ss = 0; ss < 2; ss++)
1512
896
      {
1513
896
        sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_COLORMATRIX);
1514
896
        if (sidx >= 0)
1515
7
          COPYARR(imgdata.color.dng_color[ss].colormatrix,
1516
896
            tiff_ifd[sidx].dng_color[ss].colormatrix);
1517
1518
896
        sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_CALIBRATION);
1519
896
        if (sidx >= 0)
1520
3
          COPYARR(imgdata.color.dng_color[ss].calibration,
1521
896
            tiff_ifd[sidx].dng_color[ss].calibration);
1522
1523
896
        sidx = IFDCOLORINDEX(iifd, ss, LIBRAW_DNGFM_ILLUMINANT);
1524
896
        if (sidx >= 0)
1525
6
          imgdata.color.dng_color[ss].illuminant =
1526
6
          tiff_ifd[sidx].dng_color[ss].illuminant;
1527
896
      }
1528
      // Levels
1529
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ANALOGBALANCE);
1530
448
      if (sidx >= 0)
1531
4
        COPYARR(imgdata.color.dng_levels.analogbalance,
1532
448
          tiff_ifd[sidx].dng_levels.analogbalance);
1533
1534
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BASELINEEXPOSURE);
1535
448
      if (sidx >= 0)
1536
2
        imgdata.color.dng_levels.baseline_exposure =
1537
2
        tiff_ifd[sidx].dng_levels.baseline_exposure;
1538
1539
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_WHITE);
1540
448
      if (sidx >= 0 && tiff_ifd[sidx].dng_levels.dng_whitelevel[0])
1541
41
        COPYARR(imgdata.color.dng_levels.dng_whitelevel,
1542
448
          tiff_ifd[sidx].dng_levels.dng_whitelevel);
1543
407
      else if (tiff_ifd[iifd].sample_format <= 2 && tiff_ifd[iifd].bps > 0 && tiff_ifd[iifd].bps < 32)
1544
114
        FORC4
1545
456
        imgdata.color.dng_levels.dng_whitelevel[c] = (1 << tiff_ifd[iifd].bps) - 1;
1546
1547
      // Copy dng opcode data for selected ifd to imgdata.color: if no opcodes present just 0/null copied
1548
      // DNG OpcodeListN should be in the selected IFD, not at global level (??)
1549
      // Note: pointer is copied; the data will be free'ed at recycle() by mem manager.
1550
1.79k
      for (int i = 0; i < 3; i++)
1551
1.34k
      {
1552
1.34k
        imgdata.color.dng_levels.rawopcodes[i].len = tiff_ifd[iifd].dng_levels.rawopcodes[i].len;
1553
1.34k
        imgdata.color.dng_levels.rawopcodes[i].data = tiff_ifd[iifd].dng_levels.rawopcodes[i].data;
1554
1.34k
      }
1555
1556
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_ASSHOTNEUTRAL);
1557
448
      if (sidx >= 0)
1558
22
      {
1559
22
        COPYARR(imgdata.color.dng_levels.asshotneutral,
1560
22
          tiff_ifd[sidx].dng_levels.asshotneutral);
1561
22
        if (imgdata.color.dng_levels.asshotneutral[0])
1562
15
        {
1563
15
          cam_mul[3] = 0;
1564
15
          FORCC
1565
39
            if (fabs(imgdata.color.dng_levels.asshotneutral[c]) > 0.0001)
1566
21
              cam_mul[c] = 1 / imgdata.color.dng_levels.asshotneutral[c];
1567
15
        }
1568
22
      }
1569
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_BLACK);
1570
448
      if (sidx >= 0)
1571
38
      {
1572
38
        imgdata.color.dng_levels.dng_fblack =
1573
38
          tiff_ifd[sidx].dng_levels.dng_fblack;
1574
38
        imgdata.color.dng_levels.dng_black =
1575
38
          tiff_ifd[sidx].dng_levels.dng_black;
1576
38
        COPYARR(imgdata.color.dng_levels.dng_cblack,
1577
38
          tiff_ifd[sidx].dng_levels.dng_cblack);
1578
38
        COPYARR(imgdata.color.dng_levels.dng_fcblack,
1579
38
          tiff_ifd[sidx].dng_levels.dng_fcblack);
1580
38
      }
1581
1582
1583
448
      if (pifd >= 0)
1584
390
      {
1585
390
        sidx = IFDLEVELINDEX(pifd, LIBRAW_DNGFM_PREVIEWCS);
1586
390
        if (sidx >= 0)
1587
0
          imgdata.color.dng_levels.preview_colorspace =
1588
0
          tiff_ifd[sidx].dng_levels.preview_colorspace;
1589
390
      }
1590
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_OPCODE2);
1591
448
      if (sidx >= 0)
1592
1
        meta_offset = tiff_ifd[sidx].opcode2_offset;
1593
1594
448
      sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINTABLE);
1595
448
      INT64 linoff = -1;
1596
448
      int linlen = 0;
1597
448
      if (sidx >= 0)
1598
4
      {
1599
4
        linoff = tiff_ifd[sidx].lineartable_offset;
1600
4
        linlen = tiff_ifd[sidx].lineartable_len;
1601
4
      }
1602
1603
448
      if (linoff >= 0 && linlen > 0)
1604
2
      {
1605
2
        INT64 pos = ftell(ifp);
1606
2
        fseek(ifp, linoff, SEEK_SET);
1607
2
        linear_table(linlen);
1608
2
        fseek(ifp, pos, SEEK_SET);
1609
2
      }
1610
      // Need to add curve too
1611
448
    }
1612
    /* Copy DNG black level to LibRaw's */
1613
547
    if (load_raw == &LibRaw::lossy_dng_load_raw)
1614
1
    {
1615
1
      maximum = 0xffff;
1616
4
      FORC4 imgdata.color.linear_max[c] = imgdata.color.dng_levels.dng_whitelevel[c] = 0xffff;
1617
1
    }
1618
546
    else
1619
546
    {
1620
546
      maximum = imgdata.color.dng_levels.dng_whitelevel[0];
1621
546
    }
1622
547
    black = imgdata.color.dng_levels.dng_black;
1623
547
    if (tiff_samples == 2 &&
1624
73
        !imgdata.color.dng_levels.dng_cblack[2] &&
1625
70
        !imgdata.color.dng_levels.dng_cblack[3] &&
1626
70
        (imgdata.color.dng_levels.dng_cblack[4] == 1) &&
1627
2
        (imgdata.color.dng_levels.dng_cblack[5] == 1)
1628
1
            && (imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1] == tiff_samples)
1629
547
            ) {
1630
0
      black = imgdata.color.dng_levels.dng_cblack[shot_select];
1631
0
      imgdata.color.dng_levels.dng_cblack[0] = imgdata.color.dng_levels.dng_cblack[1] = 0;
1632
0
      imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1633
0
      imgdata.color.dng_levels.dng_fcblack[0] = imgdata.color.dng_levels.dng_fcblack[1] = 0.0f;
1634
0
      imgdata.color.dng_levels.dng_fcblack[4] = imgdata.color.dng_levels.dng_fcblack[5] = 0.0f;
1635
0
    }
1636
547
    else if (tiff_samples == 2 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples
1637
73
      == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1])
1638
63
    {
1639
63
      unsigned ff = filters;
1640
63
      if (filters > 999 && colors == 3)
1641
10
        filters |= ((filters >> 2 & 0x22222222) | (filters << 2 & 0x88888888)) &
1642
10
        filters << 1;
1643
1644
      /* Special case, Fuji SuperCCD dng */
1645
63
      int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 };
1646
63
      int i = 6 + shot_select;
1647
1.94k
      for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++)
1648
2.39k
        for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++)
1649
512
        {
1650
512
          csum[FC(row, col)] += imgdata.color.dng_levels.dng_cblack[i];
1651
512
          ccount[FC(row, col)]++;
1652
512
          i += tiff_samples;
1653
512
        }
1654
315
      for (int q = 0; q < 4; q++)
1655
252
        if (ccount[q])
1656
10
          imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q];
1657
63
      imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1658
63
      filters = ff;
1659
63
    }
1660
484
    else if (tiff_samples > 2 && tiff_samples <= 4 && imgdata.color.dng_levels.dng_cblack[4] * imgdata.color.dng_levels.dng_cblack[5] * tiff_samples
1661
92
      == imgdata.color.dng_levels.dng_cblack[LIBRAW_CBLACK_SIZE - 1])
1662
91
    {
1663
      /* Special case, per_channel blacks in RepeatDim, average for per-channel */
1664
91
      int csum[4] = { 0,0,0,0 }, ccount[4] = { 0,0,0,0 };
1665
91
      int i = 6;
1666
621
      for (unsigned row = 0; row < imgdata.color.dng_levels.dng_cblack[4]; row++)
1667
533
        for (unsigned col = 0; col < imgdata.color.dng_levels.dng_cblack[5]; col++)
1668
12
          for (unsigned q = 0; q < tiff_samples && q < 4; q++)
1669
9
          {
1670
9
            csum[q] += imgdata.color.dng_levels.dng_cblack[i];
1671
9
            ccount[q]++;
1672
9
            i++;
1673
9
          }
1674
455
      for (int q = 0; q < 4; q++)
1675
364
        if (ccount[q])
1676
9
          imgdata.color.dng_levels.dng_cblack[q] += csum[q] / ccount[q];
1677
91
      imgdata.color.dng_levels.dng_cblack[4] = imgdata.color.dng_levels.dng_cblack[5] = 0;
1678
91
    }
1679
1680
547
    memmove(cblack, imgdata.color.dng_levels.dng_cblack, sizeof(cblack));
1681
1682
547
    if (iifd < (int)tiff_nifds && iifd >= 0)
1683
448
    {
1684
448
      int sidx = IFDLEVELINDEX(iifd, LIBRAW_DNGFM_LINEARRESPONSELIMIT);
1685
448
      if (sidx >= 0)
1686
25
      {
1687
25
        imgdata.color.dng_levels.LinearResponseLimit =
1688
25
          tiff_ifd[sidx].dng_levels.LinearResponseLimit;
1689
25
        if (imgdata.color.dng_levels.LinearResponseLimit > 0.1 &&
1690
24
          imgdata.color.dng_levels.LinearResponseLimit <= 1.0)
1691
18
        {
1692
          // And approx promote it to linear_max:
1693
18
          int bl4 = 0, bl64 = 0;
1694
52
          for (int chan = 0; chan < colors && chan < 4; chan++)
1695
34
            bl4 += cblack[chan];
1696
18
          bl4 /= LIM(colors, 1, 4);
1697
1698
18
          if (cblack[4] * cblack[5] > 0)
1699
9
          {
1700
9
            unsigned cnt = 0;
1701
11.0k
            for (unsigned q = 0; q < 4096 && q < cblack[4] * cblack[5]; q++)
1702
11.0k
            {
1703
11.0k
              bl64 += cblack[q + 6];
1704
11.0k
              cnt++;
1705
11.0k
            }
1706
9
            bl64 /= LIM(cnt, 1, 4096);
1707
9
          }
1708
18
          int rblack = black + bl4 + bl64;
1709
52
          for (int chan = 0; chan < colors && chan < 4; chan++)
1710
34
            imgdata.color.linear_max[chan] =
1711
34
            unsigned(
1712
34
            (maximum - rblack) *
1713
34
              imgdata.color.dng_levels.LinearResponseLimit +
1714
34
              rblack
1715
34
              );
1716
18
                    if (imgdata.color.linear_max[1] && !imgdata.color.linear_max[3])
1717
2
                        imgdata.color.linear_max[3] = imgdata.color.linear_max[1];
1718
18
        }
1719
25
      }
1720
448
    }
1721
547
  }
1722
547
}
1723
1724
void LibRaw::identify_finetune_pentax()
1725
11.3k
{
1726
11.3k
    if (dng_version && data_offset)
1727
175
    {
1728
975
        for(int i = 0; i < (int)tiff_nifds; i++)
1729
876
            if (tiff_ifd[i].offset == data_offset)
1730
76
            {
1731
76
                if (tiff_ifd[i].phint == 34892) return; // Linear DNG made from Pentax source
1732
73
                break;
1733
76
            }
1734
175
    }
1735
1736
11.3k
  if (makeIs(LIBRAW_CAMERAMAKER_Pentax) ||
1737
10.9k
    makeIs(LIBRAW_CAMERAMAKER_Samsung)) {
1738
571
    if (height == 2624 &&
1739
1
      width == 3936) // Pentax K10D, Samsung GX10;
1740
0
    {
1741
0
      height = 2616;
1742
0
      width = 3896;
1743
0
    }
1744
571
    if (height == 3136 &&
1745
1
      width == 4864) // Pentax K20D, Samsung GX20;
1746
0
    {
1747
0
      height = 3124;
1748
0
      width = 4688;
1749
0
      filters = 0x16161616;
1750
0
    }
1751
571
  }
1752
1753
11.3k
  if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) {
1754
375
    if ((width == 4352) &&
1755
7
      ((unique_id == PentaxID_K_r) ||
1756
7
      (unique_id == PentaxID_K_x)))
1757
0
    {
1758
0
      width = 4309;
1759
0
      filters = 0x16161616;
1760
0
    }
1761
375
    if ((width >= 4960) &&
1762
106
      ((unique_id == PentaxID_K_5) ||
1763
104
      (unique_id == PentaxID_K_5_II) ||
1764
104
        (unique_id == PentaxID_K_5_II_s)))
1765
3
    {
1766
3
      left_margin = 10;
1767
3
      width = 4950;
1768
3
      filters = 0x16161616;
1769
3
    }
1770
375
    if ((width == 6080) && (unique_id == PentaxID_K_70))
1771
0
    {
1772
0
      height = 4016;
1773
0
      top_margin = 32;
1774
0
      width = 6020;
1775
0
      left_margin = 60;
1776
0
    }
1777
375
    if ((width == 4736) && (unique_id == PentaxID_K_7))
1778
0
    {
1779
0
      height = 3122;
1780
0
      width = 4684;
1781
0
      filters = 0x16161616;
1782
0
      top_margin = 2;
1783
0
    }
1784
375
    if (width == 6080 && (unique_id == PentaxID_KF))
1785
0
    {
1786
0
      top_margin = 28;
1787
0
      height = 4024;
1788
0
      left_margin = 56;
1789
0
      width = 6024;
1790
0
    }
1791
375
    if ((width == 6080) && (unique_id == PentaxID_K_3_II))
1792
1
    {
1793
1
      left_margin = 4;
1794
1
      width = 6040;
1795
1
    }
1796
375
        if ((width == 6304) && (unique_id == PentaxID_K_3_III)) // From DNG ActiveArea
1797
0
        {
1798
0
          left_margin = 26;
1799
0
          width = 6224;
1800
0
          top_margin = 34;
1801
0
          height = 4160;
1802
0
        }
1803
375
        if (unique_id == PentaxID_K_3_III_Mono) 
1804
0
        {
1805
0
      if (width == 6304)
1806
0
      {
1807
0
              left_margin = 26;
1808
0
              width = 6224;
1809
0
              top_margin = 34;
1810
0
              height = 4160;
1811
0
            }
1812
0
      filters = 0;
1813
0
      colors = 1;
1814
0
        }
1815
375
        if ((width == 6112) && (unique_id == PentaxID_KP))
1816
0
    {
1817
      // From DNG, maybe too strict
1818
0
      left_margin = 54;
1819
0
      top_margin = 28;
1820
0
      width = 6028;
1821
0
      height = raw_height - top_margin;
1822
0
    }
1823
375
    if ((width == 6080) && (unique_id == PentaxID_K_3))
1824
0
    {
1825
0
      left_margin = 4;
1826
0
      width = 6040;
1827
0
    }
1828
375
    if ((width == 7424) && (unique_id == PentaxID_645D))
1829
0
    {
1830
0
      height = 5502;
1831
0
      width = 7328;
1832
0
      filters = 0x61616161;
1833
0
      top_margin = 29;
1834
0
      left_margin = 48;
1835
0
    }
1836
375
  }
1837
10.9k
  else if (makeIs(LIBRAW_CAMERAMAKER_Ricoh) &&
1838
139
    (height == 3014) && (width == 4096))  // Ricoh GX200
1839
0
    width = 4014;
1840
11.3k
}
1841
1842
void LibRaw::identify_finetune_by_filesize(INT64 fsize)
1843
10.7k
{
1844
1845
10.7k
  if (fsize == 4771840)
1846
0
  { // hack Nikon 3mpix: E880, E885, E990, E995;
1847
    // Olympus C-3030Z
1848
0
    if (!timestamp && nikon_e995())
1849
0
      strcpy(model, "E995");
1850
0
  }
1851
10.7k
  else if (fsize == 2940928)
1852
0
  { // hack Nikon 2mpix: E2100, E2500
1853
0
    if (!timestamp && !nikon_e2100())
1854
0
      strcpy(model, "E2500");
1855
0
  }
1856
10.7k
  else if (fsize == 4775936)
1857
0
  { // hack Nikon 3mpix: E3100, E3200, E3500, E3700;
1858
    // Pentax "Optio 33WR";
1859
    // Olympus C-740UZ
1860
0
    if (!timestamp)
1861
0
      nikon_3700();
1862
0
  }
1863
10.7k
  else if (fsize == 5869568)
1864
0
  { // hack Nikon 4mpix: E4300;
1865
    // hack Minolta "DiMAGE Z2"
1866
0
    if (!timestamp && minolta_z2())
1867
0
    {
1868
0
      maker_index = LIBRAW_CAMERAMAKER_Minolta;
1869
0
      strcpy(make, "Minolta");
1870
0
      strcpy(model, "DiMAGE Z2");
1871
0
    }
1872
0
  }
1873
10.7k
}
1874
1875
void LibRaw::identify_finetune_dcr(char head[64], INT64 fsize, INT64 flen)
1876
10.7k
{
1877
10.7k
  static const short pana[][6] = {
1878
    // raw_width, raw_height, left_margin, top_margin, width_increment,
1879
    // height_increment
1880
10.7k
    {3130, 1743, 4, 0, -6, 0},      /* 00 */
1881
10.7k
    {3130, 2055, 4, 0, -6, 0},      /* 01 */
1882
10.7k
    {3130, 2319, 4, 0, -6, 0},      /* 02 DMC-FZ8 */
1883
10.7k
    {3170, 2103, 18, 0, -42, 20},   /* 03 */
1884
10.7k
    {3170, 2367, 18, 13, -42, -21}, /* 04 */
1885
10.7k
    {3177, 2367, 0, 0, -1, 0},      /* 05 DMC-L1 */
1886
10.7k
    {3304, 2458, 0, 0, -1, 0},      /* 06 DMC-FZ30 */
1887
10.7k
    {3330, 2463, 9, 0, -5, 0},      /* 07 DMC-FZ18 */
1888
10.7k
    {3330, 2479, 9, 0, -17, 4},     /* 08 */
1889
10.7k
    {3370, 1899, 15, 0, -44, 20},   /* 09 */
1890
10.7k
    {3370, 2235, 15, 0, -44, 20},   /* 10 */
1891
10.7k
    {3370, 2511, 15, 10, -44, -21}, /* 11 */
1892
10.7k
    {3690, 2751, 3, 0, -8, -3},     /* 12 DMC-FZ50 */
1893
10.7k
    {3710, 2751, 0, 0, -3, 0},      /* 13 DMC-L10 */
1894
10.7k
    {3724, 2450, 0, 0, 0, -2},      /* 14 */
1895
10.7k
    {3770, 2487, 17, 0, -44, 19},   /* 15 */
1896
10.7k
    {3770, 2799, 17, 15, -44, -19}, /* 16 */
1897
10.7k
    {3880, 2170, 6, 0, -6, 0},      /* 17 DMC-LX1 */
1898
10.7k
    {4060, 3018, 0, 0, 0, -2},      /* 18 DMC-FZ35, DMC-FZ38 */
1899
10.7k
    {4290, 2391, 3, 0, -8, -1},     /* 19 DMC-LX2 */
1900
10.7k
    {4330, 2439, 17, 15, -44, -19}, /* 20 "D-LUX 3" */
1901
10.7k
    {4508, 2962, 0, 0, -3, -4},     /* 21 */
1902
10.7k
    {4508, 3330, 0, 0, -3, -6},     /* 22 */
1903
10.7k
    {10480, 7794, 0, 0, -2, 0},     /* 23: G9 in high-res */
1904
10.7k
        {11560, 8680, 8, 8, -16, -16},     /* 24: GH7 in high-res */
1905
10.7k
  };
1906
10.7k
  int i,c;
1907
10.7k
  struct jhead jh;
1908
1909
10.7k
  if (makeIs(LIBRAW_CAMERAMAKER_Canon) 
1910
1.32k
        && ( !tiff_flip || unique_id == CanonID_EOS_40D)
1911
45
    && !(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CANON_IGNORE_MAKERNOTES_ROTATION)
1912
    // Do not check Auto-Rotate, or AutoRotateMode is not Off (0)
1913
45
    && (!(imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CANON_CHECK_CAMERA_AUTO_ROTATION_MODE) || imCanon.AutoRotateMode )
1914
45
        && imCanon.MakernotesFlip)
1915
4
  {
1916
4
    tiff_flip = imCanon.MakernotesFlip;
1917
4
  }
1918
1919
10.7k
  else if (makeIs(LIBRAW_CAMERAMAKER_Nikon))
1920
492
  {
1921
492
    if (!load_raw)
1922
279
      load_raw = &LibRaw::packed_load_raw;
1923
492
    if (model[0] == 'E') // Nikon E8800, E8700, E8400, E5700, E5400, E5000,
1924
               // others are diag hacks?
1925
29
      load_flags |= !data_offset << 2 | 2;
1926
492
  }
1927
  /* Set parameters based on camera name (for non-DNG files). */
1928
1929
  /* Always 512 for arw2_load_raw */
1930
10.2k
  else if (makeIs(LIBRAW_CAMERAMAKER_Sony) &&
1931
1.10k
    (raw_width > 3888) && !black && !cblack[0])
1932
78
  {
1933
78
    black = (load_raw == &LibRaw::sony_arw2_load_raw)
1934
78
      ? 512
1935
78
      : (128 << (tiff_bps - 12));
1936
78
  }
1937
1938
10.7k
  if (is_foveon) {
1939
0
    if (height * 2 < width)
1940
0
      pixel_aspect = 0.5;
1941
0
    if (height > width)
1942
0
      pixel_aspect = 2;
1943
0
    filters = 0;
1944
1945
0
  }
1946
10.7k
  else if (makeIs(LIBRAW_CAMERAMAKER_Pentax)) {
1947
303
    if ((unique_id == PentaxID_K_1) ||
1948
302
      (unique_id == PentaxID_K_1_Mark_II)) {
1949
2
      top_margin = 18;
1950
2
      height = raw_height - top_margin;
1951
2
      if (raw_width == 7392) {
1952
0
        left_margin = 6;
1953
0
        width = 7376;
1954
0
      }
1955
1956
2
    }
1957
301
    else if (unique_id == PentaxID_Optio_S_V101) { // (fsize == 3178560)
1958
0
      cam_mul[0] *= 4;
1959
0
      cam_mul[2] *= 4;
1960
1961
0
    }
1962
301
    else if (unique_id == PentaxID_Optio_33WR) { // (fsize == 4775936)
1963
1
      flip = 1;
1964
1
      filters = 0x16161616;
1965
1966
1
    }
1967
300
    else if (unique_id == PentaxID_staristD) {
1968
2
      load_raw = &LibRaw::unpacked_load_raw;
1969
      /* data_error = -1; */ /* No way to know why data_error was raised in dcraw.c, looks not needed esp. for unpacked_load_raw */
1970
2
    }
1971
298
    else if (unique_id == PentaxID_staristDS) {
1972
3
      height -= 2;
1973
3
    }
1974
1975
303
  }
1976
10.4k
  else if (makeIs(LIBRAW_CAMERAMAKER_Canon)) {
1977
1.32k
    if (tiff_bps == 15) { // Canon sRAW
1978
23
      if (width == 3344)
1979
0
        width = 3272;
1980
23
      else if (width == 3872)
1981
0
        width = 3866;
1982
1983
23
      if (height > width) {
1984
4
        SWAP(height, width);
1985
4
        SWAP(raw_height, raw_width);
1986
4
      }
1987
23
      if (width == 7200 &&
1988
0
        height == 3888) { // Canon EOS 5DS (R);
1989
0
        raw_width = width = 6480;
1990
0
        raw_height = height = 4320;
1991
0
      }
1992
23
      filters = 0;
1993
23
      tiff_samples = colors = 3;
1994
23
      load_raw = &LibRaw::canon_sraw_load_raw;
1995
23
    }
1996
1997
1.32k
    if (!strcmp(normalized_model, "PowerShot 600")) {
1998
7
      height = 613;
1999
7
      width = 854;
2000
7
      raw_width = 896;
2001
7
      colors = 4;
2002
7
      filters = 0xe1e4e1e4;
2003
7
      load_raw = &LibRaw::canon_600_load_raw;
2004
2005
7
    }
2006
1.31k
    else if (!strcmp(normalized_model, "PowerShot A5") ||
2007
1.31k
      !strcmp(normalized_model, "PowerShot A5 Zoom")) {
2008
2
      height = 773;
2009
2
      width = 960;
2010
2
      raw_width = 992;
2011
2
      pixel_aspect = 256 / 235.0;
2012
2
      filters = 0x1e4e1e4e;
2013
2
      goto canon_a5;
2014
2015
2
    }
2016
1.31k
    else if (!strcmp(normalized_model, "PowerShot A50")) {
2017
1
      height = 968;
2018
1
      width = 1290;
2019
1
      raw_width = 1320;
2020
1
      filters = 0x1b4e4b1e;
2021
1
      goto canon_a5;
2022
2023
1
    }
2024
1.31k
    else if (!strcmp(normalized_model, "PowerShot Pro70")) {
2025
1
      height = 1024;
2026
1
      width = 1552;
2027
1
      filters = 0x1e4b4e1b;
2028
4
    canon_a5:
2029
4
      colors = 4;
2030
4
      tiff_bps = 10;
2031
4
      load_raw = &LibRaw::packed_load_raw;
2032
4
      load_flags = 40;
2033
2034
4
    }
2035
1.31k
    else if (!strcmp(normalized_model, "PowerShot Pro90 IS") ||
2036
1.31k
      !strcmp(normalized_model, "PowerShot G1")) {
2037
3
      colors = 4;
2038
3
      filters = 0xb4b4b4b4;
2039
2040
3
    }
2041
1.30k
    else if (!strcmp(normalized_model, "PowerShot A610")) { // chdk hack
2042
3
      if (canon_s2is()) {
2043
2
        strcpy(model + 10, "S2 IS");
2044
2
        strcpy(normalized_model + 10, "S2 IS");
2045
2
      }
2046
2047
3
    }
2048
1.30k
    else if (!strcmp(normalized_model, "PowerShot SX220 HS")) { // chdk hack
2049
0
      mask[1][3] = -4;
2050
0
      top_margin = 16;
2051
0
      left_margin = 92;
2052
2053
0
    }
2054
1.30k
    else if (!strcmp(normalized_model, "PowerShot S120")) { // chdk hack
2055
1
      raw_width = 4192;
2056
1
      raw_height = 3062;
2057
1
      width = 4022;
2058
1
      height = 3016;
2059
1
      mask[0][0] = top_margin = 31;
2060
1
      mask[0][2] = top_margin + height;
2061
1
      left_margin = 120;
2062
1
      mask[0][1] = 23;
2063
1
      mask[0][3] = 72;
2064
2065
1
    }
2066
1.30k
    else if (!strcmp(normalized_model, "PowerShot G16")) {
2067
1
      mask[0][0] = 0;
2068
1
      mask[0][2] = 80;
2069
1
      mask[0][1] = 0;
2070
1
      mask[0][3] = 16;
2071
1
      top_margin = 29;
2072
1
      left_margin = 120;
2073
1
      width = raw_width - left_margin - 48;
2074
1
      height = raw_height - top_margin - 14;
2075
2076
1
    }
2077
1.30k
    else if (!strcmp(normalized_model, "PowerShot SX50 HS")) {
2078
0
      top_margin = 17;
2079
0
    }
2080
2081
1.32k
  }
2082
2083
9.13k
  else if (makeIs(LIBRAW_CAMERAMAKER_Nikon)) {
2084
492
    if (!strcmp(model, "D1"))
2085
1
    {
2086
1
      imgdata.other.analogbalance[0] = cam_mul[0];
2087
1
      imgdata.other.analogbalance[2] = cam_mul[2];
2088
1
      imgdata.other.analogbalance[1] = imgdata.other.analogbalance[3] =
2089
1
        cam_mul[1];
2090
1
      cam_mul[0] = cam_mul[1] = cam_mul[2] = 1.0f;
2091
1
    }
2092
2093
491
    else if (!strcmp(model, "D1X"))
2094
1
    {
2095
1
      width -= 4;
2096
1
      pixel_aspect = 0.5;
2097
1
    }
2098
490
    else if (!strcmp(model, "D40X") ||
2099
490
      !strcmp(model, "D60") ||
2100
482
      !strcmp(model, "D80") ||
2101
481
      !strcmp(model, "D3000"))
2102
10
    {
2103
10
      height -= 3;
2104
10
      width -= 4;
2105
10
    }
2106
480
    else if (!strcmp(model, "D3") ||
2107
478
      !strcmp(model, "D3S") ||
2108
477
      !strcmp(model, "D700"))
2109
4
    {
2110
4
      width -= 4;
2111
4
      left_margin = 2;
2112
4
    }
2113
476
    else if (!strcmp(model, "D3100"))
2114
1
    {
2115
1
      width -= 28;
2116
1
      left_margin = 6;
2117
1
    }
2118
475
    else if (!strcmp(model, "D5000") ||
2119
474
      !strcmp(model, "D90"))
2120
3
    {
2121
3
      width -= 42;
2122
3
    }
2123
472
    else if (!strcmp(model, "D5100") ||
2124
471
      !strcmp(model, "D7000") ||
2125
470
      !strcmp(model, "COOLPIX A"))
2126
2
    {
2127
2
      width -= 44;
2128
2
    }
2129
470
    else if (!strcmp(model, "D3200") ||
2130
469
      !strcmp(model, "D600") ||
2131
468
      !strcmp(model, "D610") ||
2132
467
      !strncmp(model, "D800", 4)) // Nikons: D800, D800E
2133
5
    {
2134
5
      width -= 46;
2135
5
    }
2136
465
    else if (!strcmp(model, "D4") ||
2137
463
      !strcmp(model, "Df"))
2138
3
    {
2139
3
      width -= 52;
2140
3
      left_margin = 2;
2141
3
    }
2142
462
    else if (!strcmp(model, "D500"))
2143
1
    {
2144
      // Empty - to avoid width-1 below
2145
1
    }
2146
461
    else if (!strncmp(model, "D40", 3) ||
2147
459
      !strncmp(model, "D50", 3) ||
2148
457
      !strncmp(model, "D70", 3))
2149
7
    {
2150
7
      width--;
2151
7
    }
2152
454
    else if (!strcmp(model, "D100"))
2153
2
    {
2154
2
      if (load_flags) // compressed NEF
2155
1
        raw_width = (width += 3) + 3;
2156
2
    }
2157
452
    else if (!strcmp(model, "D200"))
2158
1
    {
2159
1
      left_margin = 1;
2160
1
      width -= 4;
2161
1
      filters = 0x94949494;
2162
1
    }
2163
451
    else if (!strncmp(model, "D2H", 3)) // Nikons: D2H, D2Hs
2164
8
    {
2165
8
      left_margin = 6;
2166
8
      width -= 14;
2167
8
    }
2168
443
    else if (!strncmp(model, "D2X", 3)) // Nikons: D2X, D2Xs
2169
3
    {
2170
3
      if (width == 3264) // in-camera Hi-speed crop: On
2171
0
        width -= 32;
2172
3
      else
2173
3
        width -= 8;
2174
3
    }
2175
440
    else if (!strncmp(model, "D300", 4)) // Nikons: D300, D300s
2176
4
    {
2177
4
      width -= 32;
2178
4
    }
2179
436
    else if (raw_width == 4032) // Nikon "COOLPIX P7700", "COOLPIX P7800",
2180
                  // "COOLPIX P330", "COOLPIX P340"
2181
1
    {
2182
1
      if (!strcmp(normalized_model, "COOLPIX P7700"))
2183
0
      {
2184
0
        maximum = 65504;
2185
0
        load_flags = 0;
2186
0
      }
2187
1
      else if (!strcmp(normalized_model, "COOLPIX P7800"))
2188
0
      {
2189
0
        maximum = 65504;
2190
0
        load_flags = 0;
2191
0
      }
2192
1
      else if (!strcmp(model, "COOLPIX P340"))
2193
0
      {
2194
0
        load_flags = 0;
2195
0
      }
2196
1
    }
2197
435
    else if (!strncmp(model, "COOLPIX P", 9) &&
2198
10
      raw_width != 4032) // Nikon "COOLPIX P1000", "COOLPIX P6000",
2199
                 // "COOLPIX P7000", "COOLPIX P7100"
2200
10
    {
2201
10
      load_flags = 24;
2202
10
      filters = 0x94949494;
2203
      /* the following 'if' is most probably obsolete, because we now read black
2204
       * level from metadata */
2205
10
      if ((model[9] == '7') && /* P7000, P7100 */
2206
3
        ((iso_speed >= 400) || (iso_speed == 0)) &&
2207
2
        !strstr(software, "V1.2")) /* v. 1.2 seen for P7000 only */
2208
2
        black = 255;
2209
10
    }
2210
425
    else if (!strncmp(model, "COOLPIX B700", 12))
2211
2
    {
2212
2
      load_flags = 24;
2213
2
    }
2214
423
    else if (!strncmp(model, "1 ",
2215
423
      2)) // Nikons: "1 AW1", "1 J1", "1 J2", "1 J3", "1 J4",
2216
        // "1 J5", "1 S1", "1 S2", "1 V1", "1 V2", "1 V3"
2217
6
    {
2218
6
      height -= 2;
2219
6
    }
2220
417
    else if (fsize == 1581060) // hack Nikon 1mpix: E900
2221
0
    {
2222
0
      simple_coeff(3);
2223
0
      pre_mul[0] = 1.2085f;
2224
0
      pre_mul[1] = 1.0943f;
2225
0
      pre_mul[3] = 1.1103f;
2226
0
    }
2227
417
    else if ((fsize == 4771840) &&  // hack Nikon 3mpix: E880, E885, E990
2228
0
      strcmp(model, "E995")) // but not E995
2229
0
    {
2230
0
      filters = 0xb4b4b4b4;
2231
0
      simple_coeff(3);
2232
0
      pre_mul[0] = 1.196f;
2233
0
      pre_mul[1] = 1.246f;
2234
0
      pre_mul[2] = 1.018f;
2235
0
    }
2236
417
    else if ((fsize == 4775936) && // hack Nikon 3mpix: E3100, E3200, E3500
2237
0
      (atoi(model + 1) < 3700)) // but not E3700;
2238
0
    {
2239
0
      filters = 0x49494949;
2240
0
    }
2241
417
    else if (fsize == 5869568) // hack Nikon 4mpix: E4300;
2242
0
    {
2243
0
      load_flags = 6;
2244
0
    }
2245
417
    else if (!strcmp(model, "E2500"))
2246
10
    {
2247
10
      height -= 2;
2248
10
      load_flags = 6;
2249
10
      colors = 4;
2250
10
      filters = 0x4b4b4b4b;
2251
10
    }
2252
492
  }
2253
2254
8.64k
  else if (makeIs(LIBRAW_CAMERAMAKER_Olympus)) {
2255
521
    if (OlyID == OlyID_C_740UZ) { // (fsize == 4775936)
2256
8
      i = int(find_green(12, 32, 1188864, 3576832));
2257
8
      c = int(find_green(12, 32, 2383920, 2387016));
2258
8
      if (abs(i) < abs(c)) {
2259
0
        SWAP(i, c);
2260
0
        load_flags = 24;
2261
0
      }
2262
8
      if (i < 0)
2263
0
        filters = 0x61616161;
2264
8
    }
2265
513
    else if (OlyID == OlyID_C_770UZ) {
2266
1
      height = 1718;
2267
1
      width = 2304;
2268
1
      filters = 0x16161616;
2269
1
      load_raw = &LibRaw::packed_load_raw;
2270
1
      load_flags = 30;
2271
1
    }
2272
512
    else {
2273
512
      height += height & 1;
2274
512
      if (exif_cfa)
2275
1
        filters = exif_cfa;
2276
2277
512
      if (width == 4100) // Olympus E-PL2, E-PL1, E-P2, E-P1, E-620, E-600, E-5, E-30;
2278
0
        width -= 4;
2279
2280
512
      if (width == 4080) // Olympus E-PM1, E-PL3, E-P3;
2281
0
        width -= 24;
2282
2283
512
      if (width == 10400) // Olympus PEN-F, E-M1-II, E-M1-III, E-M1X, OM-1
2284
1
        width -= 12;
2285
2286
512
      if (width == 8200) // E-M1-III in 50Mp mode, E-M1X
2287
0
        width -= 30;
2288
2289
512
      if (width == 8180) // OM-1 in 50Mp
2290
1
              width -= 10;
2291
2292
512
      if (width == 9280) { // Olympus E-M5 Mark II;
2293
0
        width -= 6;
2294
0
        height -= 6;
2295
0
      }
2296
2297
512
      if (load_raw == &LibRaw::unpacked_load_raw) {
2298
25
        load_flags = 4;
2299
25
        if (imOly.ValidBits == 10) load_flags += 2;
2300
25
      }
2301
512
      tiff_bps = imOly.ValidBits;
2302
512
      if (tiff_bps == 14)
2303
0
      {
2304
0
        black *= 4;
2305
0
        FORC(4) cblack[c] *= 4;
2306
0
        FORC(4) imgdata.color.linear_max[c] *= 4;
2307
0
        FORC(MIN(cblack[4] * cblack[5], LIBRAW_CBLACK_SIZE - 6)) cblack[c+6] *= 4;
2308
0
      }
2309
2310
2311
512
      if ((OlyID == OlyID_E_300) ||
2312
511
        (OlyID == OlyID_E_500)) {
2313
1
        width -= 20;
2314
1
        if (load_raw == &LibRaw::unpacked_load_raw) {
2315
0
          maximum = 0xfc3;
2316
0
          memset(cblack, 0, sizeof cblack);
2317
0
        }
2318
1
      }
2319
511
      else if (OlyID == OlyID_STYLUS_1) {
2320
1
        width -= 16;
2321
1
        maximum = 0xfff;
2322
2323
1
      }
2324
510
      else if (OlyID == OlyID_E_330) {
2325
2
        width -= 30;
2326
2
        if (load_raw == &LibRaw::unpacked_load_raw)
2327
1
          maximum = 0xf79;
2328
2329
2
      }
2330
508
      else if (OlyID == OlyID_SP_550UZ) {
2331
0
        thumb_length = unsigned(flen - INT64(thumb_offset = 0xa39800));
2332
0
        thumb_height = 480;
2333
0
        thumb_width = 640;
2334
2335
0
      }
2336
508
      else if (OlyID == OlyID_TG_4) {
2337
1
        width -= 16;
2338
1
      }
2339
507
      else if (
2340
507
         (OlyID == OlyID_TG_5) ||
2341
506
         (OlyID == OlyID_TG_6) ||
2342
502
         (OlyID == OlyID_TG_7)
2343
507
        ) {
2344
6
        width -= 26;
2345
6
      }
2346
512
    }
2347
2348
521
  }
2349
8.12k
  else if (makeIs(LIBRAW_CAMERAMAKER_RoverShot) &&
2350
2
    (fsize == 6291456)) { // RoverShot 3320AF
2351
0
    fseek(ifp, 0x300000, SEEK_SET);
2352
0
    if ((order = guess_byte_order(0x10000)) == 0x4d4d)
2353
0
    {
2354
0
      height -= (top_margin = 16);
2355
0
      width -= (left_margin = 28);
2356
0
      maximum = 0xf5c0;
2357
0
      strcpy(make, "ISG");
2358
0
      maker_index = LIBRAW_CAMERAMAKER_ISG;
2359
0
      model[0] = 0;
2360
0
    }
2361
2362
0
  }
2363
8.12k
  else if (makeIs(LIBRAW_CAMERAMAKER_Fujifilm)) {
2364
839
    if (!imFuji.RAFDataGeneration && (raw_width == 2944)) // S2Pro
2365
1
    {
2366
1
      height = 2144;
2367
1
      width = 2880;
2368
1
      flip = 6;
2369
1
    }
2370
838
    else if (load_raw != &LibRaw::packed_load_raw &&
2371
836
             strncmp(model, "X-", 2)              &&
2372
557
             filters >= 1000) // Bayer and not an X-model
2373
545
      maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00;
2374
2375
839
    if (!FujiCropMode && imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096))
2376
9
    {
2377
9
      width  = imFuji.RAFData_ImageSizeTable[0];
2378
9
      height = imFuji.RAFData_ImageSizeTable[1];
2379
9
    }
2380
830
    else if (FujiCropMode == 1) // FF crop on GFX
2381
1
    {
2382
1
      width = raw_width;
2383
1
      height = raw_height;
2384
1
    }
2385
        // Do we need set height = raw_height for CropMode == 2 for all cameras??
2386
829
    else if (FujiCropMode == 4) // electronic shutter, high speed mode (1.25x crop)
2387
0
    {
2388
0
      height = raw_height;
2389
0
    }
2390
2391
839
    top_margin = (raw_height >= height) ? (raw_height - height) >> 2 << 1 : 0;
2392
839
    left_margin = (raw_width >= width) ? (raw_width - width) >> 2 << 1 : 0;
2393
2394
839
    if (imFuji.RAFDataGeneration && (imFuji.RAFDataGeneration != 4096)) {
2395
9
      switch (raw_width) {
2396
0
      case 2944:                // X-S1, X10, XF1
2397
0
        filters = 0x16161616;
2398
0
        break;
2399
0
      case 4096:                // X20, X30, XQ1, XQ2
2400
0
      case 5120:                // X-Pro1, X-E1, X-A1, X-A2, X-M1
2401
0
      case 6048:                // lossless compressed X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3
2402
0
      case 6160:                // uncompressed (unpacked) X100F, X-T2, X-T20, X-Pro2, X-H1, X-E3
2403
0
        left_margin = 0;
2404
0
        break;
2405
0
      case 4992:                // X-E2S, X-E2, X-T10, X-T1, X100S, X100T, X70
2406
0
        left_margin = 4;
2407
0
        break;
2408
1
    case 7872: // X-H2, full image
2409
1
      switch (FujiCropMode)
2410
1
      {
2411
1
      case 0: // no crop
2412
1
        top_margin = 6;
2413
1
        left_margin = 0;
2414
1
        width = 7752;
2415
1
        height = 5178;
2416
1
        break;
2417
0
          default:
2418
            /* try to guess from crop inset*/
2419
0
            if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width &&
2420
0
                imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height)
2421
0
            {
2422
0
              top_margin = imgdata.sizes.raw_inset_crops[0].ctop;
2423
0
              left_margin = imgdata.sizes.raw_inset_crops[0].cleft;
2424
0
              width = imgdata.sizes.raw_inset_crops[0].cwidth;
2425
0
              height = imgdata.sizes.raw_inset_crops[0].cheight;
2426
0
            }
2427
0
            break;
2428
1
      }
2429
1
      break;
2430
2
      case 6336: // X-H2S, XT30-III
2431
2
      switch (FujiCropMode)
2432
2
      {
2433
2
          case 0: // no crop
2434
2
            top_margin = 6;
2435
2
            left_margin = 0;
2436
2
      if(!strcasecmp(model,"X-S20") || !strcasecmp(model, "X-T30 III"))
2437
0
              width = 6252;
2438
2
      else
2439
2
        width = 6264;
2440
2
            height = 4176;
2441
2
      break;
2442
0
      case 2: /* sports finder*/
2443
0
      case 4: /* Electronic shutter crop */
2444
0
        left_margin = 630;
2445
0
        top_margin = 0;
2446
0
        height = 3348;
2447
0
        width = 5004;
2448
0
        break;
2449
0
      default:
2450
        /* try to guess from crop inset*/
2451
0
        if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width
2452
0
          && imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height)
2453
0
        {
2454
0
                top_margin = imgdata.sizes.raw_inset_crops[0].ctop;
2455
0
                left_margin = imgdata.sizes.raw_inset_crops[0].cleft;
2456
0
        width = imgdata.sizes.raw_inset_crops[0].cwidth;
2457
0
        height = imgdata.sizes.raw_inset_crops[0].cheight;
2458
0
        }
2459
0
        break;
2460
2
      }
2461
2
      break;
2462
2
      case 6384:                // X-T3, X-T4, X100V, X-S10, X-T30, X-Pro3
2463
0
        top_margin = 0;
2464
0
        switch (FujiCropMode) {
2465
0
        case 0:        // no crop
2466
0
          left_margin = 0;
2467
0
          top_margin = 6;
2468
0
          width = 6246;
2469
0
          height = 4170;
2470
0
          break;
2471
0
        case 2:        // sports finder mode
2472
0
          left_margin = 624;
2473
0
          width = 5004;
2474
0
          height = raw_height;
2475
0
          break;
2476
0
        case 4:        // electronic shutter, high speed mode (1.25x crop)
2477
0
          left_margin = 624;
2478
0
          width = 5004;
2479
0
          break;
2480
0
        }
2481
0
        break;
2482
0
      case 6912:                // GFX 50S, GFX 50R; FF crop
2483
1
      case 9216:                // GFX 50S, GFX 50R; no crop
2484
1
        left_margin = 0;
2485
1
        top_margin = 0;
2486
1
        break;
2487
0
      case 8472:                // GFX 50S II
2488
0
        left_margin = 0;
2489
0
        top_margin  = 0;
2490
0
        width = raw_width - 192;
2491
0
        break;
2492
1
      case 9696:                // GFX 100; FF crop
2493
1
      case 11808:               // GFX 100; no crop
2494
1
        left_margin = 0;
2495
1
        width = raw_width - 146;
2496
1
        height = raw_height - 8;
2497
1
        top_margin = 2;
2498
1
        if (tiff_bps == 16)
2499
0
          maximum = 0xffff;
2500
5
      default:
2501
      /* insert model name-based width/height/margins/etc. assignments */
2502
5
        break;
2503
9
      }
2504
2505
830
    } else if (!imFuji.RAFDataGeneration) {
2506
829
      switch (raw_width) {
2507
1
      case 2304:                // S5100
2508
1
        height -= (top_margin = 6);
2509
1
        break;
2510
1
      case 3328:                // F550EXR, F600EXR, F770EXR, F800EXR, F900EXR,
2511
                                // HS20EXR, HS30EXR, HS33EXR, HS50EXR
2512
1
        if ((width = raw_width - 66))
2513
1
          left_margin = 34;
2514
1
        if (imgdata.sizes.raw_inset_crops[0].cleft == 8) // HS50EXR, F900EXR
2515
0
        {
2516
0
          left_margin = 0;
2517
0
          width += 2;
2518
0
          filters = 0x16161616;
2519
0
        }
2520
1
        break;
2521
0
      case 3664:                // "HS10 HS11"
2522
0
        filters = 0x16161616;
2523
0
        break;
2524
0
      case 5504:                // DBP for GX680 aka DX-2000
2525
2526
//         7712 2752 -> 5504 3856
2527
//         width = 688;
2528
//         height = 30848;
2529
//         raw_width = 688;
2530
//         raw_height = 30848;
2531
2532
0
        left_margin = 32; // imgdata.sizes.raw_inset_crops[0].cleft
2533
0
        top_margin = 8;
2534
0
        width = raw_width - 2*left_margin;
2535
0
        height = raw_height - 2*top_margin;
2536
2537
0
        load_raw = &LibRaw::unpacked_load_raw_FujiDBP;
2538
        //  maximum = 0x0fff;
2539
0
        filters = 0x16161616;
2540
0
        load_flags = 0;
2541
0
        flip = 6;
2542
0
        break;
2543
827
      default:
2544
        /* insert model name-based width/height/margins/etc. assignments */
2545
2546
827
      if (strncmp(model, "S6000", 5) && strncmp(model, "S6500", 5))
2547
824
      {
2548
        /* raw_inset_crops default*/
2549
824
        if (imgdata.sizes.raw_inset_crops[0].cwidth > 0 && imgdata.sizes.raw_inset_crops[0].cwidth <= raw_width &&
2550
5
          imgdata.sizes.raw_inset_crops[0].cheight > 0 && imgdata.sizes.raw_inset_crops[0].cheight <= raw_height)
2551
2
        {
2552
2
          top_margin = imgdata.sizes.raw_inset_crops[0].ctop;
2553
2
          left_margin = imgdata.sizes.raw_inset_crops[0].cleft;
2554
2
          width = imgdata.sizes.raw_inset_crops[0].cwidth;
2555
2
          height = imgdata.sizes.raw_inset_crops[0].cheight;
2556
2
        }
2557
824
      }
2558
827
        break;
2559
829
      }
2560
829
    }
2561
839
    if (fuji_layout)
2562
4
      raw_width *= is_raw;
2563
839
    if (filters == 9)
2564
13
      FORC(36)
2565
468
      ((char *)xtrans)[c] =
2566
468
      xtrans_abs[(c / 6 + top_margin) % 6][(c + left_margin) % 6];
2567
839
  }
2568
2569
7.28k
  else if (makeIs(LIBRAW_CAMERAMAKER_Konica)) {
2570
121
    if (!strcmp(model, "KD-400Z")) {
2571
0
      height = 1711; // 1712
2572
0
      width = 2312;
2573
0
      raw_width = 2336;
2574
0
      goto konica_400z;
2575
0
    }
2576
121
    else if (!strcmp(model, "KD-510Z")) {
2577
1
      goto konica_510z;
2578
1
    }
2579
2580
121
  }
2581
7.16k
  else if (makeIs(LIBRAW_CAMERAMAKER_Minolta)) {
2582
101
    if (fsize == 5869568) { // hack "DiMAGE Z2"
2583
0
      load_flags = 30;
2584
0
    }
2585
2586
101
    if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_UNPACKED) {
2587
0
      load_raw = &LibRaw::unpacked_load_raw;
2588
101
    } else if (imSony.prd_StorageMethod == LIBRAW_MINOLTA_PACKED) {
2589
0
      load_raw = &LibRaw::packed_load_raw;
2590
101
      } else if (!load_raw && (maximum = 0xfff)) {
2591
65
      load_raw = &LibRaw::unpacked_load_raw;
2592
65
    }
2593
2594
101
      if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_G2BRG1) {
2595
0
      filters = 0x49494949;
2596
101
      } else if (imSony.prd_BayerPattern == LIBRAW_MINOLTA_RGGB) {
2597
0
      filters = 0x94949494;
2598
0
      }
2599
2600
101
      if (imSony.prd_Active_bps && imSony.prd_Total_bps) {
2601
0
      tiff_bps = imSony.prd_Active_bps;
2602
0
      }
2603
2604
101
    if (!strncmp(model, "DiMAGE G", 8)) // hack "DiMAGE G400", "DiMAGE G500",
2605
                                               // "DiMAGE G530", "DiMAGE G600"
2606
4
    {
2607
4
      if (model[8] == '4') // DiMAGE G400
2608
1
      {
2609
1
        height = 1716;
2610
1
        width = 2304;
2611
1
      }
2612
3
      else if (model[8] == '5') // DiMAGE G500 / G530
2613
1
      {
2614
2
      konica_510z:
2615
2
        height = 1956;
2616
2
        width = 2607;
2617
2
        raw_width = 2624;
2618
2
      }
2619
2
      else if (model[8] == '6') // DiMAGE G600
2620
1
      {
2621
1
        height = 2136;
2622
1
        width = 2848;
2623
1
      }
2624
5
      data_offset += 14;
2625
5
      filters = 0x61616161;
2626
5
    konica_400z:
2627
5
      load_raw = &LibRaw::unpacked_load_raw;
2628
5
      maximum = 0x3df;
2629
5
      order = 0x4d4d;
2630
5
    }
2631
2632
101
  }
2633
7.06k
  else if (makeIs(LIBRAW_CAMERAMAKER_Samsung)) {
2634
187
    if (raw_width == 4704) // Samsung NX100, NX10, NX11,
2635
1
    {
2636
1
      height -= top_margin = 8;
2637
1
      width -= 2 * (left_margin = 8);
2638
1
      load_flags = 32;
2639
1
    }
2640
186
    else if (!strcmp(model, "NX3000")) // Samsung NX3000; raw_width: 5600
2641
0
    {
2642
0
      top_margin = 38;
2643
0
      left_margin = 92;
2644
0
      width = 5456;
2645
0
      height = 3634;
2646
0
      filters = 0x61616161;
2647
0
      colors = 3;
2648
0
    }
2649
186
    else if (raw_height == 3714) // Samsung NX2000, NX300M, NX300, NX30,
2650
                                 // "NX U" (aka:
2651
                                 //         "EK-GN100", "EK-GN110", "EK-GN120",
2652
                                 //         "EK-KN120", "Galaxy NX")
2653
1
    {
2654
1
      height -= top_margin = 18;
2655
1
      left_margin = raw_width - (width = 5536);
2656
1
      if (raw_width != 5600)
2657
1
        left_margin = top_margin = 0;
2658
1
      filters = 0x61616161;
2659
1
      colors = 3;
2660
1
    }
2661
185
    else if (raw_width == 5632) // Samsung NX1000, NX200, NX20, NX210
2662
2
    {
2663
2
      order = 0x4949;
2664
2
      height = 3694;
2665
2
      top_margin = 2;
2666
2
      width = 5574 - (left_margin = 32 + tiff_bps);
2667
2
      if (tiff_bps == 12)
2668
1
        load_flags = 80;
2669
2
    }
2670
183
    else if (raw_width == 5664) // Samsung "NX mini"
2671
1
    {
2672
1
      height -= top_margin = 17;
2673
1
      left_margin = 96;
2674
1
      width = 5544;
2675
1
      filters = 0x49494949;
2676
1
    }
2677
182
    else if (raw_width == 6496) // Samsung NX1, NX500
2678
2
    {
2679
2
      filters = 0x61616161;
2680
2
      if (!black && !cblack[0] && !cblack[1] && !cblack[2] && !cblack[3])
2681
1
        black = 1 << (tiff_bps - 7);
2682
2
    }
2683
180
    else if (!strcmp(normalized_model, "EX1")) // Samsung EX1; raw_width: 3688
2684
5
    {
2685
5
      order = 0x4949;
2686
5
      height -= 20;
2687
5
      top_margin = 2;
2688
5
      if ((width -= 6) > 3682)
2689
2
      {
2690
2
        height -= 10;
2691
2
        width -= 46;
2692
2
        top_margin = 8;
2693
2
      }
2694
5
    }
2695
175
    else if (!strcmp(normalized_model, "WB2000")) // Samsung WB2000; raw_width: 3728
2696
2
    {
2697
2
      order = 0x4949;
2698
2
      height -= 3;
2699
2
      top_margin = 2;
2700
2
      if ((width -= 10) > 3718)
2701
1
      {
2702
1
        height -= 28;
2703
1
        width -= 56;
2704
1
        top_margin = 8;
2705
1
      }
2706
2
    }
2707
173
    else if (!strcmp(model, "WB550")) // Samsung WB550; raw_width: 4000
2708
2
    {
2709
2
      order = 0x4949;
2710
2
    }
2711
171
    else if (!strcmp(model, "EX2F")) // Samsung EX2F; raw_width: 4176
2712
1
    {
2713
1
      height = 3030;
2714
1
      width = 4040;
2715
1
      top_margin = 15;
2716
1
      left_margin = 24;
2717
1
      order = 0x4949;
2718
1
      filters = 0x49494949;
2719
1
      load_raw = &LibRaw::unpacked_load_raw;
2720
1
    }
2721
187
  }
2722
2723
6.87k
  else if (makeIs(LIBRAW_CAMERAMAKER_ST_Micro) && !strcmp(model, "STV680 VGA"))
2724
0
  {
2725
0
    black = 16;
2726
0
  }
2727
6.87k
  else if (!strcmp(model, "N95"))
2728
1
  {
2729
1
    height = raw_height - (top_margin = 2);
2730
1
  }
2731
6.87k
  else if (!strcmp(model, "640x480"))
2732
1
  {
2733
1
    gamma_curve(0.45, 4.5, 1, 255);
2734
1
  }
2735
6.87k
  else if (makeIs(LIBRAW_CAMERAMAKER_Hasselblad))
2736
430
  {
2737
430
    if (load_raw == &LibRaw::lossless_jpeg_load_raw)
2738
2
      load_raw = &LibRaw::hasselblad_load_raw;
2739
2740
430
    if ((imHassy.SensorCode == 4) && !strncmp(model, "V96C", 4)) { // Hasselblad V96C
2741
2
      strcpy(model, "V96C");
2742
2
      strcpy(normalized_model, model);
2743
2
      height -= (top_margin = 6);
2744
2
      width -= (left_margin = 3) + 7;
2745
2
      filters = 0x61616161;
2746
2747
2
    }
2748
428
    else if ((imHassy.SensorCode == 9) && imHassy.uncropped) { // various Hasselblad '-39'
2749
0
      height = 5444;
2750
0
      width = 7248;
2751
0
      top_margin = 4;
2752
0
      left_margin = 7;
2753
0
      filters = 0x61616161;
2754
2755
0
    }
2756
428
    else if ((imHassy.SensorCode == 13) && imHassy.uncropped) { // Hasselblad H4D-40, H5D-40
2757
0
      height -= 84;
2758
0
      width -= 82;
2759
0
      top_margin = 4;
2760
0
      left_margin = 41;
2761
0
      filters = 0x61616161;
2762
2763
0
    }
2764
428
    else if ((imHassy.SensorCode == 11) && imHassy.uncropped) { // Hasselblad H5D-50
2765
0
      height -= 84;
2766
0
      width -= 82;
2767
0
      top_margin = 4;
2768
0
      left_margin = 41;
2769
0
      filters = 0x61616161;
2770
2771
0
    }
2772
428
    else if ((imHassy.SensorCode == 15) &&
2773
2
      !imHassy.SensorSubCode && // Hasselblad H5D-50c, CFV-50c
2774
2
      imHassy.uncropped) {
2775
0
      left_margin = 52;
2776
0
      top_margin = 100;
2777
0
      width = 8272;
2778
0
      height = 6200;
2779
0
      black = 256;
2780
2781
0
    }
2782
428
    else if ((imHassy.SensorCode == 15) &&
2783
2
      (imHassy.SensorSubCode == 2) && // various Hasselblad X1D cameras
2784
0
      imHassy.uncropped) {
2785
0
      top_margin = 96;
2786
0
      height -= 96;
2787
0
      left_margin = 48;
2788
0
      width -= 106;
2789
0
      maximum = 0xffff;
2790
0
      tiff_bps = 16;
2791
2792
0
    }
2793
428
    else if ((imHassy.SensorCode == 12) && imHassy.uncropped) { // Hasselblad H4D-60
2794
0
      if (black > 500) { // (imHassy.format == LIBRAW_HF_FFF)
2795
0
        top_margin = 12;
2796
0
        left_margin = 44;
2797
0
        width = 8956;
2798
0
        height = 6708;
2799
0
        memset(cblack, 0, sizeof(cblack));
2800
0
        black = 512;
2801
0
      }
2802
0
      else { // (imHassy.format == LIBRAW_HF_3FR)
2803
0
        top_margin = 8;
2804
0
        left_margin = 40;
2805
0
        width = 8964;
2806
0
        height = 6716;
2807
0
        black += load_flags = 256;
2808
0
        maximum = 0x8101;
2809
0
      }
2810
2811
0
    }
2812
428
    else if ((imHassy.SensorCode == 17) && imHassy.uncropped) { // Hasselblad H6D-100c, A6D-100c
2813
0
      left_margin = 64;
2814
0
      width = 11608;
2815
0
      top_margin = 108;
2816
0
      height = raw_height - top_margin;
2817
0
    }
2818
428
    else if (((imHassy.SensorCode == 20)|| (imHassy.SensorCode == 22)) && imHassy.uncropped) { // Hasselblad X2D-100c, 100c-II CFV-100c
2819
0
      left_margin = 124;
2820
0
      width = 11664;
2821
0
      top_margin = 92;
2822
0
      height = raw_height - top_margin;
2823
0
    }
2824
2825
430
    if (tiff_samples > 1)
2826
5
    {
2827
5
      is_raw = tiff_samples + 1;
2828
5
      if (!shot_select && !half_size)
2829
5
        filters = 0;
2830
5
    }
2831
430
  }
2832
6.44k
  else if (makeIs(LIBRAW_CAMERAMAKER_Sinar))
2833
71
  {
2834
71
    if (!load_raw)
2835
10
      load_raw = &LibRaw::unpacked_load_raw;
2836
71
    if (is_raw > 1 && !shot_select)
2837
27
      filters = 0;
2838
71
    maximum = 0x3fff;
2839
71
  }
2840
2841
10.7k
  if (load_raw == &LibRaw::sinar_4shot_load_raw)
2842
39
  {
2843
39
    if (is_raw > 1 && !shot_select)
2844
37
      filters = 0;
2845
39
  }
2846
10.7k
  else if (makeIs(LIBRAW_CAMERAMAKER_Leaf))
2847
495
  {
2848
495
    maximum = 0x3fff;
2849
495
    fseek(ifp, data_offset, SEEK_SET);
2850
495
    if (ljpeg_start(&jh, 1) && jh.bits == 15)
2851
2
      maximum = 0x1fff;
2852
495
    if (tiff_samples > 1)
2853
19
      filters = 0;
2854
495
    if (tiff_samples > 1 || tile_length < raw_height)
2855
88
    {
2856
88
      load_raw = &LibRaw::leaf_hdr_load_raw;
2857
88
      raw_width = tile_width;
2858
88
    }
2859
495
    if ((width | height) == 2048)
2860
2
    {
2861
2
      if (tiff_samples == 1)
2862
0
      {
2863
0
        filters = 1;
2864
0
        strcpy(cdesc, "RBTG");
2865
0
        strcpy(model, "CatchLight");
2866
0
        strcpy(normalized_model, model);
2867
0
        top_margin = 8;
2868
0
        left_margin = 18;
2869
0
        height = 2032;
2870
0
        width = 2016;
2871
0
      }
2872
2
      else
2873
2
      {
2874
2
        strcpy(model, "DCB2");
2875
2
        strcpy(normalized_model, model);
2876
2
        top_margin = 10;
2877
2
        left_margin = 16;
2878
2
        height = 2028;
2879
2
        width = 2022;
2880
2
      }
2881
2
    }
2882
493
    else if (width + height == 3144 + 2060)
2883
0
    {
2884
0
      if (!model[0])
2885
0
      {
2886
0
        strcpy(model, "Cantare");
2887
0
        strcpy(normalized_model, model);
2888
0
      }
2889
0
      if (width > height)
2890
0
      {
2891
0
        top_margin = 6;
2892
0
        left_margin = 32;
2893
0
        height = 2048;
2894
0
        width = 3072;
2895
0
        filters = 0x61616161;
2896
0
      }
2897
0
      else
2898
0
      {
2899
0
        left_margin = 6;
2900
0
        top_margin = 32;
2901
0
        width = 2048;
2902
0
        height = 3072;
2903
0
        filters = 0x16161616;
2904
0
      }
2905
0
      if (!cam_mul[0] || model[0] == 'V')
2906
0
        filters = 0;
2907
0
      else
2908
0
        is_raw = tiff_samples;
2909
0
    }
2910
493
    else if (width == 2116) // Leaf "Valeo 6"
2911
0
    {
2912
0
      strcpy(model, "Valeo 6");
2913
0
      strcpy(normalized_model, model);
2914
0
      height -= 2 * (top_margin = 30);
2915
0
      width -= 2 * (left_margin = 55);
2916
0
      filters = 0x49494949;
2917
0
    }
2918
493
    else if (width == 3171) // Leaf "Valeo 6"
2919
0
    {
2920
0
      strcpy(model, "Valeo 6");
2921
0
      strcpy(normalized_model, model);
2922
0
      height -= 2 * (top_margin = 24);
2923
0
      width -= 2 * (left_margin = 24);
2924
0
      filters = 0x16161616;
2925
0
    }
2926
495
  }
2927
10.2k
  else if (makeIs(LIBRAW_CAMERAMAKER_Panasonic))
2928
181
  {
2929
181
    if (raw_width > 0 &&
2930
167
      ((flen - data_offset) / (raw_width * 8 / 7) == raw_height))
2931
19
      load_raw = &LibRaw::panasonic_load_raw;
2932
181
    if (!load_raw)
2933
13
    {
2934
13
      load_raw = &LibRaw::unpacked_load_raw;
2935
13
      load_flags = 4;
2936
13
    }
2937
181
    zero_is_bad = 1;
2938
181
    if ((height += 12) > raw_height)
2939
175
      height = raw_height;
2940
4.70k
    for (i = 0; i < int(sizeof pana / sizeof *pana); i++)
2941
4.52k
      if (raw_width == pana[i][0] && raw_height == pana[i][1])
2942
0
      {
2943
0
        left_margin = pana[i][2];
2944
0
        top_margin = pana[i][3];
2945
0
        width += pana[i][4];
2946
0
        height += pana[i][5];
2947
0
      }
2948
181
    if (!tiff_bps && pana_bpp >= 12 && pana_bpp <= 14)
2949
5
      tiff_bps = pana_bpp;
2950
2951
181
        if (!strcmp(model, "DC-LX100M2") && raw_height == 3568 && raw_width == 4816 && filters == 3)
2952
0
            filters = 4;
2953
2954
181
    filters = 0x01010101U *
2955
181
      (uchar) "\x94\x61\x49\x16"[((filters - 1) ^ (left_margin & 1) ^
2956
181
      (top_margin << 1)) &
2957
181
      3];
2958
2959
181
  }
2960
10.0k
  else if (makeIs(LIBRAW_CAMERAMAKER_Contax) &&
2961
47
    !strcmp(model, "N Digital")) {
2962
44
    height = 2047;
2963
44
    width = 3072;
2964
44
    filters = 0x61616161;
2965
44
    data_offset = 0x1a00;
2966
44
    load_raw = &LibRaw::packed_load_raw;
2967
2968
44
  }
2969
9.99k
  else if (makeIs(LIBRAW_CAMERAMAKER_Sony)) {
2970
1.10k
    if (!strcmp(model, "DSC-F828")) { // Sony DSC-F828
2971
2
      width = 3288;
2972
2
      left_margin = 5;
2973
2
      mask[1][3] = -17;
2974
2
      data_offset = 862144;
2975
2
      load_raw = &LibRaw::sony_load_raw;
2976
2
      filters = 0x9c9c9c9c;
2977
2
      colors = 4;
2978
2
      strcpy(cdesc, "RGBE");
2979
2980
2
    }
2981
1.09k
    else if (!strcmp(model, "DSC-V3")) { // Sony DSC-V3
2982
1
      width = 3109;
2983
1
      left_margin = 59;
2984
1
      mask[0][1] = 9;
2985
1
      data_offset = 787392;
2986
1
      load_raw = &LibRaw::sony_load_raw;
2987
2988
1
    }
2989
1.09k
        else if ((unique_id == SonyID_ILCE_7RM5) ||
2990
1.09k
                 (unique_id == SonyID_ILCE_7CR)  ||
2991
1.09k
        (unique_id == SonyID_DSC_RX1RM3) || // only Lossless/FF samples for now
2992
1.09k
                 (unique_id == SonyID_ILX_LR1))
2993
6
        {
2994
6
          if (raw_width == 6304)
2995
0
          {
2996
            /* nothing: APS-C Uncompressed, handled in open_datastream*/
2997
0
          }
2998
6
          else if (raw_width == 6656) /* 7RM5 Lossy compressed, medium */
2999
0
          {
3000
0
            width = 6272;
3001
0
            height = 4180;
3002
0
          }
3003
6
          else if (raw_width == 9728) // FF, Lossless compresssed
3004
0
          {
3005
0
            width = 9566;
3006
0
            height = 6374;
3007
0
          }
3008
6
          else if (raw_width == 5120) // APS-C??/Lossy-Small?
3009
0
          {
3010
0
            width = 4776;
3011
0
            height = 3180;
3012
0
          }
3013
6
      else if (raw_width == 9600)
3014
0
      {
3015
0
        width = raw_width - 36;
3016
0
      }
3017
6
          else
3018
6
          {
3019
6
            width = raw_width - 32; // fallback
3020
6
      imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3021
3022
6
          }
3023
6
        }
3024
1.09k
    else if (raw_width == 3984) 
3025
0
    { // Sony DSC-R1;
3026
0
      width = 3925;
3027
0
      order = 0x4d4d;
3028
3029
0
    }
3030
1.09k
    else if (raw_width == 4288) { // Sony ILCE-7S, ILCE-7SM2, ILCE-7SM3, DSLR-A700, DSLR-A500;
3031
2
      width -= 32;
3032
2
    }
3033
1.08k
    else if (raw_width == 4600) { // Sony DSLR-A290, DSLR-A350, DSLR-A380;
3034
0
      if (!strcmp(model, "DSLR-A350"))
3035
0
        height -= 4;
3036
0
      black = 0;
3037
3038
0
    }
3039
1.08k
    else if (raw_width == 4928) {
3040
      // Sony DSLR-A580, NEX-C3, SLT-A35, DSC-HX99, DSC-HX95, SLT-A55,
3041
      // NEX-5N, SLT-A37, SLT-A57, NEX-F3, NEX-6, NEX-5R, NEX-3N, NEX-5T;
3042
2
      if (height < 3280)
3043
1
        width -= 8;
3044
3045
2
    }
3046
1.08k
    else if (raw_width == 5504) {
3047
      // Sony ILCE-3000, SLT-A58, DSC-RX100M3, ILCE-QX1,
3048
      // DSC-RX10M4, DSC-RX100M6, DSC-RX100, DSC-RX100M2, DSC-RX10,
3049
      // ILCE-5000, DSC-RX100M4, DSC-RX10M2, DSC-RX10M3,
3050
      // DSC-RX100M5, DSC-RX100M5A;
3051
1
      width -= height > 3664 ? 8 : 32;
3052
3053
1
    }
3054
1.08k
    else if (unique_id == SonyID_ILCE_9M3)
3055
5
    {
3056
5
      if (raw_width == 6048)
3057
0
        width -= 36; // 
3058
5
      else if (raw_width == 6144) // Lossless/L, FF
3059
1
      {
3060
1
        width = 6012;
3061
1
        height = 4020;
3062
1
      }
3063
4
      else if (raw_width == 4096) // Lossless/M
3064
1
      {
3065
1
        width = 3944;
3066
1
        height = 2644;
3067
1
      }
3068
3
      else if (raw_width == 3072) // Lossless/S
3069
1
      {
3070
1
        width = 3016;
3071
1
        height = 2008;
3072
1
      }
3073
2
      else if (raw_width == 3968)   // Uncompressed, APS
3074
0
      {
3075
0
        width = 3948;
3076
0
      }
3077
2
      else // We do not have other samples, offer vendor crop to caller
3078
2
      {
3079
2
              width = raw_width - 32; // fallback
3080
2
              imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3081
2
      }
3082
5
    }
3083
1.08k
    else if (raw_width == 6048) {
3084
      // Sony SLT-A65, DSC-RX1, SLT-A77, DSC-RX1, ILCA-77M2,
3085
      // ILCE-7M3, NEX-7, SLT-A99, ILCE-7, DSC-RX1R, ILCE-6000,
3086
      // ILCE-5100, ILCE-7M2, ILCA-68, ILCE-6300, ILCE-9,
3087
      // ILCE-6500, ILCE-6400;
3088
1
      width -= 24;
3089
1
      if (strstr(normalized_model, "RX1") ||
3090
1
        strstr(normalized_model, "A99"))
3091
0
        width -= 6;
3092
3093
1
    }
3094
1.08k
    else if (raw_width == 7392) { // Sony ILCE-7R;
3095
1
      width -= 30;
3096
3097
1
    }
3098
1.07k
    else if (raw_width == 8000) {
3099
      // Sony ILCE-7RM2, ILCE-7RM2, ILCE-7RM3, DSC-RX1RM2, ILCA-99M2;
3100
0
      width -= 32;
3101
3102
0
    }
3103
1.07k
    else if (raw_width == 9600) { // Sony ILCE-7RM4 && 7RM5
3104
1
      width -= 32;
3105
3106
1
    }
3107
1.07k
        else if (unique_id == SonyID_ZV_E1)
3108
12
        {
3109
12
          if (raw_width == 4608 && raw_height == 3072) // SonyID_ZV_E1
3110
0
          {
3111
0
            width  = 4256;
3112
0
            height = 2846;
3113
0
          }
3114
12
        }
3115
1.06k
        else if((unique_id == SonyID_ILCE_1) || (unique_id == SonyID_ILCE_1M2))
3116
21
        {
3117
21
          if (raw_width == 8704 && raw_height == 6144) // ILCE-1 FF@Compressed
3118
0
          {
3119
0
            width = 8660;
3120
0
            height = 5784;
3121
0
          }
3122
21
          else if (raw_width == 8672) // FF uncompressed/lossy
3123
1
          {
3124
1
            width -= 12;
3125
1
          }
3126
20
          else if (raw_width == 6144 && raw_height == 4096) // APSC/Lossless
3127
1
          {
3128
1
            width = 5636;
3129
1
            height = 3768;
3130
1
          }
3131
19
          else if (raw_width == 5664) // APS-C/Uncompressed or lossy
3132
0
          {
3133
0
              width -= 28;
3134
0
          }
3135
19
          else if (raw_width == 5632) // Lossy/Medium
3136
1
          {
3137
1
            width -= 4;
3138
1
      height = 3756;
3139
1
          }
3140
18
          else if (raw_width == 4608) // Lossy/small
3141
1
          {
3142
1
            width = 4332;
3143
1
            height = 2892;
3144
1
          }
3145
17
      else
3146
17
            imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3147
3148
      /* need samples for lossy small/medium w/ APC crop*/
3149
21
        }
3150
1.04k
        else if (unique_id == SonyID_ILCE_7M5)
3151
1
    {
3152
1
      if (raw_width == 7168 && raw_height == 5120) // FF, lossless
3153
0
      {
3154
0
              width = 7028;
3155
0
              height = 4688;
3156
0
      }
3157
1
            else if (raw_width == 7040) // FF compressed/compressedHQ
3158
0
            {
3159
0
              width -= 12;
3160
0
            }
3161
1
      else if (raw_width == 5120 && raw_height == 3584) // APS-C, lossless
3162
0
      {
3163
0
              width = 4628;
3164
0
              height = 3088;
3165
0
      }
3166
1
      else if (raw_width == 4640) // APS-C Compressed/CompressedHQ
3167
0
      {
3168
0
              width -= 12;
3169
0
      }
3170
1
      else
3171
1
              imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3172
1
    }
3173
1.04k
    else if (unique_id == SonyID_ILCE_7RM6)
3174
0
    {
3175
0
          if (raw_width == 10240 && raw_height == 7168) // FF, lossless
3176
0
          {
3177
0
            width = 10002;
3178
0
            height = 6668; // ensure 2:3
3179
0
          }
3180
0
          else if (raw_width == 10016 && raw_height == 6672) // FF, Compressed
3181
0
          {
3182
0
            width = 10002;
3183
0
            height = 6668; // ensure 2:3
3184
0
          }
3185
0
          else if (raw_width == 6656 && raw_height == 4608) // APS, Lossless
3186
0
          {
3187
0
            width = 6540;
3188
0
            height = 4360; // ensure 2:3
3189
0
          }
3190
0
          else if (raw_width == 6592 && raw_height == 4372) // APS, Compressed
3191
0
          {
3192
0
            width = 6540;
3193
0
            height = 4360; // ensure 2:3
3194
0
          }
3195
0
          else
3196
0
            imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3197
0
    }
3198
1.04k
    else if ((unique_id == SonyID_ILCE_7M4)|| (unique_id == SonyID_ILCE_7CM2) || (unique_id == SonyID_ILME_FX2))
3199
11
        {
3200
11
          if (raw_width == 7168 && raw_height == 5120) 
3201
1
          {
3202
1
            width = 7028;
3203
1
            height = 4688;
3204
1
          }
3205
10
          else if (raw_width == 4736) // APS-C crop
3206
1
          {
3207
1
            width = 4692;
3208
            //height = 3080;
3209
1
          }
3210
9
          else if (raw_width == 5120) // Lossy/Medium
3211
0
          {
3212
0
            width = 4624;
3213
0
            height = 3080;
3214
0
          }
3215
9
          else if (raw_width == 3584) // Lossy/Small
3216
0
          {
3217
0
            width = 3516;
3218
0
            height = 2344;
3219
0
          }
3220
9
          else if (raw_width == 7040) // FF uncompressed/lossy
3221
2
          {
3222
2
            width -= 12;
3223
2
          }
3224
7
      else
3225
7
            imgdata.process_warnings |= LIBRAW_WARN_VENDOR_CROP_SUGGESTED;
3226
          /* FIXME: need APS-C samples, both losslesscompressed and uncompressed or lossy */
3227
11
        }
3228
1.03k
    else if ((unique_id == SonyID_ILCE_6700) || (unique_id == SonyID_ZV_E10M2)
3229
1.02k
        || (unique_id == SonyID_ILME_FX30)) // same sensor
3230
7
    {
3231
7
      if (raw_width == 6656)
3232
0
      {
3233
0
        width = 6240;
3234
0
        height = 4168;
3235
0
      }
3236
7
            else if (raw_width == 6272) // APS-C uncompressed
3237
0
            {
3238
0
              width = raw_width - 32;
3239
0
            }
3240
7
      else // fallback
3241
7
      {
3242
7
        width = raw_width - 32;
3243
7
      }
3244
7
    }
3245
1.02k
        else if (!strcmp(model, "DSLR-A100")) {
3246
5
      if (width == 3880) {
3247
0
        height--;
3248
0
        width = ++raw_width;
3249
0
      }
3250
5
      else {
3251
5
        height -= 4;
3252
5
        width -= 4;
3253
5
        order = 0x4d4d;
3254
5
        load_flags = 2;
3255
5
      }
3256
5
      filters = 0x61616161;
3257
5
    }
3258
1.10k
  }
3259
3260
8.89k
  else if (!strcmp(model, "PIXL")) {
3261
1
    height -= top_margin = 4;
3262
1
    width -= left_margin = 32;
3263
1
    gamma_curve(0, 7, 1, 255);
3264
3265
1
  }
3266
8.89k
  else if (makeIs(LIBRAW_CAMERAMAKER_Kodak)) {
3267
3268
407
    if (!strncasecmp(model, "EasyShare", 9)) {
3269
4
      data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000;
3270
4
      load_raw = &LibRaw::packed_load_raw;
3271
3272
4
    }
3273
403
    else if (!strcmp(model, "C603") ||
3274
361
      !strcmp(model, "C330") ||
3275
336
      !strcmp(model, "12MP")) {
3276
68
      order = 0x4949;
3277
68
      if (filters && data_offset) {
3278
1
        fseek(ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET);
3279
1
        read_shorts(curve, 256);
3280
1
      }
3281
67
      else
3282
67
        gamma_curve(0, 3.875, 1, 255);
3283
3284
68
      load_raw = filters ? &LibRaw::eight_bit_load_raw
3285
68
        : strcmp(model, "C330") ? &LibRaw::kodak_c603_load_raw
3286
59
        : &LibRaw::kodak_c330_load_raw;
3287
68
      load_flags = tiff_bps > 16;
3288
68
      tiff_bps = 8;
3289
3290
68
    }
3291
335
    else {
3292
335
      if (!strncmp(model, "NC2000", 6) ||
3293
333
        !strncmp(model, "EOSDCS", 6) ||
3294
328
        !strncmp(model, "DCS4", 4)) {
3295
15
        width -= 4;
3296
15
        left_margin = 2;
3297
3298
15
      }
3299
320
      else if (!strcmp(model, "DCS660M")) {
3300
1
        black = 214;
3301
3302
1
      }
3303
319
      else if (!strcmp(model, "EOS D2000C")) {
3304
4
        filters = 0x61616161;
3305
4
        if (!black) black = curve[200];
3306
4
      }
3307
3308
335
      if (filters == UINT_MAX) filters = 0x61616161;
3309
3310
335
      if (!strcmp(model + 4, "20X"))
3311
0
        strcpy(cdesc, "MYCY");
3312
335
      if (!strcmp(model, "DC25")) {
3313
3
        data_offset = 15424;
3314
3
      }
3315
3316
335
      if (!strncmp(model, "DC2", 3)) {
3317
9
        raw_height = 2 + (height = 242);
3318
9
        if (!strncmp(model, "DC290", 5))
3319
0
          iso_speed = 100;
3320
9
        if (!strncmp(model, "DC280", 5))
3321
1
          iso_speed = 70;
3322
9
        if (flen < 100000) {
3323
9
          raw_width = 256;
3324
9
          width = 249;
3325
9
          pixel_aspect = (4.0 * height) / (3.0 * width);
3326
9
        }
3327
0
        else {
3328
0
          raw_width = 512;
3329
0
          width = 501;
3330
0
          pixel_aspect = (493.0 * height) / (373.0 * width);
3331
0
        }
3332
9
        top_margin = left_margin = 1;
3333
9
        colors = 4;
3334
9
        filters = 0x8d8d8d8d;
3335
9
        simple_coeff(1);
3336
9
        pre_mul[1] = 1.179f;
3337
9
        pre_mul[2] = 1.209f;
3338
9
        pre_mul[3] = 1.036f;
3339
9
        load_raw = &LibRaw::eight_bit_load_raw;
3340
9
      }
3341
326
      else if (!strcmp(model, "DC40")) {
3342
3
        height = 512;
3343
3
        width = 768;
3344
3
        data_offset = 1152;
3345
3
        load_raw = &LibRaw::kodak_radc_load_raw;
3346
3
        tiff_bps = 12;
3347
12
        FORC4 cam_mul[c] = 1.0f;
3348
3349
3
      }
3350
323
      else if (!strcmp(model, "DC50")) {
3351
2
        height = 512;
3352
2
        width = 768;
3353
2
        iso_speed = 84;
3354
2
        data_offset = 19712;
3355
2
        load_raw = &LibRaw::kodak_radc_load_raw;
3356
8
        FORC4 cam_mul[c] = 1.0f;
3357
3358
2
      }
3359
321
      else if (!strcmp(model, "DC120")) {
3360
7
        raw_height = height = 976;
3361
7
        raw_width = width = 848;
3362
7
        iso_speed = 160;
3363
7
        pixel_aspect = height / 0.75 / width;
3364
7
        load_raw = tiff_compress == 7 ? &LibRaw::kodak_jpeg_load_raw
3365
7
          : &LibRaw::kodak_dc120_load_raw;
3366
3367
7
      }
3368
314
      else if (!strcmp(model, "DCS200")) {
3369
1
        thumb_height = 128;
3370
1
        thumb_width = 192;
3371
1
        thumb_offset = 6144;
3372
1
        thumb_misc = 360;
3373
1
        iso_speed = 140;
3374
1
        thumb_format = LIBRAW_INTERNAL_THUMBNAIL_LAYER;
3375
1
        black = 17;
3376
1
      }
3377
335
    }
3378
3379
407
  }
3380
8.49k
  else if (makeIs(LIBRAW_CAMERAMAKER_Logitech) &&
3381
7
    !strcmp(model, "Fotoman Pixtura")) {
3382
3
    height = 512;
3383
3
    width = 768;
3384
3
    data_offset = 3632;
3385
3
    load_raw = &LibRaw::kodak_radc_load_raw;
3386
3
    filters = 0x61616161;
3387
3
    simple_coeff(2);
3388
3389
3
  }
3390
8.48k
  else if (makeIs(LIBRAW_CAMERAMAKER_Apple) &&
3391
246
    !strncmp(model, "QuickTake", 9)) {
3392
233
    if (head[5]) {
3393
93
      strcpy(model + 10, "200");
3394
93
      strcpy(normalized_model, model);
3395
93
    }
3396
233
    fseek(ifp, 544, SEEK_SET);
3397
233
    height = get2();
3398
233
    width = get2();
3399
233
    data_offset = (get4(), get2()) == 30 ? 738 : 736;
3400
233
    if (height > width) {
3401
70
      SWAP(height, width);
3402
70
      fseek(ifp, data_offset - 6, SEEK_SET);
3403
70
      flip = ~get2() & 3 ? 5 : 6;
3404
70
    }
3405
233
    filters = 0x61616161;
3406
3407
233
  }
3408
8.25k
  else if (makeIs(LIBRAW_CAMERAMAKER_Rollei) &&
3409
376
    !load_raw) {
3410
360
    switch (raw_width) {
3411
0
    case 1316: // Rollei d530flex
3412
0
      height = 1030;
3413
0
      width = 1300;
3414
0
      top_margin = 1;
3415
0
      left_margin = 6;
3416
0
      break;
3417
0
    case 2568:
3418
0
      height = 1960;
3419
0
      width = 2560;
3420
0
      top_margin = 2;
3421
0
      left_margin = 8;
3422
360
    }
3423
360
    filters = 0x16161616;
3424
360
    load_raw = &LibRaw::rollei_load_raw;
3425
3426
360
  }
3427
7.89k
  else if (!strcmp(model, "GRAS-50S5C")) {
3428
2
    height = 2048;
3429
2
    width = 2440;
3430
2
    load_raw = &LibRaw::unpacked_load_raw;
3431
2
    data_offset = 0;
3432
2
    filters = 0x49494949;
3433
2
    order = 0x4949;
3434
2
    maximum = 0xfffC;
3435
3436
2
  }
3437
7.89k
  else if (!strcmp(model, "BB-500CL")) {
3438
1
    height = 2058;
3439
1
    width = 2448;
3440
1
    load_raw = &LibRaw::unpacked_load_raw;
3441
1
    data_offset = 0;
3442
1
    filters = 0x94949494;
3443
1
    order = 0x4949;
3444
1
    maximum = 0x3fff;
3445
3446
1
  }
3447
7.89k
  else if (!strcmp(model, "BB-500GE")) {
3448
2
    height = 2058;
3449
2
    width = 2456;
3450
2
    load_raw = &LibRaw::unpacked_load_raw;
3451
2
    data_offset = 0;
3452
2
    filters = 0x94949494;
3453
2
    order = 0x4949;
3454
2
    maximum = 0x3fff;
3455
3456
2
  }
3457
7.89k
  else if (!strcmp(model, "SVS625CL")) {
3458
1
    height = 2050;
3459
1
    width = 2448;
3460
1
    load_raw = &LibRaw::unpacked_load_raw;
3461
1
    data_offset = 0;
3462
1
    filters = 0x94949494;
3463
1
    order = 0x4949;
3464
1
    maximum = 0x0fff;
3465
1
  }
3466
10.7k
}