Coverage Report

Created: 2025-06-16 07:00

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