Coverage Report

Created: 2025-11-16 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dng_sdk/source/dng_utils.h
Line
Count
Source
1
/*****************************************************************************/
2
// Copyright 2006-2012 Adobe Systems Incorporated
3
// All Rights Reserved.
4
//
5
// NOTICE:  Adobe permits you to use, modify, and distribute this file in
6
// accordance with the terms of the Adobe license agreement accompanying it.
7
/*****************************************************************************/
8
9
/* $Id: //mondo/dng_sdk_1_4/dng_sdk/source/dng_utils.h#3 $ */ 
10
/* $DateTime: 2012/06/14 20:24:41 $ */
11
/* $Change: 835078 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#ifndef __dng_utils__
17
#define __dng_utils__
18
19
/*****************************************************************************/
20
21
#include <cmath>
22
#include <limits>
23
24
#include "dng_classes.h"
25
#include "dng_flags.h"
26
#include "dng_memory.h"
27
#include "dng_safe_arithmetic.h"
28
#include "dng_types.h"
29
30
/*****************************************************************************/
31
32
// The unsigned integer overflow is intended here since a wrap around is used to
33
// calculate the abs() in the branchless version.
34
#if defined(__clang__) && defined(__has_attribute)
35
#if __has_attribute(no_sanitize)
36
__attribute__((no_sanitize("unsigned-integer-overflow")))
37
#endif
38
#endif
39
inline uint32 Abs_int32 (int32 x)
40
21.8M
  {
41
  
42
  #if 0
43
  
44
  // Reference version.
45
  
46
  return (uint32) (x < 0 ? -x : x);
47
  
48
  #else
49
  
50
  // Branchless version.
51
  
52
21.8M
    uint32 mask = (uint32) (x >> 31);
53
    
54
21.8M
    return (uint32) (((uint32) x + mask) ^ mask);
55
    
56
21.8M
  #endif
57
  
58
21.8M
  }
59
60
inline int32 Min_int32 (int32 x, int32 y)
61
1.25G
  {
62
  
63
1.25G
  return (x <= y ? x : y);
64
  
65
1.25G
  }
66
67
inline int32 Max_int32 (int32 x, int32 y)
68
1.25G
  {
69
  
70
1.25G
  return (x >= y ? x : y);
71
  
72
1.25G
  }
73
74
inline int32 Pin_int32 (int32 min, int32 x, int32 max)
75
1.22G
  {
76
  
77
1.22G
  return Max_int32 (min, Min_int32 (x, max));
78
  
79
1.22G
  }
80
81
inline int32 Pin_int32_between (int32 a, int32 x, int32 b)
82
0
  {
83
0
  
84
0
  int32 min, max;
85
0
  if (a < b) { min = a; max = b; }
86
0
  else { min = b; max = a; }
87
0
  
88
0
  return Pin_int32 (min, x, max);
89
0
  
90
0
  }
91
92
/*****************************************************************************/
93
94
inline uint16 Min_uint16 (uint16 x, uint16 y)
95
0
  {
96
0
  
97
0
  return (x <= y ? x : y);
98
0
  
99
0
  }
100
101
inline uint16 Max_uint16 (uint16 x, uint16 y)
102
0
  {
103
0
  
104
0
  return (x >= y ? x : y);
105
0
  
106
0
  }
107
108
inline int16 Pin_int16 (int32 x)
109
0
  {
110
0
  
111
0
  x = Pin_int32 (-32768, x, 32767);
112
0
  
113
0
  return (int16) x;
114
0
  
115
0
  }
116
  
117
/*****************************************************************************/
118
119
inline uint32 Min_uint32 (uint32 x, uint32 y)
120
309M
  {
121
  
122
309M
  return (x <= y ? x : y);
123
  
124
309M
  }
125
126
inline uint32 Min_uint32 (uint32 x, uint32 y, uint32 z)
127
0
  {
128
0
  
129
0
  return Min_uint32 (x, Min_uint32 (y, z));
130
0
  
131
0
  }
132
  
133
inline uint32 Max_uint32 (uint32 x, uint32 y)
134
592k
  {
135
  
136
592k
  return (x >= y ? x : y);
137
  
138
592k
  }
139
  
140
inline uint32 Max_uint32 (uint32 x, uint32 y, uint32 z)
141
0
  {
142
0
  
143
0
  return Max_uint32 (x, Max_uint32 (y, z));
144
0
  
145
0
  }
146
  
147
inline uint32 Pin_uint32 (uint32 min, uint32 x, uint32 max)
148
471k
  {
149
  
150
471k
  return Max_uint32 (min, Min_uint32 (x, max));
151
  
152
471k
  }
