Coverage Report

Created: 2026-03-31 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libraw/src/metadata/hasselblad_model.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
5
 LibRaw is free software; you can redistribute it and/or modify
6
 it under the terms of the one of two licenses as you choose:
7
8
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
9
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
10
11
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
12
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
13
14
 */
15
16
#include "../../internal/dcraw_defs.h"
17
#include "../../internal/libraw_cameraids.h"
18
19
  static const struct {
20
    const int idx;
21
    const char *FormatName;
22
  } HassyRawFormat[] = {
23
    { LIBRAW_HF_Unknown, "Unknown"},
24
    { LIBRAW_HF_3FR, "-3FR"},
25
    { LIBRAW_HF_FFF, "-FFF"},
26
    { LIBRAW_HF_Imacon, "Imacon"},
27
    { LIBRAW_HF_HasselbladDNG, "hDNG"},
28
    { LIBRAW_HF_AdobeDNG, "aDNG"},
29
    { LIBRAW_HF_AdobeDNG_fromPhocusDNG, "a(hDNG)"},
30
  };
31
32
const char* LibRaw::HassyRawFormat_idx2HR(unsigned idx) // HR means "human-readable"
33
373
{
34
1.11k
    for (int i = 0; i < int(sizeof HassyRawFormat / sizeof *HassyRawFormat); i++)
35
1.11k
        if((unsigned)HassyRawFormat[i].idx == idx)
36
373
            return HassyRawFormat[i].FormatName;
37
0
    return 0;
38
373
}
39
40
7
void LibRaw::process_Hassy_Lens (int LensMount) {
41
// long long unsigned id =
42
//    mount*100000000ULL + series*10000000ULL +
43
//    focal1*10000ULL + focal2*10 + version;
44
7
  char *ps;
45
7
  int c;
46
7
  char *q = strchr(imgdata.lens.Lens, ' ');
47
7
  if (!q)
48
1
    return;
49
6
  c = atoi(q +1);
50
6
  if (!c)
51
1
    return;
52
53
5
  if (LensMount == LIBRAW_MOUNT_Hasselblad_H) {
54
4
    if (imgdata.lens.Lens[2] == ' ') // HC lens
55
2
      ilm.LensID = LensMount*100000000ULL + 10000000ULL;
56
2
    else                             // HCD lens
57
2
      ilm.LensID = LensMount*100000000ULL + 20000000ULL;
58
4
    ilm.LensFormat = LIBRAW_FORMAT_645;
59
4
  } else if (LensMount == LIBRAW_MOUNT_Hasselblad_XCD) {
60
1
    ilm.LensFormat = LIBRAW_FORMAT_CROP645;
61
1
    ilm.LensID = LensMount*100000000ULL;
62
1
  } else
63
0
    return;
64
65
5
  ilm.LensMount = LensMount;
66
5
  ilm.LensID += c*10000ULL;
67
5
  if ((ps=strchr(imgdata.lens.Lens, '-'))) {
68
1
    ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
69
1
    ilm.LensID += atoi(ps+1)*10ULL;
70
4
  } else {
71
4
    ilm.FocalType = LIBRAW_FT_PRIME_LENS;
72
4
    ilm.LensID += c*10ULL;
73
4
  }
74
5
  if (strstr(imgdata.lens.Lens, "III"))
75
1
    ilm.LensID += 3ULL;
76
4
  else if (strstr(imgdata.lens.Lens, "II"))
77
1
    ilm.LensID += 2ULL;
78
5
}
79
80
373
void LibRaw::parseHassyModel() {
81
82
373
static const char *Hasselblad_Ctrl[] = { // manually selectable options only
83
373
  "ELD", "ELX", "Winder CW", "CW", "Pinhole", "Flash Sync",
84
373
  "SWC", "200 (Mod)", "200", "500 Mech.", "500", "H Series",
85
373
  "H-Series", "H1", "H2", "Black Box", "LENSCONTROL S", "LENSCTRL S", "Generic",
86
373
};
87
88
373
static const char *Hasselblad_SensorEnclosures[] = {
89
373
  "CFH", "CFV", "CFV", "CFII", "CF", "Ixpress",
90
373
};
91
92
373
  char tmp_model[64];
93
373
  const char *ps;
94
373
  char *eos;
95
373
  int c;
96
373
  int nPix = raw_width*raw_height;
97
373
  int add_MP_toName = 1;
98
373
  int norm_model_isSet = 0;
99
100
373
  if (model[0] == ' ')
101
14
    memmove(model, model+1, MIN(sizeof(model)-1,strlen(model)));
102
103
373
  imHassy.HostBody[0] = 0;
104
373
  if ((ps = strrchr(model, '/')))
105
7
    strcpy(imHassy.HostBody, ps+1);
106
366
  else if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '/')))
