Coverage Report

Created: 2026-07-20 07:19

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