153
154
/*****************************************************************************/
155
156
inline uint16 Pin_uint16 (int32 x)
157
166M
  {
158
  
159
  #if 0
160
  
161
  // Reference version.
162
  
163
  x = Pin_int32 (0, x, 0x0FFFF);
164
  
165
  #else
166
  
167
  // Single branch version.
168
  
169
166M
  if (x & ~65535)
170
117M
    {
171
    
172
117M
    x = ~x >> 31;
173
    
174
117M
    }
175
    
176
166M
  #endif
177
    
178
166M
  return (uint16) x;
179
  
180
166M
  }
181
182
/*****************************************************************************/
183
184
inline uint32 RoundDown2 (uint32 x)
185
0
  {
186
0
  
187
0
  return x & (uint32) ~1;
188
0
  
189
0
  }
190
191
inline uint32 RoundDown4 (uint32 x)
192
0
  {
193
0
  
194
0
  return x & (uint32) ~3;
195
0
  
196
0
  }
197
198
inline uint32 RoundDown8 (uint32 x)
199
0
  {
200
0
  
201
0
  return x & (uint32) ~7;
202
0
  
203
0
  }
204
205
inline uint32 RoundDown16 (uint32 x)
206
0
  {
207
0
  
208
0
  return x & (uint32) ~15;
209
0
  
210
0
  }
211
212
/******************************************************************************/
213
214
inline bool RoundUpForPixelSize (uint32 x, uint32 pixelSize, uint32 *result)
215
1.69M
  {
216
  
217
1.69M
  uint32 multiple;
218
1.69M
  switch (pixelSize)
219
1.69M
    {
220
    
221
29.1k
    case 1:
222
485k
    case 2:
223
1.69M
    case 4:
224
1.69M
    case 8:
225
1.69M
      multiple = 16 / pixelSize;
226
1.69M
      break;
227
      
228
0
    default:
229
0
      multiple = 16;
230
0
      break;
231
    
232
1.69M
    }
233
  
234
1.69M
  return RoundUpUint32ToMultiple(x, multiple, result);
235
  
236
1.69M
  }
237
238
/******************************************************************************/
239
240
// Type of padding to be performed by ComputeBufferSize().
241
enum PaddingType
242
  {
243
  // Don't perform any padding.
244
  padNone,
245
  // Pad each scanline to an integer multiple of 16 bytes (in the same way
246
  // that RoundUpForPixelSize() does).
247
  pad16Bytes
248
  };
249
250
// Returns the number of bytes required for an image tile with the given pixel
251
// type, tile size, number of image planes, and desired padding. Throws a
252
// dng_exception with dng_error_memory error code if one of the components of
253
// tileSize is negative or if arithmetic overflow occurs during the computation.
254
uint32 ComputeBufferSize(uint32 pixelType, const dng_point &tileSize,
255
             uint32 numPlanes, PaddingType paddingType);
256
257
/******************************************************************************/
258
259
inline uint64 Abs_int64 (int64 x)
260
0
  {
261
0
  
262
0
  return (uint64) (x < 0 ? -x : x);
263
0
264
0
  }
265
266
inline int64 Min_int64 (int64 x, int64 y)
267
0
  {
268
0
  
269
0
  return (x <= y ? x : y);
270
0
  
271
0
  }
272
273
inline int64 Max_int64 (int64 x, int64 y)
274
0
  {
275
0
  
276
0
  return (x >= y ? x : y);
277
0
  
278
0
  }
279
280
inline int64 Pin_int64 (int64 min, int64 x, int64 max)
281
0
  {
282
0
  
283
0
  return Max_int64 (min, Min_int64 (x, max));
284
0
  
285
0
  }
286
287
/******************************************************************************/
288
289
inline uint64 Min_uint64 (uint64 x, uint64 y)
290
19.3M
  {
291
  
292
19.3M
  return (x <= y ? x : y);
293
  
294
19.3M
  }
295
296
inline uint64 Max_uint64 (uint64 x, uint64 y)
297
1.03G
  {
298
  
299
1.03G
  return (x >= y ? x : y);
300
  
301
1.03G
  }
302
303
inline uint64 Pin_uint64 (uint64 min, uint64 x, uint64 max)
304
0
  {
305
0
  
306
0
  return Max_uint64 (min, Min_uint64 (x, max));
307
0
  
308
0
  }
309
310
/*****************************************************************************/
311
312
inline real32 Abs_real32 (real32 x)
313
0
  {
314
  
315
0
  return (x < 0.0f ? -x : x);
316
  
317
0
  }
318
319
inline real32 Min_real32 (real32 x, real32 y)
320
5.48G
  {
321
  
322
5.48G
  return (x < y ? x : y);
323
  
324
5.48G
  }
325
326
inline real32 Max_real32 (real32 x, real32 y)
327
5.25G
  {
328
  
329
5.25G
  return (x > y ? x : y);
330
  
331
5.25G
  }
