Coverage Report

Created: 2026-04-01 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/LibRaw/src/decoders/fp_dng.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw is free software; you can redistribute it and/or modify
5
 it under the terms of the one of two licenses as you choose:
6
7
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
8
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
9
10
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
11
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
12
13
 */
14
15
#include "../../internal/libraw_cxx_defs.h"
16
17
inline unsigned int __DNG_HalfToFloat(ushort halfValue)
18
34.5M
{
19
34.5M
  int sign = (halfValue >> 15) & 0x00000001;
20
34.5M
  int exponent = (halfValue >> 10) & 0x0000001f;
21
34.5M
  int mantissa = halfValue & 0x000003ff;
22
34.5M
  if (exponent == 0)
23
16.3M
  {
24
16.3M
    if (mantissa == 0)
25
7.76M
    {
26
7.76M
      return (unsigned int)(sign << 31);
27
7.76M
    }
28
8.61M
    else
29
8.61M
    {
30
50.8M
      while (!(mantissa & 0x00000400))
31
42.2M
      {
32
42.2M
        mantissa <<= 1;
33
42.2M
        exponent -= 1;
34
42.2M
      }
35
8.61M
      exponent += 1;
36
8.61M
      mantissa &= ~0x00000400;
37
8.61M
    }
38
16.3M
  }
39
18.2M
  else if (exponent == 31)
40
3.29M
  {
41
3.29M
    if (mantissa == 0)
42
68.1k
    {
43
68.1k
      return (unsigned int)((sign << 31) | ((0x1eL + 127 - 15) << 23) |
44
68.1k
                            (0x3ffL << 13));
45
68.1k
    }
46
3.23M
    else
47
3.23M
    {
48
3.23M
      return 0;
49
3.23M
    }
50
3.29M
  }
51
23.5M
  exponent += (127 - 15);
52
23.5M
  mantissa <<= 13;
53
23.5M
  return (unsigned int)((sign << 31) | (exponent << 23) | mantissa);
54
34.5M
}
55
56
inline unsigned int __DNG_FP24ToFloat(const unsigned char *input)
57
277k
{
58
277k
  int sign = (input[0] >> 7) & 0x01;
59
277k
  int exponent = (input[0]) & 0x7F;
60
277k
  int mantissa = (((int)input[1]) << 8) | input[2];
61
277k
  if (exponent == 0)
62
79.7k
  {
63
79.7k
    if (mantissa == 0)
64
29.0k
    {
65
29.0k
      return (unsigned int)(sign << 31);
66
29.0k
    }
67
50.6k
    else
68
50.6k
    {
69
413k
      while (!(mantissa & 0x00010000))
70
362k
      {
71
362k
        mantissa <<= 1;
72
362k
        exponent -= 1;
73
362k
      }
74
50.6k
      exponent += 1;
75
50.6k
      mantissa &= ~0x00010000;
76
50.6k
    }
77
79.7k
  }
78
198k
  else if (exponent == 127)
79
17.0k
  {
80
17.0k
    if (mantissa == 0)
81
1.29k
    {
82
1.29k
      return (unsigned int)((sign << 31) | ((0x7eL + 128 - 64) << 23) |
83
1.29k
                            (0xffffL << 7));
84
1.29k
    }
85
15.7k
    else
86
15.7k
    {
87
      // Nan -- Just set to zero.
88
15.7k
      return 0;
89
15.7k
    }
90
17.0k
  }
91
231k
  exponent += (128 - 64);
92
231k
  mantissa <<= 7;
93
231k
  return (uint32_t)((sign << 31) | (exponent << 23) | mantissa);
94
277k
}
95
96
inline void DecodeDeltaBytes(unsigned char *bytePtr, int cols, int channels)
97
0
{
98
0
  if (channels == 1)
99
0
  {
100
0
    unsigned char b0 = bytePtr[0];
101
0
    bytePtr += 1;
102
0
    for (int col = 1; col < cols; ++col)
103
0
    {
104
0
      b0 += bytePtr[0];
105
0
      bytePtr[0] = b0;
106
0
      bytePtr += 1;
107
0
    }
108
0
  }
109
0
  else if (channels == 3)
110
0
  {
111
0
    unsigned char b0 = bytePtr[0];
112
0
    unsigned char b1 = bytePtr[1];
113
0
    unsigned char b2 = bytePtr[2];
114
0
    bytePtr += 3;
115
0
    for (int col = 1; col < cols; ++col)
116
0
    {
117
0
      b0 += bytePtr[0];
118
0
      b1 += bytePtr[1];
119
0
      b2 += bytePtr[2];
120
0
      bytePtr[0] = b0;
121
0
      bytePtr[1] = b1;
122
0
      bytePtr[2] = b2;
123
0
      bytePtr += 3;
124
0
    }
125
0
  }
126
0
  else if (channels == 4)
127
0
  {
128
0
    unsigned char b0 = bytePtr[0];
129
0
    unsigned char b1 = bytePtr[1];
130
0
    unsigned char b2 = bytePtr[2];
131
0
    unsigned char b3 = bytePtr[3];
132
0
    bytePtr += 4;
133
0
    for (int col = 1; col < cols; ++col)
134
0
    {
135
0
      b0 += bytePtr[0];
136
0
      b1 += bytePtr[1];
137
0
      b2 += bytePtr[2];
138
0
      b3 += bytePtr[3];
139
0
      bytePtr[0] = b0;
140
0
      bytePtr[1] = b1;
141
0
      bytePtr[2] = b2;
142
0
      bytePtr[3] = b3;
143
0
      bytePtr += 4;
144
0
    }
145
0
  }
146
0
  else
147
0
  {
148
0
    for (int col = 1; col < cols; ++col)
149
0
    {
150
0
      for (int chan = 0; chan < channels; ++chan)
151
0
      {
152
0
        bytePtr[chan + channels] += bytePtr[chan];
153
0
      }
154
0
      bytePtr += channels;
155
0
    }
156
0
  }
157
0
}
158
159
#ifdef USE_ZLIB
160
static void DecodeFPDelta(unsigned char *input, unsigned char *output, int cols,
161
                          int channels, int bytesPerSample)
