Coverage Report

Created: 2025-11-11 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dng_sdk/source/dng_fingerprint.cpp
Line
Count
Source
1
/*****************************************************************************/
2
// Copyright 2006-2007 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_fingerprint.cpp#3 $ */ 
10
/* $DateTime: 2012/07/11 10:36:56 $ */
11
/* $Change: 838485 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#include "dng_fingerprint.h"
17
18
#include "dng_assertions.h"
19
#include "dng_flags.h"
20
21
/*****************************************************************************/
22
23
dng_fingerprint::dng_fingerprint ()
24
2.46M
  {
25
  
26
41.9M
  for (uint32 j = 0; j < 16; j++)
27
39.5M
    {
28
    
29
39.5M
    data [j] = 0;
30
    
31
39.5M
    }
32
    
33
2.46M
  }
34
35
/*****************************************************************************/
36
37
bool dng_fingerprint::IsNull () const
38
352k
  {
39
  
40
5.38M
  for (uint32 j = 0; j < 16; j++)
41
5.06M
    {
42
    
43
5.06M
    if (data [j] != 0)
44
39.1k
      {
45
      
46
39.1k
      return false;
47
      
48
39.1k
      }
49
      
50
5.06M
    }
51
    
52
313k
  return true;
53
  
54
352k
  }
55
56
/*****************************************************************************/
57
58
bool dng_fingerprint::operator== (const dng_fingerprint &print) const
59
8.15k
  {
60
  
61
8.56k
  for (uint32 j = 0; j < 16; j++)
62
8.56k
    {
63
    
64
8.56k
    if (data [j] != print.data [j])
65
8.14k
      {
66
      
67
8.14k
      return false;
68
      
69
8.14k
      }
70
      
71
8.56k
    }
72
    
73
2
  return true;
74
  
75
8.15k
  }
76
    
77
/******************************************************************************/
78
79
uint32 dng_fingerprint::Collapse32 () const
80
0
  {
81
  
82
0
  uint32 x = 0;
83
  
84
0
  for (uint32 j = 0; j < 4; j++)
85
0
    {
86
    
87
0
    uint32 y = 0;
88
    
89
0
    for (uint32 k = 0; k < 4; k++)
90
0
      {
91
      
92
0
      y = (y << 8) + (uint32) data [j * 4 + k];
93
      
94
0
      }
95
      
96
0
    x = x ^ y;
97
    
98
0
    }
99
    
100
0
  return x;
101
  
102
0
  }
103
104
/******************************************************************************/
105
106
static char NumToHexChar (unsigned int c)
107
0
  {
108
109
0
  if (c < 10)
110
0
    {
111
0
    return (char) ('0' + c);
112
0
    }
113
114
0
  else
115
0
    {
116
0
    return (char) ('A' + c - 10);
117
0
    }
118
119
0
  }
120
121
/*****************************************************************************/
122
123
void dng_fingerprint::ToUtf8HexString (char resultStr [2 * kDNGFingerprintSize + 1]) const
124
0
  {
125
  
126
0
  for (size_t i = 0; i < kDNGFingerprintSize; i++)
127
0
    {
128
    
129
0
    unsigned char c = data [i];
130
131
0
    resultStr [i * 2] = NumToHexChar (c >> 4);
132
0
    resultStr [i * 2 + 1] = NumToHexChar (c & 15);
133
    
134
0
    }
135
  
136
0
  resultStr [kDNGFingerprintSize * 2] = '\0';
137
138
0
  }
139
140
/******************************************************************************/
141
142
static int HexCharToNum (char hexChar)
143
62.4k
  {
144
  
145
62.4k
  if (hexChar >= '0' && hexChar <= '9')
146
0
    {
147
0
    return hexChar - '0';
148
0
    }
149
150
62.4k
  else if (hexChar >= 'A' && hexChar <= 'F')
151
0
    {
152
0
    return hexChar - 'A' + 10;
153
0
    }
154
155
62.4k
  else if (hexChar >= 'a' && hexChar <= 'f')
156
62.4k
    {
157
62.4k
    return hexChar - 'a' + 10;
158
62.4k
    }
159
  
160
0
  return -1;
161
  
162
62.4k
  }