332
333
inline real32 Pin_real32 (real32 min, real32 x, real32 max)
334
5.25G
  {
335
  
336
5.25G
  return Max_real32 (min, Min_real32 (x, max));
337
  
338
5.25G
  }
339
  
340
inline real32 Pin_real32 (real32 x)
341
0
  {
342
343
0
  return Pin_real32 (0.0f, x, 1.0f);
344
345
0
  }
346
347
inline real32 Pin_real32_Overrange (real32 min, 
348
                  real32 x, 
349
                  real32 max)
350
0
  {
351
0
  
352
0
  // Normal numbers in (min,max). No change.
353
0
  
354
0
  if (x > min && x < max)
355
0
    {
356
0
    return x;
357
0
    }
358
0
    
359
0
  // Map large numbers (including positive infinity) to max.
360
0
    
361
0
  else if (x > min)
362
0
    {
363
0
    return max;
364
0
    }
365
0
    
366
0
  // Map everything else (including negative infinity and all NaNs) to min.
367
0
    
368
0
  return min;
369
0
  
370
0
  }
371
372
inline real32 Pin_Overrange (real32 x)
373
3.13G
  {
374
  
375
  // Normal in-range numbers, except for plus and minus zero.
376
  
377
3.13G
  if (x > 0.0f && x <= 1.0f)
378
2.04G
    {
379
2.04G
    return x;
380
2.04G
    }
381
    
382
  // Large numbers, including positive infinity.
383
    
384
1.09G
  else if (x > 0.5f)
385
1.59k
    {
386
1.59k
    return 1.0f;
387
1.59k
    }
388
    
389
  // Plus and minus zero, negative numbers, negative infinity, and all NaNs.
390
    
391
1.09G
  return 0.0f;
392
  
393
3.13G
  }
394
395
inline real32 Lerp_real32 (real32 a, real32 b, real32 t)
396
0
  {
397
0
  
398
0
  return a + t * (b - a);
399
0
  
400
0
  }
401
402
/*****************************************************************************/
403
404
inline real64 Abs_real64 (real64 x)
405
4.99G
  {
406
  
407
4.99G
  return (x < 0.0 ? -x : x);
408
  
409
4.99G
  }
410
411
inline real64 Min_real64 (real64 x, real64 y)
412
1.11G
  {
413
  
414
1.11G
  return (x < y ? x : y);
415
  
416
1.11G
  }
417
418
inline real64 Max_real64 (real64 x, real64 y)
419
2.11G
  {
420
  
421
2.11G
  return (x > y ? x : y);
422
  
423
2.11G
  }
424
425
inline real64 Pin_real64 (real64 min, real64 x, real64 max)
426
1.08G
  {
427
  
428
1.08G
  return Max_real64 (min, Min_real64 (x, max));
429
  
430
1.08G
  }
431
432
inline real64 Pin_real64 (real64 x)
433
0
  {
434
0
  
435
0
  return Pin_real64 (0.0, x, 1.0);
436
0
  
437
0
  }
438
439
inline real64 Pin_real64_Overrange (real64 min, 
440
                  real64 x, 
441
                  real64 max)
442
0
  {
443
0
  
444
0
  // Normal numbers in (min,max). No change.
445
0
  
446
0
  if (x > min && x < max)
447
0
    {
448
0
    return x;
449
0
    }
450
0
    
451
0
  // Map large numbers (including positive infinity) to max.
452
0
    
453
0
  else if (x > min)
454
0
    {
455
0
    return max;
456
0
    }
457
0
    
458
0
  // Map everything else (including negative infinity and all NaNs) to min.
459
0
    
460
0
  return min;
461
0
  
462
0
  }
463
464
inline real64 Lerp_real64 (real64 a, real64 b, real64 t)
465
0
  {
466
  
467
0
  return a + t * (b - a);
468
  
469
0
  }
470
471
/*****************************************************************************/
472
473
inline int32 Round_int32 (real32 x)
474
0
  {
475
0
  
476
0
  return (int32) (x > 0.0f ? x + 0.5f : x - 0.5f);
477
0
  
478
0
  }
479
480
inline int32 Round_int32 (real64 x)
481
5.26G
  {
482
  
483
5.26G
  const real64 temp = x > 0.0 ? x + 0.5 : x - 0.5;
484
  
485
  // NaNs will fail this test (because NaNs compare false against
486
  // everything) and will therefore also take the else branch.
487
5.26G
  if (temp > real64(std::numeric_limits<int32>::min()) - 1.0 &&
488
5.26G
      temp < real64(std::numeric_limits<int32>::max()) + 1.0)
489
5.26G
    {
490
5.26G
    return (int32) temp;
491
5.26G
    }
492
  
493
5.66k
  else
494
5.66k
    {
495
5.66k
    ThrowProgramError("Overflow in Round_int32");
496
    // Dummy return.
497
5.66k
    return 0;
498
5.66k
    }
499
  
500
5.26G
  }