162
0
{
163
0
  DecodeDeltaBytes(input, cols * bytesPerSample, channels);
164
0
  int32_t rowIncrement = cols * channels;
165
166
0
  if (bytesPerSample == 2)
167
0
  {
168
169
#if LibRawBigEndian
170
    const unsigned char *input0 = input;
171
    const unsigned char *input1 = input + rowIncrement;
172
#else
173
0
    const unsigned char *input1 = input;
174
0
    const unsigned char *input0 = input + rowIncrement;
175
0
#endif
176
0
    for (int col = 0; col < rowIncrement; ++col)
177
0
    {
178
0
      output[0] = input0[col];
179
0
      output[1] = input1[col];
180
0
      output += 2;
181
0
    }
182
0
  }
183
0
  else if (bytesPerSample == 3)
184
0
  {
185
0
    const unsigned char *input0 = input;
186
0
    const unsigned char *input1 = input + rowIncrement;
187
0
    const unsigned char *input2 = input + rowIncrement * 2;
188
0
    for (int col = 0; col < rowIncrement; ++col)
189
0
    {
190
0
      output[0] = input0[col];
191
0
      output[1] = input1[col];
192
0
      output[2] = input2[col];
193
0
      output += 3;
194
0
    }
195
0
  }
196
0
  else
197
0
  {
198
#if LibRawBigEndian
199
    const unsigned char *input0 = input;
200
    const unsigned char *input1 = input + rowIncrement;
201
    const unsigned char *input2 = input + rowIncrement * 2;
202
    const unsigned char *input3 = input + rowIncrement * 3;
203
#else
204
0
    const unsigned char *input3 = input;
205
0
    const unsigned char *input2 = input + rowIncrement;
206
0
    const unsigned char *input1 = input + rowIncrement * 2;
207
0
    const unsigned char *input0 = input + rowIncrement * 3;
208
0
#endif
209
0
    for (int col = 0; col < rowIncrement; ++col)
210
0
    {
211
0
      output[0] = input0[col];
212
0
      output[1] = input1[col];
213
0
      output[2] = input2[col];
214
0
      output[3] = input3[col];
215
0
      output += 4;
216
0
    }
217
0
  }
218
0
}
219
#endif
220
221
static float expandFloats(unsigned char *dst, int tileWidth, int bytesps)
222
123k
{
223
123k
  float max = 0.f;
224
123k
  if (bytesps == 2)
225
121k
  {
226
121k
    uint16_t *dst16 = (ushort *)dst;
227
121k
    uint32_t *dst32 = (unsigned int *)dst;
228
121k
    float *f32 = (float *)dst;
229
34.7M
    for (int index = tileWidth - 1; index >= 0; --index)
230
34.5M
    {
231
34.5M
      dst32[index] = __DNG_HalfToFloat(dst16[index]);
232
34.5M
      max = MAX(max, f32[index]);
233
34.5M
    }
234
121k
  }
235
1.71k
  else if (bytesps == 3)
236
1.55k
  {
237
1.55k
    uint8_t *dst8 = ((unsigned char *)dst) + (tileWidth - 1) * 3;
238
1.55k
    uint32_t *dst32 = (unsigned int *)dst;
239
1.55k
    float *f32 = (float *)dst;
240
279k
    for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3)
241
277k
    {
242
277k
      dst32[index] = __DNG_FP24ToFloat(dst8);
243
277k
      max = MAX(max, f32[index]);
244
277k
    }
245
1.55k
  }