107
0
    strcpy(imHassy.HostBody, ps+1);
108
366
  else if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/')))
109
3
    strcpy(imHassy.HostBody, ps+1);
110
363
  else if ((ps = strrchr(imHassy.SensorUnitConnector, '/')))
111
0
    strcpy(imHassy.HostBody, ps+1);
112
373
  if (imHassy.HostBody[0]) {
113
10
    if ((eos = strrchr(imHassy.HostBody, '-')))
114
3
      *eos = 0;
115
10
  }
116
117
373
  if (!imHassy.format) {
118
372
    if (dng_version) {
119
16
      if (!strncmp(software, "Adobe", 5)) {
120
0
        if (!imgdata.color.OriginalRawFileName[0] ||
121
0
            !imgdata.color.LocalizedCameraModel[0] ||
122
0
            !strcasestr(imgdata.color.UniqueCameraModel, "coated"))
123
0
          imHassy.format = LIBRAW_HF_AdobeDNG_fromPhocusDNG;
124
0
        else
125
0
          imHassy.format = LIBRAW_HF_AdobeDNG;
126
16
      } else imHassy.format = LIBRAW_HF_HasselbladDNG;
127
356
    } else if ((imHassy.nIFD_CM[0] != -1) &&
128
2
               (imHassy.nIFD_CM[1] == -1) &&
129
1
               !imHassy.mnColorMatrix[0][0]) {
130
1
      imHassy.format = LIBRAW_HF_3FR;
131
355
    } else imHassy.format = LIBRAW_HF_FFF;
132
372
  }
133
134
373
  if (imHassy.SensorUnitConnector[0]) {
135
2
    char buf[64];
136
2
    if (!strncmp(imHassy.SensorUnitConnector, "Hasselblad ", 11))
137
0
      memmove(imHassy.SensorUnitConnector, imHassy.SensorUnitConnector+11, 64-11);
138
2
    strcpy(buf, imHassy.SensorUnitConnector);
139
2
    if ((eos = strrchr(buf, '/'))) {
140
0
      *eos = 0;
141
0
      if ((eos = strrchr(buf, ' '))) {
142
0
        *eos = 0;
143
0
        strcpy (imHassy.SensorUnitConnector, buf);
144
0
      }
145
0
    }
146
2
  }