501
502
inline uint32 Floor_uint32 (real32 x)
503
0
  {
504
  
505
0
  return (uint32) Max_real32 (0.0f, x);
506
  
507
0
  }
508
509
inline uint32 Floor_uint32 (real64 x)
510
1.02G
  {
511
  
512
1.02G
  const real64 temp = Max_real64 (0.0, x);
513
  
514
  // NaNs will fail this test (because NaNs compare false against
515
  // everything) and will therefore also take the else branch.
516
1.02G
  if (temp < real64(std::numeric_limits<uint32>::max()) + 1.0)
517
1.02G
    {
518
1.02G
    return (uint32) temp;
519
1.02G
    }
520
  
521
299
  else
522
299
    {
523
299
    ThrowProgramError("Overflow in Floor_uint32");
524
    // Dummy return.
525
299
    return 0;
526
299
    }
527
  
528
1.02G
  }
529
530
inline uint32 Round_uint32 (real32 x)
531
0
  {
532
  
533
0
  return Floor_uint32 (x + 0.5f);
534
  
535
0
  }
536
537
inline uint32 Round_uint32 (real64 x)
538
1.02G
  {
539
  
540
1.02G
  return Floor_uint32 (x + 0.5);
541
  
542
1.02G
  }
543
544
/******************************************************************************/
545
546
inline int64 Round_int64 (real64 x)
547
0
  {
548
  
549
0
  return (int64) (x >= 0.0 ? x + 0.5 : x - 0.5);
550
  
551
0
  }
552
553
/*****************************************************************************/
554
555
const int64 kFixed64_One  = (((int64) 1) << 32);
556
const int64 kFixed64_Half = (((int64) 1) << 31);
557
558
/******************************************************************************/
559
560
inline int64 Real64ToFixed64 (real64 x)
561
0
  {
562
  
563
0
  return Round_int64 (x * (real64) kFixed64_One);
564
  
565
0
  }
566
567
/******************************************************************************/
568
569
inline real64 Fixed64ToReal64 (int64 x)
570
0
  {
571
0
  
572
0
  return x * (1.0 / (real64) kFixed64_One);
573
0
  
574
0
  }
575
576
/*****************************************************************************/
577
578
inline char ForceUppercase (char c)
579
254k
  {
580
  
581
254k
  if (c >= 'a' && c <= 'z')
582
60.1k
    {
583
    
584
60.1k
    c -= 'a' - 'A';
585
    
586
60.1k
    }
587
    
588
254k
  return c;
589
  
590
254k
  }
591
592
/*****************************************************************************/
593
594
inline uint16 SwapBytes16 (uint16 x)
595
58.2M
  {
596
  
597
58.2M
  return (uint16) ((x << 8) |
598
58.2M
           (x >> 8));
599
  
600
58.2M
  }
601
602
inline uint32 SwapBytes32 (uint32 x)
603
54.4M
  {
604
  
605
54.4M
  return (x << 24) +
606
54.4M
       ((x << 8) & 0x00FF0000) +
607
54.4M
       ((x >> 8) & 0x0000FF00) +
608
54.4M
       (x >> 24);
609
  
610
54.4M
  }
611
612
/*****************************************************************************/
613
614
inline bool IsAligned16 (const void *p)
615
0
  {
616
0
  
617
0
  return (((uintptr) p) & 1) == 0;
618
0
  
619
0
  }
620
621
inline bool IsAligned32 (const void *p)
622
0
  {
623
  
624
0
  return (((uintptr) p) & 3) == 0;
625
  
626
0
  }
627
628
inline bool IsAligned64 (const void *p)
629
0
  {
630
0
  
631
0
  return (((uintptr) p) & 7) == 0;
632
0
  
633
0
  }
634
635
inline bool IsAligned128 (const void *p)
636
0
  {
637
0
  
638
0
  return (((uintptr) p) & 15) == 0;
639
0
  
640
0
  }
641
642
/******************************************************************************/
643
644
// Converts from RGB values (range 0.0 to 1.0) to HSV values (range 0.0 to
645
// 6.0 for hue, and 0.0 to 1.0 for saturation and value).
646
647
inline void DNG_RGBtoHSV (real32 r,
648
                real32 g,
649
                real32 b,
650
                real32 &h,
651
                real32 &s,
652
                real32 &v)