163
164
/*****************************************************************************/
165
166
bool dng_fingerprint::FromUtf8HexString (const char inputStr [2 * kDNGFingerprintSize + 1])
167
1.95k
  {
168
  
169
33.1k
  for (size_t i = 0; i < kDNGFingerprintSize; i++)
170
31.2k
    {
171
    
172
31.2k
    int highNibble = HexCharToNum (inputStr [i * 2]);
173
174
31.2k
    if (highNibble < 0)
175
0
      {
176
0
      return false;
177
0
      }
178
    
179
31.2k
    int lowNibble = HexCharToNum (inputStr [i * 2 + 1]);
180
181
31.2k
    if (lowNibble < 0)
182
0
      {
183
0
      return false;
184
0
      }
185
186
31.2k
    data [i] = (uint8) ((highNibble << 4) + lowNibble);
187
    
188
31.2k
    }
189
  
190
1.95k
  return true;
191
192
1.95k
  }
193
194
/******************************************************************************/
195
196
// Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
197
198
// Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
199
// rights reserved.
200
// 
201
// License to copy and use this software is granted provided that it
202
// is identified as the "RSA Data Security, Inc. MD5 Message-Digest
203
// Algorithm" in all material mentioning or referencing this software
204
// or this function.
205
// 
206
// License is also granted to make and use derivative works provided
207
// that such works are identified as "derived from the RSA Data
208
// Security, Inc. MD5 Message-Digest Algorithm" in all material
209
// mentioning or referencing the derived work.
210
// 
211
// RSA Data Security, Inc. makes no representations concerning either
212
// the merchantability of this software or the suitability of this
213
// software for any particular purpose. It is provided "as is"
214
// without express or implied warranty of any kind.
215
// 
216
// These notices must be retained in any copies of any part of this
217
// documentation and/or software.
218
219
/******************************************************************************/
220
221
dng_md5_printer::dng_md5_printer ()
222
223
191k
  : final  (false)
224
191k
  , result ()
225
  
226
191k
  {
227
  
228
191k
  Reset ();
229
  
230
191k
  }
231
                
232
/******************************************************************************/
233
234
void dng_md5_printer::Reset ()
235
191k
  {
236
  
237
  // No bits processed yet.
238
  
239
191k
  count [0] = 0;
240
191k
  count [1] = 0;
241
242
  // Load magic initialization constants.
243
244
191k
  state [0] = 0x67452301;
245
191k
  state [1] = 0xefcdab89;
246
191k
  state [2] = 0x98badcfe;
247
191k
  state [3] = 0x10325476;
248
249
  // Not finalized yet.
250
  
251
191k
  final = false;
252
  
253
191k
  }
254
255
/******************************************************************************/
256
257
void dng_md5_printer::Process (const void *data,
258
                   uint32 inputLen)
259
1.24M
  {
260
  
261
1.24M
  DNG_ASSERT (!final, "Fingerprint already finalized!");
262
  
263
1.24M
  const uint8 *input = (const uint8 *) data;
264
  
265
  // Compute number of bytes mod 64
266
  
267
1.24M
  uint32 index = (count [0] >> 3) & 0x3F;
268
269
  // Update number of bits
270
  
271
1.24M
  if ((count [0] += inputLen << 3) < (inputLen << 3))
272
2
    {
273
2
    count [1]++;
274
2
    }
275
    
276
1.24M
  count [1] += inputLen >> 29;
277
278
  // Transform as many times as possible.
279
  
280
1.24M
  uint32 i = 0;
281
282
1.24M
  uint32 partLen = 64 - index;
283
284
1.24M
  if (inputLen >= partLen)
285
890k
    {
286
    
287
890k
    memcpy (&buffer [index],
288
890k
        input,
289
890k
        partLen);
290
        
291
890k
    MD5Transform (state, buffer);
292
293
179M
    for (i = partLen; i + 63 < inputLen; i += 64)
294
178M
      {
295
      
296
178M
      MD5Transform (state, &input [i]);
297
      
298
178M
      }
299
300
890k
    index = 0;
301
    
302
890k
    }
303
    
304
  // Buffer remaining input
305
  
306
1.24M
  memcpy (&buffer [index],
307
1.24M
      &input [i],
308
1.24M
      inputLen - i);
309
  
310
1.24M
  }