147
148
373
  if (imHassy.format == LIBRAW_HF_AdobeDNG) { // Adobe DNG, use LocalizedCameraModel
149
0
      imgdata.color.LocalizedCameraModel[63] = 0; // make sure it's 0-terminated
150
0
    if ((ps = strrchr(imgdata.color.LocalizedCameraModel, '-')))
151
0
      c = int(ps-imgdata.color.LocalizedCameraModel);
152
0
    else c = int(strlen(imgdata.color.LocalizedCameraModel));
153
0
    int cc = MIN(c, (int)sizeof(tmp_model)-1);
154
0
    memcpy(tmp_model, imgdata.color.LocalizedCameraModel,cc);
155
0
    tmp_model[cc] = 0;
156
0
    if (strcasestr(imgdata.color.UniqueCameraModel, "coated")) {
157
0
      strncpy(normalized_model, imgdata.color.UniqueCameraModel,sizeof(imgdata.color.UniqueCameraModel)-1);
158
0
      normalized_model[sizeof(imgdata.color.UniqueCameraModel) - 1] = 0;
159
0
      norm_model_isSet = 1;
160
0
    }
161
0
      if (!strncmp(normalized_model, "Hasselblad ", 11))
162
0
        memmove(normalized_model, normalized_model+11, 64-11);
163
373
  } else {
164
373
    if ((ps = strrchr(imgdata.color.UniqueCameraModel, '/'))) {
165
4
      c = int(ps-imgdata.color.UniqueCameraModel);
166
4
    }
167
369
    else c = int(strlen(imgdata.color.UniqueCameraModel));
168
373
    int cc = MIN(c, (int)sizeof(tmp_model)-1);
169
373
    memcpy(tmp_model, imgdata.color.UniqueCameraModel,cc);
170
373
    tmp_model[cc] = 0;
171
373
  }
172
373
  if (!strncasecmp(tmp_model, "Hasselblad ", 11))
173
0
    memmove(tmp_model, tmp_model+11, 64-11);
174
175
373
  strncpy(imHassy.CaptureSequenceInitiator, model,31);
176
373
  imHassy.CaptureSequenceInitiator[31] = 0;
177
373
  if ((eos = strrchr(imHassy.CaptureSequenceInitiator, '/'))) {
178
6
    *eos = 0;
179
6
  }
180
// check if model tag contains manual CaptureSequenceInitiator info:
181
7.00k
  FORC(int(sizeof Hasselblad_Ctrl / sizeof *Hasselblad_Ctrl)) {
182
7.00k
    if (strcasestr(model, Hasselblad_Ctrl[c])) {
183
// yes, fill 'model' with sensor unit data
184
7
      strncpy(model, tmp_model,63);
185
7
      model[63] = 0;
186
7
      break;
187
7
    }
188
7.00k
  }
189
190
373
  if (!imHassy.HostBody[0]) {
191
363
    ps = strchr(model, '-');
192
363
    if (ps) {                  // check if model contains both host body and sensor version, resolution, MS info
193
156
      strncpy(imHassy.SensorUnit, model,63);
194
156
      memcpy(imHassy.HostBody, model, ps-model);
195
156
      imHassy.HostBody[ps-model] = 0;
196
156
      if (!strncmp(ps-2, "II-", 3))
197
5
        ps -=2;
198
156
      strncpy(imHassy.Sensor, ps,7);
199
156
      imHassy.Sensor[7] = 0;
200
156
      add_MP_toName = 0;
201
207
    } else { // model contains host body only
202
207
      strncpy(imHassy.HostBody, model,63);
203
207
      imHassy.HostBody[63] = 0;
204
  // fill 'model' with sensor unit data
205
207
      strncpy(model, tmp_model,63);
206
207
      model[63] = 0;
207
207
    }
208
363
  }
209
210
373
  if (strstr(model, "503CWD")) {
211
0
    strncpy(imHassy.HostBody, model,63);
212
0
    imHassy.HostBody[63] = 0;
213
0
    ilm.CameraFormat = LIBRAW_FORMAT_66;
214
0
    ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_V;
215
0
    if (model[6] == 'I' && model[7] == 'I')
216
0
      strcpy(model, "CFVII");
217
0
    else strcpy(model, "CFV");
218
373
  } else if (strstr(model, "Hasselblad") &&
219
7
             (model[10] != ' ')) {
220
5
    strcpy(model, "CFV");
221
5
    ilm.CameraMount = LIBRAW_MOUNT_DigitalBack;
222
368
  } else {
223
2.20k
    FORC(int(sizeof Hasselblad_SensorEnclosures / sizeof *Hasselblad_SensorEnclosures)) {
224
2.20k
      if (strcasestr(model, Hasselblad_SensorEnclosures[c])) {
225
135
        if (add_MP_toName) strcpy(model, Hasselblad_SensorEnclosures[c]);
226
135
        ilm.CameraMount = LIBRAW_MOUNT_DigitalBack;
227
135
        break;
228
135
      }
229
2.20k
    }
230
368
  }