653
0
  {
654
  
655
0
  v = Max_real32 (r, Max_real32 (g, b));
656
657
0
  real32 gap = v - Min_real32 (r, Min_real32 (g, b));
658
  
659
0
  if (gap > 0.0f)
660
0
    {
661
662
0
    if (r == v)
663
0
      {
664
      
665
0
      h = (g - b) / gap;
666
      
667
0
      if (h < 0.0f)
668
0
        {
669
0
        h += 6.0f;
670
0
        }
671
        
672
0
      }
673
      
674
0
    else if (g == v) 
675
0
      {
676
0
      h = 2.0f + (b - r) / gap;
677
0
      }
678
      
679
0
    else
680
0
      {
681
0
      h = 4.0f + (r - g) / gap;
682
0
      }
683
      
684
0
    s = gap / v;
685
    
686
0
    }
687
    
688
0
  else
689
0
    {
690
0
    h = 0.0f;
691
0
    s = 0.0f;
692
0
    }
693
  
694
0
  }
695
696
/*****************************************************************************/
697
698
// Converts from HSV values (range 0.0 to 6.0 for hue, and 0.0 to 1.0 for
699
// saturation and value) to RGB values (range 0.0 to 1.0).
700
701
inline void DNG_HSVtoRGB (real32 h,
702
              real32 s,
703
              real32 v,
704
              real32 &r,
705
              real32 &g,
706
              real32 &b)
707
0
  {
708
  
709
0
  if (s > 0.0f)
710
0
    {
711
    
712
0
    if (!std::isfinite(h))
713
0
      ThrowProgramError("Unexpected NaN or Inf");
714
0
    h = std::fmod(h, 6.0f);
715
0
    if (h < 0.0f)
716
0
      h += 6.0f;
717
      
718
0
    int32  i = (int32) h;
719
0
    real32 f = h - (real32) i;
720
    
721
0
    real32 p = v * (1.0f - s);
722
    
723
0
    #define q (v * (1.0f - s * f))
724
0
    #define t (v * (1.0f - s * (1.0f - f)))
725
    
726
0
    switch (i)
727
0
      {
728
0
      case 0: r = v; g = t; b = p; break;
729
0
      case 1: r = q; g = v; b = p; break;
730
0
      case 2: r = p; g = v; b = t; break;
731
0
      case 3: r = p; g = q; b = v; break;
732
0
      case 4: r = t; g = p; b = v; break;
733
0
      case 5: r = v; g = p; b = q; break;
734
0
      }
735
      
736
0
    #undef q
737
0
    #undef t
738
    
739
0
    }
740
    
741
0
  else
742
0
    {
743
0
    r = v;
744
0
    g = v;
745
0
    b = v;
746
0
    }
747
  
748
0
  }
749
750
/******************************************************************************/
751
752
// High resolution timer, for code profiling.
753
754
real64 TickTimeInSeconds ();
755
756
// Lower resolution timer, but more stable.
757
758
real64 TickCountInSeconds ();
759
760
/******************************************************************************/
761
762
class dng_timer
763
  {
764
765
  public:
766
767
    dng_timer (const char *message);
768
769
    ~dng_timer ();
770
    
771
  private:
772
  
773
    // Hidden copy constructor and assignment operator.
774
  
775
    dng_timer (const dng_timer &timer);
776
    
777
    dng_timer & operator= (const dng_timer &timer);
778
779
  private:
780
781
    const char *fMessage;
782
    
783
    real64 fStartTime;
784
    
785
  };
786
787
/*****************************************************************************/
788
789
// Returns the maximum squared Euclidean distance from the specified point to the
790
// specified rectangle rect.
791
792
real64 MaxSquaredDistancePointToRect (const dng_point_real64 &point,
793
                    const dng_rect_real64 &rect);
794
795
/*****************************************************************************/
796
797
// Returns the maximum Euclidean distance from the specified point to the specified
798
// rectangle rect.
799
800
real64 MaxDistancePointToRect (const dng_point_real64 &point,
801
                 const dng_rect_real64 &rect);