246
155
  else if (bytesps == 4)
247
155
  {
248
155
    float *f32 = (float *)dst;
249
9.50k
    for (int index = 0; index < tileWidth; index++)
250
9.35k
      max = MAX(max, f32[index]);
251
155
  }
252
123k
  return max;
253
123k
}
254
255
struct tile_stripe_data_t
256
{
257
    bool tiled, striped;
258
    int tileCnt;
259
    unsigned tileWidth, tileHeight, tilesH, tilesV;
260
    INT64 maxBytesInTile;
261
    std::vector<INT64> tOffsets, tBytes;
262
127
    tile_stripe_data_t() : tiled(false), striped(false),tileCnt(0),
263
127
        tileWidth(0),tileHeight(0),tilesH(0),tilesV(0),
264
127
        maxBytesInTile(0){}
265
    void init(tiff_ifd_t *ifd, const libraw_image_sizes_t&, const unpacker_data_t&,
266
        short _order,
267
        LibRaw_abstract_datastream *stream);
268
};
269
270
static unsigned static_get4(LibRaw_abstract_datastream *stream, short _order)
271
0
{
272
0
    uchar str[4] = { 0xff, 0xff, 0xff, 0xff };
273
0
    stream->read(str, 1, 4);
274
0
    return libraw_sget4_static(_order, str);
275
0
}
276
277
278
void tile_stripe_data_t::init(tiff_ifd_t *ifd, const libraw_image_sizes_t& sizes, 
279
    const unpacker_data_t& unpacker_data, short _order, LibRaw_abstract_datastream *stream)