311
    
312
/******************************************************************************/
313
314
const dng_fingerprint & dng_md5_printer::Result ()
315
191k
  {
316
  
317
191k
  if (!final)
318
191k
    {
319
    
320
191k
    static uint8 PADDING [64] =
321
191k
      {
322
191k
      0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
323
191k
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
324
191k
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
325
191k
      };
326
327
    // Save number of bits
328
    
329
191k
    uint8 bits [8];
330
331
191k
    Encode (bits, count, 8);
332
333
    // Pad out to 56 mod 64.
334
    
335
191k
    uint32 index = (count [0] >> 3) & 0x3f;
336
    
337
191k
    uint32 padLen = (index < 56) ? (56 - index) : (120 - index);
338
    
339
191k
    Process (PADDING, padLen);
340
341
    // Append length (before padding)
342
343
191k
    Process (bits, 8);
344
345
    // Store state in digest
346
    
347
191k
    Encode (result.data, state, 16);
348
349
    // We are now finalized.
350
    
351
191k
    final = true;
352
    
353
191k
    }
354
  
355
191k
  return result;
356
357
191k
  }
358
359
/******************************************************************************/
360
361
// Encodes input (uint32) into output (uint8). Assumes len is
362
// a multiple of 4.
363
364
void dng_md5_printer::Encode (uint8 *output,
365
                const uint32 *input,
366
                uint32 len)
367
383k
  {
368
369
383k
  uint32 i, j;
370
  
371
1.53M
  for (i = 0, j = 0; j < len; i++, j += 4)
372
1.15M
    {
373
1.15M
    output [j  ] = (uint8) ((input [i]      ) & 0xff);
374
1.15M
    output [j+1] = (uint8) ((input [i] >>  8) & 0xff);
375
1.15M
    output [j+2] = (uint8) ((input [i] >> 16) & 0xff);
376
1.15M
    output [j+3] = (uint8) ((input [i] >> 24) & 0xff);
377
1.15M
    }
378
379
383k
  }
380
381
/******************************************************************************/
382
383
// Decodes input (uint8) into output (uint32). Assumes len is
384
// a multiple of 4.
385
386
void dng_md5_printer::Decode (uint32 *output,
387
                const uint8 *input,
388
                uint32 len)
389
10.3M
  {
390
  
391
  // Check for non-aligned case.
392
  
393
10.3M
  if (((uintptr) input) & 3)
394
10.3M
    {
395
396
10.3M
    uint32 i, j;
397
  
398
175M
    for (i = 0, j = 0; j < len; i++, j += 4)
399
165M
      {
400
      
401
165M
      output [i] = (((uint32) input [j  ])      ) |
402
165M
             (((uint32) input [j+1]) <<  8) |
403
165M
               (((uint32) input [j+2]) << 16) |
404
165M
               (((uint32) input [j+3]) << 24);
405
     
406
165M
        }
407
        
408
10.3M
      }
409
      
410
  // Else use optimized code for aligned case.
411
      
412
0
  else
413
0
    {
414
    
415
0
    len = len >> 2;
416
    
417
0
    const uint32 *sPtr = (const uint32 *) input;
418
    
419
0
    uint32 *dPtr = output;
420
    
421
0
    while (len--)
422
0
      {
423
      
424
      #if qDNGBigEndian
425
      
426
      uint32 data = *(sPtr++);
427
      
428
      data = (data >> 24) |
429
           ((data >> 8) & 0x0000FF00) |
430
           ((data << 8) & 0x00FF0000) |
431
           (data << 24);
432
           
433
      *(dPtr++) = data;
434
      
435
      #else
436
      
437
0
      *(dPtr++) = *(sPtr++);
438
      
439
0
      #endif
440
441
0
      }
442
        
443
0
    }
444
   
445
10.3M
  }