802
803
/*****************************************************************************/
804
805
inline uint32 DNG_HalfToFloat (uint16 halfValue)
806
269M
  {
807
808
269M
  int32 sign     = (halfValue >> 15) & 0x00000001;
809
269M
  int32 exponent = (halfValue >> 10) & 0x0000001f;
810
269M
  int32 mantissa =  halfValue      & 0x000003ff;
811
    
812
269M
  if (exponent == 0)
813
187M
    {
814
    
815
187M
    if (mantissa == 0)
816
186M
      {
817
      
818
      // Plus or minus zero
819
820
186M
      return (uint32) (sign << 31);
821
      
822
186M
      }
823
      
824
903k
    else
825
903k
      {
826
      
827
      // Denormalized number -- renormalize it
828
829
5.05M
      while (!(mantissa & 0x00000400))
830
4.14M
        {
831
4.14M
        mantissa <<= 1;
832
4.14M
        exponent -=  1;
833
4.14M
        }
834
835
903k
      exponent += 1;
836
903k
      mantissa &= ~0x00000400;
837
      
838
903k
      }
839
      
840
187M
    }
841
    
842
81.1M
  else if (exponent == 31)
843
7.68M
    {
844
    
845
7.68M
    if (mantissa == 0)
846
6.86M
      {
847
      
848
      // Positive or negative infinity, convert to maximum (16 bit) values.
849
      
850
6.86M
      return (uint32) ((sign << 31) | ((0x1eL + 127 - 15) << 23) |  (0x3ffL << 13));
851
852
6.86M
      }
853
      
854
815k
    else
855
815k
      {
856
      
857
      // Nan -- Just set to zero.
858
859
815k
      return 0;
860
      
861
815k
      }
862
      
863
7.68M
    }
864
865
  // Normalized number
866
867
74.4M
  exponent += (127 - 15);
868
74.4M
  mantissa <<= 13;
869
870
  // Assemble sign, exponent and mantissa.
871
872
74.4M
  return (uint32) ((sign << 31) | (exponent << 23) | mantissa);
873
  
874
269M
  }
875
876
/*****************************************************************************/
877
878
inline uint16 DNG_FloatToHalf (uint32 i)
879
415M
  {
880
  
881
415M
  int32 sign     =  (i >> 16) & 0x00008000;
882
415M
  int32 exponent = ((i >> 23) & 0x000000ff) - (127 - 15);
883
415M
  int32 mantissa =   i    & 0x007fffff;
884
885
415M
  if (exponent <= 0)
886
299M
    {
887
    
888
299M
    if (exponent < -10)
889
298M
      {
890
      
891
      // Zero or underflow to zero.
892
      
893
298M
      return (uint16)sign;
894
      
895
298M
      }
896
897
    // E is between -10 and 0.  We convert f to a denormalized half.
898
899
1.26M
    mantissa = (mantissa | 0x00800000) >> (1 - exponent);
900
901
    // Round to nearest, round "0.5" up.
902
    //
903
    // Rounding may cause the significand to overflow and make
904
    // our number normalized.  Because of the way a half's bits
905
    // are laid out, we don't have to treat this case separately;
906
    // the code below will handle it correctly.
907
908
1.26M
    if (mantissa &  0x00001000)
909
542k
      mantissa += 0x00002000;
910
911
    // Assemble the half from sign, exponent (zero) and mantissa.
912
913
1.26M
    return (uint16)(sign | (mantissa >> 13));
914
    
915
299M
    }
916
  
917
115M
  else if (exponent == 0xff - (127 - 15))
918
495k
    {
919
    
920
495k
    if (mantissa == 0)
921
92.5k
      {
922
      
923
      // F is an infinity; convert f to a half
924
      // infinity with the same sign as f.
925
926
92.5k
      return (uint16)(sign | 0x7c00);
927
      
928
92.5k
      }
929
      
930
402k
    else
931
402k
      {
932
      
933
      // F is a NAN; produce a half NAN that preserves
934
      // the sign bit and the 10 leftmost bits of the
935
      // significand of f.
936
937
402k
      return (uint16)(sign | 0x7c00 | (mantissa >> 13));
938
      
939
402k
      }
940
  
941
495k
    }
942
943
  // E is greater than zero.  F is a normalized float.
944
  // We try to convert f to a normalized half.
945
946
  // Round to nearest, round "0.5" up
947
948
115M
  if (mantissa & 0x00001000)
949
33.8M
    {
950
    
951
33.8M
    mantissa += 0x00002000;
952
953
33.8M
    if (mantissa & 0x00800000)
954
3.82M
      {
955
3.82M
      mantissa =  0;    // overflow in significand,
956
3.82M
      exponent += 1;    // adjust exponent
957
3.82M
      }
958
959
33.8M
    }
960
961
  // Handle exponent overflow
962
963
115M
  if (exponent > 30)
964
7.18M
    {
965
7.18M
    return (uint16)(sign | 0x7c00); // infinity with the same sign as f.
966
7.18M
    }
967
968
  // Assemble the half from sign, exponent and mantissa.
969
970
108M
  return (uint16)(sign | (exponent << 10) | (mantissa >> 13));
971
    
972
115M
  }