280
127
{
281
127
    tiled = (unpacker_data.tile_width <= sizes.raw_width) && (unpacker_data.tile_length <= sizes.raw_height);
282
127
    striped = (ifd->rows_per_strip > 0 && ifd->rows_per_strip < sizes.raw_height) && ifd->strip_byte_counts_count > 0;
283
284
127
    tileWidth = tiled ? unpacker_data.tile_width : sizes.raw_width;
285
127
    tileHeight = tiled ? unpacker_data.tile_length :(striped ? ifd->rows_per_strip : sizes.raw_height);
286
127
    tilesH = tiled ? (sizes.raw_width + tileWidth - 1) / tileWidth : 1;
287
127
    tilesV = tiled ? (sizes.raw_height + tileHeight - 1) / tileHeight :
288
127
        (striped ? ((sizes.raw_height + ifd->rows_per_strip - 1) / ifd->rows_per_strip) : 1);
289
127
    tileCnt = tilesH * tilesV;
290
291
127
    if (tileCnt < 1 || tileCnt > 1000000)
292
0
        throw LIBRAW_EXCEPTION_DECODE_RAW;
293
294
127
    tOffsets = std::vector<INT64>(tileCnt,0);
295
127
    tBytes = std::vector <INT64>(tileCnt,0);
296
297
127
    if (tiled)
298
0
        for (int t = 0; t < tileCnt; ++t)
299
0
            tOffsets[t] = static_get4(stream, _order);
300
127
    else if (striped)
301
306
        for (int t = 0; t < tileCnt && t < ifd->strip_offsets_count; ++t)
302
267
            tOffsets[t] = ifd->strip_offsets[t];
303
88
    else
304
88
        tOffsets[0] = ifd->offset;
305
306
127
    maxBytesInTile = 0;
307
308
127
    if (tileCnt == 1 || (!tiled && !striped))
309
88
        tBytes[0] = maxBytesInTile = ifd->bytes;
310
39
    else if (tiled)
311
0
    {
312
        // ifd->bytes points to tile size table if more than 1 tile exists
313
0
        stream->seek(ifd->bytes, SEEK_SET);
314
0
        for (int t = 0; t < tileCnt; ++t)
315
0
        {
316
0
            tBytes[t] = static_get4(stream, _order); ;
317
0
            maxBytesInTile = MAX(maxBytesInTile, tBytes[t]);
318
0
        }
319
0
    }
320
39
    else if (striped)
321
493
        for (int t = 0; t < tileCnt && t < ifd->strip_byte_counts_count; ++t)
322
454
        {
323
454
            tBytes[t] = ifd->strip_byte_counts[t];
324
454
            maxBytesInTile = MAX(maxBytesInTile, tBytes[t]);
325
454
        }
326
127
}
327
328
#ifdef USE_ZLIB
329
void LibRaw::deflate_dng_load_raw()
330
11
{
331
11
  int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset);
332
11
  if(iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds)
333
0
      throw LIBRAW_EXCEPTION_DECODE_RAW;
334
11
  struct tiff_ifd_t *ifd = &tiff_ifd[iifd];
335
336
11
  float *float_raw_image = 0;
337
11
  float max = 0.f;
338
339
11
  if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4)
340
2
    throw LIBRAW_EXCEPTION_DECODE_RAW; 
341
342
9
  if (libraw_internal_data.unpacker_data.tiff_samples != (unsigned)ifd->samples)
343
0
    throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD
344
345
9
  if (imgdata.idata.filters && ifd->samples > 1)
346
2
    throw LIBRAW_EXCEPTION_DECODE_RAW;
347
348
7
  tile_stripe_data_t tiles;
349
7
  tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order,
350
7
      libraw_internal_data.internal_data.input);
351
352
7
  if (tiles.tBytes.size() < 1)
353
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
354
355
  // Ensure less then 2GB per compressed tile
356
7
  INT64 maxcomprlen = tiles.tBytes[0];
357
7
  for (int i = 1; i < tiles.tBytes.size(); i++)
358
0
    maxcomprlen = MAX(maxcomprlen, tiles.tBytes[i]);
359
360
7
  if(maxcomprlen >= (1LL << 31) || maxcomprlen < 0)
361
1
    throw LIBRAW_EXCEPTION_TOOBIG;
362
  
363
  // Max bytes: 2^16 raw width * 2^2 bytes/pixel * 2^2 channels = 2^20, so check against 2^22
364
6
  INT64 rowbytes = INT64(MAX(tiles.tileWidth, imgdata.sizes.raw_width)) * 4ULL * INT64(ifd->samples);
365
6
  if (rowbytes > (1LL << 22))
366
0
    throw LIBRAW_EXCEPTION_TOOBIG;
367
368
6
  if (ifd->sample_format == 3)
369
4
  {
370
4
    INT64 raw_bytes = INT64(tiles.tileCnt) * INT64(tiles.tileWidth) * INT64(tiles.tileHeight) * INT64(ifd->samples) * sizeof(float);
371
4
    if (raw_bytes > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024))
372
0
      throw LIBRAW_EXCEPTION_TOOBIG;
373
4
    float_raw_image = (float *)calloc(raw_bytes, 1);
374
4
  }
375
2
  else
376
2
    throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float deflated supported
377
378
4
  int xFactor;
379
4
  switch (ifd->predictor)