231
232
373
#define cpynorm(str)                \
233
373
  if (!norm_model_isSet) {          \
234
17
    strcpy(normalized_model, str);  \
235
17
    norm_model_isSet = 1;           \
236
17
  }
237
238
373
  if ((imHassy.SensorCode == 4) &&
239
2
      (imHassy.CoatingCode < 2)) {
240
1
    strcpy(imHassy.Sensor, "-16");
241
1
    cpynorm("16-Uncoated");
242
243
372
  } else if ((imHassy.SensorCode == 6) &&
244
1
             (imHassy.CoatingCode < 2)) {
245
1
    strcpy(imHassy.Sensor, "-22");
246
1
    cpynorm("22-Uncoated");
247
248
371
  } else if ((imHassy.SensorCode == 8) &&
249
3
             (imHassy.CoatingCode == 1)) {
250
1
    strcpy(imHassy.Sensor, "-31");
251
1
    cpynorm("31-Uncoated");
252
253
370
  } else if ((imHassy.SensorCode == 9) &&
254
0
             (imHassy.CoatingCode < 2)) {
255
0
    strcpy(imHassy.Sensor, "-39");
256
0
    cpynorm("39-Uncoated");
257
258
370
  } else if ((imHassy.SensorCode == 9) &&
259
0
             (imHassy.CoatingCode == 4)) {
260
0
    strcpy(imHassy.Sensor, "-39");
261
0
    strcpy(model, "H3DII");
262
0
    add_MP_toName = 1;
263
0
    cpynorm("39-Coated");
264
265
370
  } else if ((imHassy.SensorCode == 13) &&
266
2
             (imHassy.CoatingCode == 4)) {
267
1
    strcpy(imHassy.Sensor, "-40");
268
1
    cpynorm("40-Coated");
269
270
369
  } else if ((imHassy.SensorCode == 13) &&
271
1
             (imHassy.CoatingCode == 5)) {
272
0
    strcpy(imHassy.Sensor, "-40");
273
0
    cpynorm("40-Coated5");
274
275
369
  } else if ((imHassy.SensorCode == 11) &&
276
3
             (imHassy.CoatingCode == 4)) {
277
1
    if (!strncmp(model, "H3D", 3))
278
0
      strcpy(model, "H3DII-50");
279
1
    else strcpy(imHassy.Sensor, "-50");
280
1
    cpynorm("50-Coated");
281
282
368
  } else if ((imHassy.SensorCode == 11) &&
283
2
             (imHassy.CoatingCode == 5)) {
284
1
    strcpy(imHassy.Sensor, "-50");
285
1
    cpynorm("50-Coated5");
286
287
367
  } else if ((imHassy.SensorCode == 15) &&
288
2
             (imHassy.CoatingCode == 5)) {
289
1
    strcpy(imHassy.Sensor, "-50c");
290
1
    cpynorm("50-15-Coated5");
291
1
    if (!strncmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) {
292
0
      imHassy.SensorSubCode = 2;
293
0
      add_MP_toName = 0;
294
0
      strcat(imHassy.Sensor, " II");
295
0
      strcpy(model, "CFV II 50C");
296
0
      strcat(normalized_model, "-II");
297
1
    } else if (!strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3)) {
298
0
      imHassy.SensorSubCode = 2;
299
0
      add_MP_toName = 0;
300
0
      strcat(imHassy.Sensor, " II");
301
0
      if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) {
302
0
        strcpy(model, "X1D II 50C");
303
0
        strcat(normalized_model, "-II");
304
0
      } else {
305
0
        strcpy(model, "X1D-50c");
306
0
      }