446
447
/******************************************************************************/
448
449
// MD5 basic transformation. Transforms state based on block.
450
451
#if defined(__clang__) && defined(__has_attribute)
452
#if __has_attribute(no_sanitize)
453
__attribute__((no_sanitize("unsigned-integer-overflow")))
454
#endif
455
#endif
456
void dng_md5_printer::MD5Transform (uint32 state [4],
457
                    const uint8 block [64])
458
179M
  {
459
  
460
179M
  enum
461
179M
    {
462
179M
    S11 = 7,
463
179M
    S12 = 12,
464
179M
    S13 = 17,
465
179M
    S14 = 22,
466
179M
    S21 = 5,
467
179M
    S22 = 9,
468
179M
    S23 = 14,
469
179M
    S24 = 20,
470
179M
    S31 = 4,
471
179M
    S32 = 11,
472
179M
    S33 = 16,
473
179M
    S34 = 23,
474
179M
    S41 = 6,
475
179M
    S42 = 10,
476
179M
    S43 = 15,
477
179M
    S44 = 21
478
179M
    };
479
    
480
  #if qDNGBigEndian
481
482
  uint32 x [16];
483
484
  Decode (x, block, 64);
485
  
486
  #else
487
488
179M
  uint32 temp [16];
489
490
179M
  const uint32 *x;
491
  
492
179M
  if (((uintptr) block) & 3)
493
10.3M
    {
494
    
495
10.3M
    Decode (temp, block, 64);
496
    
497
10.3M
    x = temp;
498
    
499
10.3M
    }
500
    
501
169M
  else
502
169M
    x = (const uint32 *) block;
503
    
504
179M
  #endif
505
506
179M
  uint32 a = state [0];
507
179M
  uint32 b = state [1];
508
179M
  uint32 c = state [2];
509
179M
  uint32 d = state [3];
510
  
511
  /* Round 1 */
512
179M
  FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
513
179M
  FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
514
179M
  FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
515
179M
  FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
516
179M
  FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
517
179M
  FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
518
179M
  FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
519
179M
  FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
520
179M
  FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
521
179M
  FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
522
179M
  FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
523
179M
  FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
524
179M
  FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
525
179M
  FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
526
179M
  FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
527
179M
  FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
528
529
  /* Round 2 */
530
179M
  GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
531
179M
  GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
532
179M
  GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
533
179M
  GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
534
179M
  GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
535
179M
  GG (d, a, b, c, x[10], S22,  0x2441453); /* 22 */
536
179M
  GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
537
179M
  GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
538
179M
  GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
539
179M
  GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
540
179M
  GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
541
179M
  GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
542
179M
  GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
543
179M
  GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
544
179M
  GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
545
179M
  GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
546
547
  /* Round 3 */
548
179M
  HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
549
179M
  HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
550
179M
  HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
551
179M
  HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
552
179M
  HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
553
179M
  HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
554
179M
  HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
555
179M
  HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
556
179M
  HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
557
179M
  HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
558
179M
  HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
559
179M
  HH (b, c, d, a, x[ 6], S34,  0x4881d05); /* 44 */
560
179M
  HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
561
179M
  HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
562
179M
  HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
563
179M
  HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
564
565
  /* Round 4 */
566
179M
  II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
567
179M
  II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
568
179M
  II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
569
179M
  II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
570
179M
  II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
571
179M
  II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
572
179M
  II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
573
179M
  II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
574
179M
  II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
575
179M
  II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
576
179M
  II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
577
179M
  II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
578
179M
  II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
579
179M
  II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
580
179M
  II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
581
179M
  II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
582
583
179M
  state [0] += a;
584
179M
  state [1] += b;
585
179M
  state [2] += c;
586
179M
  state [3] += d;
587
588
179M
  }
589
590
/*****************************************************************************/
591
592
// End of RSA Data Security, Inc. derived code.
593
594
/*****************************************************************************/