380
4
  {
381
0
  case 3:
382
4
  default:
383
4
    xFactor = 1;
384
4
    break;
385
0
  case 34894:
386
0
    xFactor = 2;
387
0
    break;
388
0
  case 34895:
389
0
    xFactor = 4;
390
0
    break;
391
4
  }
392
393
4
  INT64 tilePixels =  INT64(tiles.tileWidth) * INT64(tiles.tileHeight);
394
4
  unsigned pixelSize = sizeof(float) * ifd->samples;
395
4
  INT64 tileBytes = tilePixels * INT64(pixelSize);
396
4
  INT64 tileRowBytes = INT64(tiles.tileWidth) * INT64(pixelSize);
397
398
4
  if(INT64(tiles.maxBytesInTile) > INT64(imgdata.rawparams.max_raw_memory_mb) * 1024LL * 1024LL )
399
0
    throw LIBRAW_EXCEPTION_TOOBIG;
400
401
4
  if (tileBytes + tileRowBytes > INT64(imgdata.rawparams.max_raw_memory_mb) * 1024LL * 1024LL)
402
0
    throw LIBRAW_EXCEPTION_TOOBIG;
403
404
4
  std::vector<uchar> cBuffer(tiles.maxBytesInTile,0);
405
4
  std::vector<uchar> uBuffer(tileBytes + tileRowBytes,0); // extra row for decoding
406
407
5
  for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight)
408
4
    {
409
5
      for (size_t x = 0; x < imgdata.sizes.raw_width; x += tiles.tileWidth, ++t)
410
4
      {
411
4
        libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET);
412
4
        int bytesread = libraw_internal_data.internal_data.input->read(cBuffer.data(), 1, tiles.tBytes[t]);
413
4
    if (bytesread < tiles.tBytes[t])
414
1
      derror();
415
4
        unsigned long dstLen = tileBytes;
416
4
        int err =
417
4
            uncompress(uBuffer.data() + tileRowBytes, &dstLen, cBuffer.data(), (unsigned long)tiles.tBytes[t]);
418
4
        if (err != Z_OK)
419
3
        {
420
3
          throw LIBRAW_EXCEPTION_DECODE_RAW;
421
0
          return;
422
3
        }
423
1
        else
424
1
        {
425
1
          int bytesps = ifd->bps >> 3;
426
1
          size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight;
427
1
          size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth;
428
429
1
          for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed
430
0
          {
431
0
              unsigned char *dst = uBuffer.data() + row * tiles.tileWidth * bytesps * ifd->samples;
432
0
              unsigned char *src = dst + tileRowBytes;
433
0
              DecodeFPDelta(src, dst, tiles.tileWidth / xFactor, ifd->samples * xFactor, bytesps);
434
0
              float lmax = expandFloats(dst, tiles.tileWidth * ifd->samples, bytesps);
435
0
            max = MAX(max, lmax);
436
0
            unsigned char *dst2 = (unsigned char *)&float_raw_image
437
0
                [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples];
438
0
            memmove(dst2, dst, colsInTile * ifd->samples * sizeof(float));
439
0
          }
440
1
        }
441
4
      }
442
4
    }
443
  
444
1
  imgdata.color.fmaximum = max;
445
446
  // Set fields according to data format
447
448
1
  imgdata.rawdata.raw_alloc = float_raw_image;
449
1
  if (ifd->samples == 1)
450
0
  {
451
0
    imgdata.rawdata.float_image = float_raw_image;
452
0
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
453
0
        imgdata.sizes.raw_width * 4;
454
0
  }
455
1
  else if (ifd->samples == 3)
456
0
  {
457
0
    imgdata.rawdata.float3_image = (float(*)[3])float_raw_image;
458
0
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
459
0
        imgdata.sizes.raw_width * 12;
460
0
  }
461
1
  else if (ifd->samples == 4)
462
0
  {
463
0
    imgdata.rawdata.float4_image = (float(*)[4])float_raw_image;
464
0
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
465
0
        imgdata.sizes.raw_width * 16;
466
0
  }
467
468
1
  if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)
469
0
    convertFloatToInt(); // with default settings