307
0
    }
308
309
366
  } else if ((imHassy.SensorCode == 12) &&
310
2
             (imHassy.CoatingCode == 4)) {
311
0
    strcpy(imHassy.Sensor, "-60");
312
0
    cpynorm("60-Coated");
313
314
366
  } else if ((imHassy.SensorCode == 17) &&
315
2
             (imHassy.CoatingCode == 5)) {
316
1
    strcpy(imHassy.Sensor, "-100c");
317
1
    cpynorm("100-17-Coated5");
318
319
365
  } else if ((imHassy.SensorCode == 20) &&
320
2
             (imHassy.CoatingCode == 6)) {
321
0
    strcpy(imHassy.Sensor, "-100c");
322
0
    cpynorm("100-20-Coated6");
323
324
365
  } else if ((raw_width == 4090) || // V96C
325
365
             ((raw_width == 4096) && (raw_height == 4096)) ||
326
362
             ((raw_width == 4088) && (raw_height == 4088)) || // Adobe crop
327
362
             ((raw_width == 4080) && (raw_height == 4080))) { // Phocus crop
328
3
    strcpy(imHassy.Sensor, "-16");
329
3
    cpynorm("16-Uncoated");
330
3
    if (!imHassy.SensorCode) imHassy.SensorCode = 4;
331
332
362
  } else if ((raw_width == 5568) && (raw_height == 3648)) {
333
0
    strcpy(imHassy.Sensor, "-20c");
334
335
362
  } else if (((raw_width == 4096) && (raw_height == 5456)) ||
336
362
             ((raw_width == 4088) && (raw_height == 5448)) ||  // Adobe crop
337
362
             ((raw_width == 4080) && (raw_height == 5440))) {  // Phocus crop
338
0
    strcpy(imHassy.Sensor, "-22");
339
0
    cpynorm("22-Uncoated");
340
0
    if (!imHassy.SensorCode) imHassy.SensorCode = 6;
341
342
362
  } else if (((raw_width == 6542) && (raw_height == 4916)) ||
343
362
             ((raw_width == 6504) && (raw_height == 4880)) || // Adobe crop
344
362
             ((raw_width == 6496) && (raw_height == 4872))) { // Phocus crop
345
0
    strcpy(imHassy.Sensor, "-31");
346
0
    cpynorm("31-Uncoated");
347
0
    if (!imHassy.SensorCode) imHassy.SensorCode = 8;
348
349
362
  } else if (((raw_width == 7262) && (raw_height == 5456)) || //
350
362
             ((raw_width == 7224) && (raw_height == 5420)) || // Adobe crop
351
362
             ((raw_width == 7216) && (raw_height == 5412)) || // Phocus crop
352
362
             ((raw_width == 7212) && (raw_height == 5412)) || // CF-39, CFV-39, possibly v.II; Phocus crop
353
// uncropped, when the exact size is unknown, should be:
354
// - greater or equal to the smallest Phocus crop for the current size
355
// - smaller than the smallest Phocus crop for the next size
356
362
           ((nPix >= 7212*5412) && (nPix < 7304*5478))) {
357
3
    strcpy(imHassy.Sensor, "-39");
358
3
    if (!imHassy.SensorCode) imHassy.SensorCode = 9;
359
3
    if (!strncmp(model, "H3D", 3)) {
360
0
      if (((imHassy.format == LIBRAW_HF_Imacon) ||
361
0
          strstr(imgdata.color.UniqueCameraModel, "H3D-39") ||
362
0
          strstr(imgdata.color.LocalizedCameraModel, "H3D-39") ||
363
0
          strstr(model, "H3D-39")) &&
364
0
          !strstr(imgdata.color.UniqueCameraModel, "II") &&
365
0
          !strstr(imgdata.color.LocalizedCameraModel, "II") &&
366
0
          !strstr(model, "II")) {
367
0
        strcpy(model, "H3D-39");
368
0
        add_MP_toName = 0;
369
0
        cpynorm("39-Uncoated");
370
371
0
      } else {
372
0
        strcpy(model, "H3DII-39");
373
0
        add_MP_toName = 0;
374
0
        cpynorm("39-Coated");
375
0
        if (!imHassy.CoatingCode) imHassy.CoatingCode = 4;
376
0
      }
377
378
0
    } else
379
3
      cpynorm("39-Uncoated");
380
381
359
  } else if (((raw_width == 7410) && (raw_height == 5586)) || // (H4D-40, H5D-40)
382
359
             ((raw_width == 7312) && (raw_height == 5486)) || // Adobe crop
383
359
             ((raw_width == 7304) && (raw_height == 5478))) { // Phocus crop
384
0
    strcpy(imHassy.Sensor, "-40");
385
0
    if (!strncmp(model, "H4D", 3)) {
386
0
      cpynorm("40-Coated");
387
0
      if (!imHassy.SensorCode) imHassy.SensorCode = 13;
388
0
      if (!imHassy.CoatingCode) imHassy.CoatingCode = 4;
389
0
    } else {
390
0
      cpynorm("40-Coated5");
391
0
      if (!imHassy.SensorCode) imHassy.SensorCode = 13;
392
0
      if (!imHassy.CoatingCode) imHassy.CoatingCode = 5;
393
0
    }
394
395
359
  } else if (((raw_width == 8282) && (raw_height == 6240)) || // (CFV-50, H3DII-50, H5D-50)
396
359
             ((raw_width == 8184) && (raw_height == 6140)) || // Adobe crop
397
359
             ((raw_width == 8176) && (raw_height == 6132))) { // Phocus crop
398
0
    strcpy(imHassy.Sensor, "-50");
399
0
    if (!strncmp(model, "H5D", 3)) {
400
0
      cpynorm("50-Coated5");
401
0
      if (!imHassy.SensorCode) imHassy.SensorCode = 11;
402
0
      if (!imHassy.CoatingCode) imHassy.CoatingCode = 5;
403
0
    } else {
404
0
      cpynorm("50-Coated"); // CFV-50, H3DII-50,
405
0
      if (!strncmp(model, "H3D", 3)) {
406
0
        strcpy(model, "H3DII-50");
407
0
      if (!imHassy.SensorCode) imHassy.SensorCode = 11;
408
0
      if (!imHassy.CoatingCode) imHassy.CoatingCode = 4;
409
0
        add_MP_toName = 0;
410
0
      }
411
0
    }
412
413
359
  } else if (((raw_width == 8374) && (raw_height == 6304)) ||  // (H5D-50c, CFV-50c)
414
359
             ((raw_width == 8384) && (raw_height == 6304)) ||  // (X1D-50c, "X1D II 50C", "CFV II 50C")
415
359
             ((raw_width == 8280) && (raw_height == 6208)) ||  // Adobe crop
416
359
             ((raw_width == 8272) && (raw_height == 6200))) {  // Phocus crop
417
0
    cpynorm("50-15-Coated5");
418
0
    if (!imHassy.SensorCode) imHassy.SensorCode = 15;
419
0
    if (!imHassy.CoatingCode) imHassy.CoatingCode = 5;
420
0
    strcpy(imHassy.Sensor, "-50c");
421
0
    if ((raw_width == 8384) ||
422
0
        !strncmp(imHassy.CaptureSequenceInitiator, "X1D", 3) ||
423
0
        !strncmp(imHassy.CaptureSequenceInitiator, "CFV II", 6)) {
424
0
      imHassy.SensorSubCode = 2;
425
0
      add_MP_toName = 0;
426
0
      strcat(imHassy.Sensor, " II");
427
0
      if (strstr(imHassy.CaptureSequenceInitiator, " II ")) {
428
0
          strcat(normalized_model, "-II");
429
0
        if (!strncasecmp(imHassy.CaptureSequenceInitiator, "X1D II 50C", 10)) {
430
0
          strcpy(model, "X1D II 50C");
431
0
        } else if (!strncasecmp(imHassy.CaptureSequenceInitiator, "CFV II 50C", 10)) {
432
0
          strcpy(model, "CFV II 50C");
433
0
        }
434
0
      } else {
435
0
        strcpy(model, "X1D-50c");
436
0
      }
437
0
    }
438
439
359
  } else if (((raw_width == 9044) && (raw_height == 6732)) ||
440
359
             ((raw_width == 8964) && (raw_height == 6716)) || // Adobe crop
441
359
             ((raw_width == 8956) && (raw_height == 6708))) { // Phocus crop
442
0
    strcpy(imHassy.Sensor, "-60");
443
0
    cpynorm("60-Coated");
444
0
    if (!imHassy.SensorCode) imHassy.SensorCode = 12;
445
0
    if (!imHassy.CoatingCode) imHassy.CoatingCode = 4;
446
447
448
359
  } else if (((raw_width == 10320) && (raw_height == 7752)) || // Phocus crop, A5D-80
449
359
             ((nPix >= 10320*7752) && (nPix < 10520*8000))) {
450
2
    strcpy(imHassy.Sensor, "-80");
451
2
    cpynorm("80-Coated");
452
453
357
  } else if (((raw_width == 12000) && (raw_height == 8816)) ||
454
356
             ((raw_width == 11608) && (raw_height == 8708)) || // Adobe crop
455
356
             ((raw_width == 11600) && (raw_height == 8700))) { // Phocus crop
456
1
    strcpy(imHassy.Sensor, "-100c");
457
1
    cpynorm("100-17-Coated5");
458
1
    if (!imHassy.SensorCode) imHassy.SensorCode = 17;
459
1
    if (!imHassy.CoatingCode) imHassy.CoatingCode = 5;
460
461
356
  } else if (((raw_width == 11904) && (raw_height == 8842)) || // X2D 100C, CFV 100C
462
356
             ((raw_width == 11664) && (raw_height == 8750)) || // Adobe crop
463
356
             ((raw_width == 11656) && (raw_height == 8742))) { // Phocus crop
464
0
    strcpy(imHassy.Sensor, "-100c");
465
0
    cpynorm("100-20-Coated6");
466
0
    if (!imHassy.SensorCode) imHassy.SensorCode = 20;
467
0
    if (!imHassy.CoatingCode) imHassy.CoatingCode = 6;
468
469
0
  }