973
974
/*****************************************************************************/
975
976
inline uint32 DNG_FP24ToFloat (const uint8 *input)
977
8.89M
  {
978
979
8.89M
  int32 sign     = (input [0] >> 7) & 0x01;
980
8.89M
  int32 exponent = (input [0]     ) & 0x7F;
981
8.89M
  int32 mantissa = (((int32) input [1]) << 8) | input[2];
982
    
983
8.89M
  if (exponent == 0)
984
3.04M
    {
985
    
986
3.04M
    if (mantissa == 0)
987
2.12M
      {
988
      
989
      // Plus or minus zero
990
      
991
2.12M
      return (uint32) (sign << 31);
992
      
993
2.12M
      }
994
995
919k
    else
996
919k
      {
997
      
998
      // Denormalized number -- renormalize it
999
1000
7.96M
      while (!(mantissa & 0x00010000))
1001
7.04M
        {
1002
7.04M
        mantissa <<= 1;
1003
7.04M
        exponent -=  1;
1004
7.04M
        }
1005
1006
919k
      exponent += 1;
1007
919k
      mantissa &= ~0x00010000;
1008
      
1009
919k
      }
1010
  
1011
3.04M
    }
1012
    
1013
5.85M
  else if (exponent == 127)
1014
459k
    {
1015
    
1016
459k
    if (mantissa == 0)
1017
14.4k
      {
1018
      
1019
      // Positive or negative infinity, convert to maximum (24 bit) values.
1020
  
1021
14.4k
      return (uint32) ((sign << 31) | ((0x7eL + 128 - 64) << 23) |  (0xffffL << 7));
1022
      
1023
14.4k
      }
1024
      
1025
444k
    else
1026
444k
      {
1027
      
1028
      // Nan -- Just set to zero.
1029
1030
444k
      return 0;
1031
      
1032
444k
      }
1033
      
1034
459k
    }
1035
  
1036
  // Normalized number
1037
1038
6.31M
  exponent += (128 - 64);
1039
6.31M
  mantissa <<= 7;
1040
1041
  // Assemble sign, exponent and mantissa.
1042
1043
6.31M
  return (uint32) ((sign << 31) | (exponent << 23) | mantissa);
1044
  
1045
8.89M
  }
1046
1047
/*****************************************************************************/
1048
1049
inline void DNG_FloatToFP24 (uint32 input, uint8 *output)
1050
4.73M
  {
1051
  
1052
4.73M
  int32 exponent = (int32) ((input >> 23) & 0xFF) - 128;
1053
4.73M
  int32 mantissa = input & 0x007FFFFF;
1054
1055
4.73M
  if (exponent == 127)  // infinity or NaN
1056
24.7k
    {
1057
    
1058
    // Will the NaN alais to infinity? 
1059
    
1060
24.7k
    if (mantissa != 0x007FFFFF && ((mantissa >> 7) == 0xFFFF))
1061
286
      {
1062
      
1063
286
      mantissa &= 0x003FFFFF;   // knock out msb to make it a NaN
1064
      
1065
286
      }
1066
      
1067
24.7k
    }
1068
    
1069
4.71M
  else if (exponent > 63)    // overflow, map to infinity
1070
110k
    {
1071
    
1072
110k
    exponent = 63;
1073
110k
    mantissa = 0x007FFFFF;
1074
    
1075
110k
    }
1076
    
1077
4.60M
  else if (exponent <= -64) 
1078
3.20M
    {
1079
    
1080
3.20M
    if (exponent >= -79)    // encode as denorm
1081
49.0k
      {
1082
49.0k
      mantissa = (mantissa | 0x00800000) >> (-63 - exponent);
1083
49.0k
      }
1084
      
1085
3.15M
    else            // underflow to zero
1086
3.15M
      {
1087
3.15M
      mantissa = 0;
1088
3.15M
      }
1089
1090
3.20M
    exponent = -64;
1091
    
1092
3.20M
    }
1093
1094
4.73M
  output [0] = (uint8)(((input >> 24) & 0x80) | (uint32) (exponent + 64));
1095
  
1096
4.73M
  output [1] = (mantissa >> 15) & 0x00FF;
1097
4.73M
  output [2] = (mantissa >>  7) & 0x00FF;
1098
  
1099
4.73M
  }
1100
1101
/******************************************************************************/
1102
1103
// The following code was from PSDivide.h in Photoshop.
1104
1105
// High order 32-bits of an unsigned 32 by 32 multiply.
1106
1107
#ifndef MULUH
1108
1109
#if defined(_X86_) && defined(_MSC_VER)
1110
1111
inline uint32 Muluh86 (uint32 x, uint32 y)
1112
  {
1113
  uint32 result;
1114
  __asm
1115
    {
1116
    MOV   EAX, x
1117
    MUL   y
1118
    MOV   result, EDX
1119
    }
1120
  return (result);
1121
  }