470
1
}
471
#else
472
void LibRaw::deflate_dng_load_raw() { throw LIBRAW_EXCEPTION_DECODE_RAW; }
473
#endif
474
475
int LibRaw::is_floating_point()
476
0
{
477
0
  struct tiff_ifd_t *ifd = &tiff_ifd[0];
478
0
  while (ifd < &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds] &&
479
0
         ifd->offset != libraw_internal_data.unpacker_data.data_offset)
480
0
    ++ifd;
481
0
  if (ifd == &tiff_ifd[libraw_internal_data.identify_data.tiff_nifds])
482
0
    return 0;
483
484
0
  return ifd->sample_format == 3;
485
0
}
486
487
int LibRaw::have_fpdata()
488
0
{
489
0
  return imgdata.rawdata.float_image || imgdata.rawdata.float3_image ||
490
0
         imgdata.rawdata.float4_image;
491
0
}
492
493
void LibRaw::convertFloatToInt(float dmin /* =4096.f */,
494
                               float dmax /* =32767.f */,
495
                               float dtarget /*= 16383.f */)
496
39
{
497
39
  int samples = 0;
498
39
  float *data = 0;
499
39
  void *orawalloc = imgdata.rawdata.raw_alloc;
500
39
  if (imgdata.rawdata.float_image)
501
12
  {
502
12
    samples = 1;
503
12
    data = imgdata.rawdata.float_image;
504
12
  }
505
27
  else if (imgdata.rawdata.float3_image)
506
26
  {
507
26
    samples = 3;
508
26
    data = (float *)imgdata.rawdata.float3_image;
509
26
  }
510
1
  else if (imgdata.rawdata.float4_image)
511
1
  {
512
1
    samples = 4;
513
1
    data = (float *)imgdata.rawdata.float4_image;
514
1
  }
515
0
  else
516
0
    return;
517
518
39
  ushort *raw_alloc = (ushort *)malloc(
519
39
      imgdata.sizes.raw_height * imgdata.sizes.raw_width *
520
39
      libraw_internal_data.unpacker_data.tiff_samples * sizeof(ushort));
521
39
  float tmax = float(MAX(imgdata.color.maximum, 1));
522
39
  float datamax = imgdata.color.fmaximum;
523
524
39
  tmax = MAX(tmax, datamax);
525
39
  tmax = MAX(tmax, 1.f);
526
527
39
  float multip = 1.f;
528
39
  if (tmax < dmin || tmax > dmax)
529
39
  {
530
39
    imgdata.rawdata.color.fnorm = imgdata.color.fnorm = multip = dtarget / tmax;
531
39
    imgdata.rawdata.color.maximum = imgdata.color.maximum = unsigned(dtarget);
532
39
    imgdata.rawdata.color.black = imgdata.color.black =
533
39
        unsigned((float)imgdata.color.black * multip);
534
39
    for (int i = 0;
535
160k
         i < int(sizeof(imgdata.color.cblack)/sizeof(imgdata.color.cblack[0]));
536
160k
         i++)
537
160k
      if (i != 4 && i != 5)
538
159k
        imgdata.rawdata.color.cblack[i] = imgdata.color.cblack[i] =
539
159k
            unsigned((float)imgdata.color.cblack[i] * multip);
540
39
  }
541
0
  else
542
0
    imgdata.rawdata.color.fnorm = imgdata.color.fnorm = 0.f;
543
544
34.6M
  for (size_t i = 0; i < imgdata.sizes.raw_height * imgdata.sizes.raw_width *
545
34.6M
                             libraw_internal_data.unpacker_data.tiff_samples;
546
34.6M
       ++i)
547
34.6M
  {
548
34.6M
    float val = MAX(data[i], 0.f);
549
34.6M
    raw_alloc[i] = (ushort)(val * multip);
550
34.6M
  }
551
552
39
  if (samples == 1)
553
12
  {
554
12
    imgdata.rawdata.raw_alloc = imgdata.rawdata.raw_image = raw_alloc;
555
12
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
556
12
        imgdata.sizes.raw_width * 2;
557
12
  }
558
27
  else if (samples == 3)
559
26
  {
560
26
    imgdata.rawdata.raw_alloc = imgdata.rawdata.color3_image =
561
26
        (ushort(*)[3])raw_alloc;
562
26
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
563
26
        imgdata.sizes.raw_width * 6;
564
26
  }
565
1
  else if (samples == 4)
566
1
  {
567
1
    imgdata.rawdata.raw_alloc = imgdata.rawdata.color4_image =
568
1
        (ushort(*)[4])raw_alloc;
569
1
    imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
570
1
        imgdata.sizes.raw_width * 8;
571
1
  }
572
39
  if(orawalloc)
573
39
    free(orawalloc); // remove old allocation
574
39
  imgdata.rawdata.float_image = 0;
575
39
  imgdata.rawdata.float3_image = 0;
576
39
  imgdata.rawdata.float4_image = 0;
577
39
}
578
579
static
580
#if (defined(_MSC_VER) && !defined(__clang__))
581
_forceinline
582
#else
583
inline
584
#endif
585
void libraw_swap24(uchar *data, int len)
586
1.55k
{
587
279k
    for (int i = 0; i < len - 2; i += 3)
588
277k
    {
589
277k
        uchar t = data[i];
590
277k
        data[i] = data[i + 2];
591
277k
        data[i + 2] = t;
592
277k
    }
593
1.55k
}
594
595
static
596
#if (defined(_MSC_VER) && !defined(__clang__))
597
_forceinline
598
#else
599
inline
600
#endif
601
void libraw_swap32(uchar *data, int len)
602
0
{
603
0
    unsigned *d = (unsigned*)data;
604
0
    for (int i = 0; i < len / 4; i++)
605
0
    {
606
0
        unsigned x = d[i];
607
0
        d[i] = (x << 24) + ((x << 8) & 0x00FF0000) +
608
0
            ((x >> 8) & 0x0000FF00) + (x >> 24);
609
0
    }
610
0
}
611
612
613
void LibRaw::uncompressed_fp_dng_load_raw()
614
125
{
615
125
    int iifd = find_ifd_by_offset(libraw_internal_data.unpacker_data.data_offset);
616
125
    if (iifd < 0 || iifd > (int)libraw_internal_data.identify_data.tiff_nifds)
617
1
        throw LIBRAW_EXCEPTION_DECODE_RAW;
618
124
    struct tiff_ifd_t *ifd = &tiff_ifd[iifd];
619
620
124
    float *float_raw_image = 0;
621
622
124
    if (ifd->samples != 1 && ifd->samples != 3 && ifd->samples != 4)
623
1
        throw LIBRAW_EXCEPTION_DECODE_RAW; 
624
625
123
    if(imgdata.idata.filters && ifd->samples > 1)
626
1
      throw LIBRAW_EXCEPTION_DECODE_RAW;
627
628
122
    if ((int)libraw_internal_data.unpacker_data.tiff_samples != ifd->samples)
629
1
        throw LIBRAW_EXCEPTION_DECODE_RAW; // Wrong IFD
630
631
121
    int bytesps = (ifd->bps + 7) >> 3; // round to upper value
632
633
121
  if(bytesps < 1 || bytesps > 4)
634
1
      throw LIBRAW_EXCEPTION_DECODE_RAW;
635
636
120
    tile_stripe_data_t tiles;
637
120
    tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order,
638
120
        libraw_internal_data.internal_data.input);