470
471
373
  if (raw_width == 4090)
472
0
    strcpy(model, "V96C");
473
474
373
  if (
475
373
    (raw_width == 4090) ||
476
373
    ((raw_width ==  4096) && (raw_height ==  4096)) ||
477
370
    ((raw_width ==  5568) && (raw_height ==  3648)) ||
478
370
    ((raw_width ==  4096) && (raw_height ==  5456)) ||
479
370
    ((raw_width ==  6542) && (raw_height ==  4916)) ||
480
370
    ((raw_width ==  7262) && (raw_height ==  5456)) ||
481
370
    ((raw_width ==  7410) && (raw_height ==  5586)) ||
482
370
    ((raw_width ==  8282) && (raw_height ==  6240)) ||
483
370
    ((raw_width ==  8374) && (raw_height ==  6304)) ||
484
370
    ((raw_width ==  8384) && (raw_height ==  6304)) ||
485
370
    ((raw_width ==  9044) && (raw_height ==  6732)) ||
486
370
    ((raw_width == 10320) && (raw_height ==  7752)) ||
487
370
    ((raw_width == 12000) && (raw_height ==  8816)) ||
488
369
    ((raw_width == 11904) && (raw_height ==  8842))
489
373
  )
490
4
  imHassy.uncropped = 1;