1122
1123
#define MULUH Muluh86
1124
1125
#else
1126
1127
49.1k
#define MULUH(x,y)  ((uint32) (((x) * (uint64) (y)) >> 32))
1128
1129
#endif
1130
1131
#endif
1132
1133
// High order 32-bits of an signed 32 by 32 multiply.
1134
1135
#ifndef MULSH
1136
1137
#if defined(_X86_) && defined(_MSC_VER)
1138
1139
inline int32 Mulsh86 (int32 x, int32 y)
1140
  {
1141
  int32 result;
1142
  __asm
1143
    {
1144
    MOV   EAX, x
1145
    IMUL  y
1146
    MOV   result, EDX
1147
    }
1148
  return (result);
1149
  }
1150
1151
#define MULSH Mulsh86
1152
1153
#else
1154
1155
#define MULSH(x,y)  ((int32) (((x) * (int64) (y)) >> 32))
1156
1157
#endif
1158
1159
#endif
1160
1161
/******************************************************************************/
1162
1163
// Random number generator (identical to Apple's) for portable use.
1164
1165
// This implements the "minimal standard random number generator"
1166
// as proposed by Park and Miller in CACM October, 1988.
1167
// It has a period of 2147483647 (0x7fffffff)
1168
1169
// This is the ACM standard 30 bit generator:
1170
// x' = (x * 16807) mod 2^31-1
1171
// This function intentionally exploits the defined behavior of unsigned integer
1172
// overflow.
1173
#if defined(__clang__) && defined(__has_attribute)
1174
#if __has_attribute(no_sanitize)
1175
__attribute__((no_sanitize("unsigned-integer-overflow")))
1176
#endif
1177
#endif
1178
inline uint32 DNG_Random (uint32 seed)
1179
49.1k
  {
1180
  
1181
  // high = seed / 127773
1182
  
1183
49.1k
  uint32 temp = MULUH (0x069C16BD, seed);
1184
49.1k
  uint32 high = (temp + ((seed - temp) >> 1)) >> 16;
1185
  
1186
  // low = seed % 127773
1187
  
1188
49.1k
  uint32 low = seed - high * 127773;
1189
  
1190
  // seed = (seed * 16807) % 2147483647
1191
  
1192
49.1k
  seed = 16807 * low - 2836 * high;
1193
  
1194
49.1k
  if (seed & 0x80000000)
1195
579
    seed += 2147483647;
1196
    
1197
49.1k
  return seed;
1198
  
1199
49.1k
  }
1200
1201
/*****************************************************************************/
1202
1203
class dng_dither
1204
  {
1205
    
1206
  public:
1207
1208
    static const uint32 kRNGBits = 7;
1209
1210
    static const uint32 kRNGSize = 1 << kRNGBits;
1211
1212
    static const uint32 kRNGMask = kRNGSize - 1;
1213
1214
    static const uint32 kRNGSize2D = kRNGSize * kRNGSize;
1215
1216
  private:
1217
1218
    dng_memory_data fNoiseBuffer;
1219
1220
  private:
1221
1222
    dng_dither ();
1223
1224
    // Hidden copy constructor and assignment operator.
1225
  
1226
    dng_dither (const dng_dither &);
1227
    
1228
    dng_dither & operator= (const dng_dither &);
1229
    
1230
  public:
1231
1232
    static const dng_dither & Get ();
1233
1234
  public:
1235
1236
    const uint16 *NoiseBuffer16 () const
1237
32.1k
      {
1238
32.1k
      return fNoiseBuffer.Buffer_uint16 ();
1239
32.1k
      }
1240
    
1241
  };
1242
1243
/*****************************************************************************/
1244
1245
void HistogramArea (dng_host &host,
1246
          const dng_image &image,
1247
          const dng_rect &area,
1248
          uint32 *hist,
1249
          uint32 histLimit,
1250
          uint32 plane = 0);
1251
1252
/*****************************************************************************/
1253
1254
void LimitFloatBitDepth (dng_host &host,
1255
             const dng_image &srcImage,
1256
             dng_image &dstImage,
1257
             uint32 bitDepth,
1258
             real32 scale = 1.0f);
1259
1260
/*****************************************************************************/
1261
1262
#if qMacOS
1263
1264
/*****************************************************************************/
1265
1266
template<typename T>
1267
class CFReleaseHelper
1268
  {
1269
1270
  private:
1271
1272
    T fRef;
1273
1274
  public:
1275
1276
    CFReleaseHelper (T ref)
1277
      : fRef (ref)
1278
      {
1279
      }
1280
1281
    ~CFReleaseHelper ()
1282
      {
1283
      if (fRef)
1284
        {
1285
        CFRelease (fRef);
1286
        }
1287
      }
1288
1289
    T Get () const
1290
      {
1291
      return fRef;
1292
      }
1293
1294
  };
1295
1296
/*****************************************************************************/
1297
1298
#endif  // qMacOS
1299
1300
/*****************************************************************************/
1301
1302
#endif
1303
  
1304
/*****************************************************************************/