639
640
  // Max bytes: 2^16 raw width * 2^2 bytes/pixel * 2^2 channels = 2^20, so check against 2^22
641
120
  INT64 rowbytes = INT64(MAX(tiles.tileWidth, imgdata.sizes.raw_width)) * INT64(MAX(bytesps,4)) * INT64(ifd->samples);
642
120
  if(rowbytes > (1LL << 22))
643
0
      throw LIBRAW_EXCEPTION_TOOBIG;
644
645
120
  INT64 allocsz = INT64(tiles.tileCnt) * INT64(tiles.tileWidth) * INT64(tiles.tileHeight) * INT64(ifd->samples) * INT64(sizeof(float));
646
120
  if (allocsz > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024))
647
3
    throw LIBRAW_EXCEPTION_TOOBIG;
648
649
117
    if (ifd->sample_format == 3)
650
116
        float_raw_image = (float *)calloc(allocsz,1);
651
1
    else
652
1
        throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float supported
653
654
116
    bool difford = (libraw_internal_data.unpacker_data.order == 0x4949) == (ntohs(0x1234) == 0x1234);
655
116
    float max = 0.f;
656
657
116
    std::vector<uchar> rowbuf(tiles.tileWidth *sizeof(float) * ifd->samples,0); // line buffer for last tile in tile row