491
492
493
373
  if (model[0] && add_MP_toName)
494
8
    strcat(model, imHassy.Sensor);
495
373
  if (imHassy.Sensor[0] == '-')
496
162
    memmove(imHassy.Sensor, imHassy.Sensor+1, strlen(imHassy.Sensor));
497
498
373
  if (dng_version &&
499
16
      (imHassy.SensorCode == 13) &&
500
1
      (imHassy.CoatingCode == 4)) {
501
0
    c = LIBRAW_HF_AdobeDNG;
502
373
  } else if ((imHassy.format == LIBRAW_HF_HasselbladDNG) ||
503
357
             (imHassy.format == LIBRAW_HF_AdobeDNG_fromPhocusDNG)) {
504
16
    c = LIBRAW_HF_FFF;
505
357
  } else if (imHassy.format == LIBRAW_HF_Imacon) {
506
1
    c = LIBRAW_HF_3FR;
507
356
  } else {
508
356
    c = imHassy.format;
509
356
  }
510
373
  ps = HassyRawFormat_idx2HR(c);
511
373
  if ((c == LIBRAW_HF_3FR) ||
512
371
      (c == LIBRAW_HF_FFF))
513
373
    strcat(normalized_model, ps);
514
515
373
  if (((imHassy.CaptureSequenceInitiator[0] == 'H') &&
516
12
       (imHassy.CaptureSequenceInitiator[1] != 'a')) ||
517
364
      ((imHassy.CaptureSequenceInitiator[0] == 'A') &&
518
12
       isdigit(imHassy.CaptureSequenceInitiator[1]))) {
519
12
    ilm.CameraFormat = LIBRAW_FORMAT_645;
520
12
    ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_H;
521
12
    if (imgdata.lens.Lens[0] == 'H')
522
3
      process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H);
523
361
  } else if (((imHassy.CaptureSequenceInitiator[0] == 'X') &&
524
8
              isdigit(imHassy.CaptureSequenceInitiator[1])) ||
525
354
             !strncmp(imHassy.HostBody, "907", 3)) {
526
9
    ilm.CameraFormat = LIBRAW_FORMAT_CROP645;
527
9
    ilm.CameraMount = LIBRAW_MOUNT_Hasselblad_XCD;
528
9
    if (imgdata.lens.Lens[0] == 'H') {
529
1
      process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_H);
530
1
      strcpy(ilm.Adapter, "XH");
531
8
    } else {
532
8
      if (imgdata.lens.Lens[0] == 'X') {
533
3
        process_Hassy_Lens(LIBRAW_MOUNT_Hasselblad_XCD);
534
5
      } else if (!imgdata.lens.Lens[0] &&
535
4
                 (aperture > 1.0f)   &&
536
2
                 (focal_len > 10.0f)) {
537
1
        ilm.LensID = uint64_t(focal_len);
538
1
        if (ilm.LensID == 35) {
539
0
          ilm.FocalType = LIBRAW_FT_ZOOM_LENS;
540
0
          ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL +
541
0
                       35*10000ULL + 75*10;
542
0
        }
543
1
        else {
544
1
          ilm.FocalType = LIBRAW_FT_PRIME_LENS;
545
1
          ilm.LensID = LIBRAW_MOUNT_Hasselblad_XCD*100000000ULL +
546
1
                       ilm.LensID*10000ULL + ilm.LensID*10;
547
1
        }
548
1
      }
549
8
    }
550
9
  }
551
// printf (">>Host Body: =%s= CaptureSequenceInitiator: =%s=\n", imHassy.HostBody, imHassy.CaptureSequenceInitiator);
552
// printf (">> SensorCode: %d, CoatingCode: %d, Sensor: =%s=\n", imHassy.SensorCode, imHassy.CoatingCode, imHassy.Sensor);
553
// printf (">> raw_width: %d, raw_height: %d\n", raw_width, raw_height);
554
555
373
  if (normalized_model[0]  && !CM_found)
556
373
    CM_found = adobe_coeff(maker_index, normalized_model);
557
373
}