658
659
24.4k
    for (size_t y = 0, t = 0; y < imgdata.sizes.raw_height; y += tiles.tileHeight)
660
24.3k
    {
661
48.7k
        for (unsigned x = 0; x < imgdata.sizes.raw_width  && t < (unsigned)tiles.tileCnt; x += tiles.tileWidth, ++t)
662
24.3k
        {
663
24.3k
            libraw_internal_data.internal_data.input->seek(tiles.tOffsets[t], SEEK_SET);
664
24.3k
            size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight;
665
24.3k
            size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth;
666
667
      // inrowbytes is less then 2^22 (see above) so conversion to int is safe
668
24.3k
            size_t inrowbytes = colsInTile * bytesps * ifd->samples;
669
24.3k
            int fullrowbytes = tiles.tileWidth *bytesps * ifd->samples;
670
24.3k
            size_t outrowbytes = colsInTile * sizeof(float) * ifd->samples;
671
672
147k
            for (size_t row = 0; row < rowsInTile; ++row) // do not process full tile if not needed
673
123k
            {
674
123k
                unsigned char *dst = fullrowbytes > int(inrowbytes) ? rowbuf.data(): // last tile in row, use buffer
675
123k
                    (unsigned char *)&float_raw_image
676
123k
                    [((y + row) * imgdata.sizes.raw_width + x) * ifd->samples];
677
123k
                int bytesread = libraw_internal_data.internal_data.input->read(dst, 1, fullrowbytes);
678
123k
        if (bytesread < fullrowbytes)
679
77
          derror();
680
123k
                if (bytesps == 2 && difford)
681
0
                    libraw_swab(dst, fullrowbytes);
682
123k
                else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit
683
1.55k
                    libraw_swap24(dst, fullrowbytes);
684
123k
                if (bytesps == 4 && difford)
685
0
                    libraw_swap32(dst, fullrowbytes);
686
687
123k
                float lmax = expandFloats(
688
123k
                    dst,
689
123k
                    tiles.tileWidth * ifd->samples,
690
123k
                    bytesps);
691
123k
                if (fullrowbytes > int(inrowbytes)) // last tile in row: copy buffer to destination
692
0
                    memmove(&float_raw_image[((y + row) * imgdata.sizes.raw_width + x) * ifd->samples], dst, outrowbytes);
693
123k
                max = MAX(max, lmax);
694
123k
            }
695
24.3k
        }
696
24.3k
    }
697
698
116
    imgdata.color.fmaximum = max;
699
700
    // setup outpuf fields
701
116
    imgdata.rawdata.raw_alloc = float_raw_image;
702
116
    if (ifd->samples == 1)
703
12
    {
704
12
        imgdata.rawdata.float_image = float_raw_image;
705
12
        imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
706
12
            imgdata.sizes.raw_width * 4;
707
12
    }
708
104
    else if (ifd->samples == 3)
709
26
    {
710
26
        imgdata.rawdata.float3_image = (float(*)[3])float_raw_image;
711
26
        imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
712
26
            imgdata.sizes.raw_width * 12;
713
26
    }
714
78
    else if (ifd->samples == 4)
715
1
    {
716
1
        imgdata.rawdata.float4_image = (float(*)[4])float_raw_image;
717
1
        imgdata.rawdata.sizes.raw_pitch = imgdata.sizes.raw_pitch =
718
1
            imgdata.sizes.raw_width * 16;
719
1
    }
720
721
116
    if (imgdata.rawparams.options & LIBRAW_RAWOPTIONS_CONVERTFLOAT_TO_INT)
722
39
        convertFloatToInt();  
723
116
}