Coverage Report

Created: 2026-07-25 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dng_sdk/source/dng_matrix.cpp
Line
Count
Source
1
/*****************************************************************************/
2
// Copyright 2006-2008 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_matrix.cpp#1 $ */ 
10
/* $DateTime: 2012/05/30 13:28:51 $ */
11
/* $Change: 832332 $ */
12
/* $Author: tknoll $ */
13
14
/*****************************************************************************/
15
16
#include "dng_matrix.h"
17
18
#include "dng_exceptions.h"
19
#include "dng_utils.h"
20
21
/*****************************************************************************/
22
        
23
dng_matrix::dng_matrix ()
24
            
25
52.8M
  : fRows (0)
26
52.8M
  , fCols (0)
27
  
28
52.8M
  {
29
  
30
52.8M
  }
31
          
32
/*****************************************************************************/
33
        
34
dng_matrix::dng_matrix (uint32 rows,
35
            uint32 cols)
36
            
37
678k
  : fRows (0)
38
678k
  , fCols (0)
39
  
40
678k
  {
41
  
42
678k
  if (rows < 1 || rows > kMaxColorPlanes ||
43
678k
    cols < 1 || cols > kMaxColorPlanes)
44
0
    {
45
    
46
0
    ThrowProgramError ();
47
    
48
0
    }
49
  
50
678k
  fRows = rows;
51
678k
  fCols = cols;
52
  
53
2.68M
  for (uint32 row = 0; row < fRows; row++)
54
8.12M
    for (uint32 col = 0; col < fCols; col++)
55
6.11M
      {
56
      
57
6.11M
      fData [row] [col] = 0.0;
58
      
59
6.11M
      }
60
  
61
678k
  }
62
          
63
/*****************************************************************************/
64
        
65
dng_matrix::dng_matrix (const dng_matrix &m)
66
67
2.69M
  : fRows (m.fRows)
68
2.69M
  , fCols (m.fCols)
69
  
70
2.69M
  {
71
  
72
3.61M
  for (uint32 row = 0; row < fRows; row++)
73
3.69M
    for (uint32 col = 0; col < fCols; col++)
74
2.77M
      {
75
      
76
2.77M
      fData [row] [col] = m.fData [row] [col];
77
      
78
2.77M
      }
79
  
80
2.69M
  }
81
          
82
/*****************************************************************************/
83
        
84
void dng_matrix::Clear () 
85
25.4k
  {
86
  
87
25.4k
  fRows = 0;
88
25.4k
  fCols = 0;
89
  
90
25.4k
  }
91
        
92
/*****************************************************************************/
93
        
94
void dng_matrix::SetIdentity (uint32 count) 
95
5.38k
  {
96
  
97
5.38k
  *this = dng_matrix (count, count);
98
  
99
21.8k
  for (uint32 j = 0; j < count; j++)
100
16.4k
    {
101
    
102
16.4k
    fData [j] [j] = 1.0;
103
    
104
16.4k
    }
105
  
106
5.38k
  }
107
        
108
/******************************************************************************/
109
110
bool dng_matrix::operator== (const dng_matrix &m) const
111
34.7M
  {
112
  
113
34.7M
  if (Rows () != m.Rows () ||
114
34.6M
      Cols () != m.Cols ())
115
121k
    {
116
    
117
121k
    return false;
118
    
119
121k
    }
120
  
121
62.5M
  for (uint32 j = 0; j < Rows (); j++)  
122
111M
    for (uint32 k = 0; k < Cols (); k++)
123
83.9M
      {
124
      
125
83.9M
      if (fData [j] [k] != m.fData [j] [k])
126
69.7k
        {
127
        
128
69.7k
        return false;
129
        
130
69.7k
        }
131
      
132
83.9M
      }
133
      
134
34.5M
  return true;
135
  
136
34.6M
  }
137
138
/******************************************************************************/
139
140
bool dng_matrix::IsDiagonal () const
141
0
  {
142
  
143
0
  if (IsEmpty ())
144
0
    {
145
0
    return false;
146
0
    }
147
  
148
0
  if (Rows () != Cols ())
149
0
    {
150
0
    return false;
151
0
    }
152
  
153
0
  for (uint32 j = 0; j < Rows (); j++)
154
0
    for (uint32 k = 0; k < Cols (); k++)
155
0
      {
156
      
157
0
      if (j != k)
158
0
        {
159
        
160
0
        if (fData [j] [k] != 0.0)
161
0
          {
162
0
          return false;
163
0
          }
164
        
165
0
        }
166
      
167
0
      }
168
      
169
0
  return true;
170
  
171
0
  }
172
173
/******************************************************************************/
174
175
real64 dng_matrix::MaxEntry () const
176
0
  {
177
  
178
0
  if (IsEmpty ())
179
0
    {
180
    
181
0
    return 0.0;
182
    
183
0
    }
184
  
185
0
  real64 m = fData [0] [0];
186
  
187
0
  for (uint32 j = 0; j < Rows (); j++)
188
0
    for (uint32 k = 0; k < Cols (); k++)
189
0
      {
190
      
191
0
      m = Max_real64 (m, fData [j] [k]);
192
      
193
0
      }
194
      
195
0
  return m;
196
  
197
0
  }
198
    
199
/******************************************************************************/
200
201
real64 dng_matrix::MinEntry () const
202
0
  {
203
  
204
0
  if (IsEmpty ())
205
0
    {
206
    
207
0
    return 0.0;
208
    
209
0
    }
210
  
211
0
  real64 m = fData [0] [0];
212
  
213
0
  for (uint32 j = 0; j < Rows (); j++)
214
0
    for (uint32 k = 0; k < Cols (); k++)
215
0
      {
216
      
217
0
      m = Min_real64 (m, fData [j] [k]);
218
      
219
0
      }
220
      
221
0
  return m;
222
  
223
0
  }
224
    
225
/*****************************************************************************/
226
227
void dng_matrix::Scale (real64 factor)
228
184k
  {
229
  
230
739k
  for (uint32 j = 0; j < Rows (); j++)  
231
2.21M
    for (uint32 k = 0; k < Cols (); k++)
232
1.66M
      {
233
      
234
1.66M
      fData [j] [k] *= factor;
235
      
236
1.66M
      }
237
      
238
184k
  }
239
      
240
/*****************************************************************************/
241
242
void dng_matrix::Round (real64 factor)
243
227k
  {
244
  
245
227k
  real64 invFactor = 1.0 / factor;
246
  
247
906k
  for (uint32 j = 0; j < Rows (); j++)  
248
2.71M
    for (uint32 k = 0; k < Cols (); k++)
249
2.03M
      {
250
      
251
2.03M
      fData [j] [k] = Round_int32 (fData [j] [k] * factor) * invFactor;
252
      
253
2.03M
      }
254
      
255
227k
  }
256
  
257
/*****************************************************************************/
258
259
void dng_matrix::SafeRound (real64 factor)
260
0
  {
261
  
262
0
  real64 invFactor = 1.0 / factor;
263
  
264
0
  for (uint32 j = 0; j < Rows (); j++)
265
0
    {
266
    
267
    // Round each row to the specified accuracy, but make sure the
268
    // a rounding does not affect the total of the elements in a row
269
    // more than necessary.
270
    
271
0
    real64 error = 0.0;
272
    
273
0
    for (uint32 k = 0; k < Cols (); k++)
274
0
      {
275
      
276
0
      fData [j] [k] += error;
277
      
278
0
      real64 rounded = Round_int32 (fData [j] [k] * factor) * invFactor;
279
      
280
0
      error = fData [j] [k] - rounded;
281
      
282
0
      fData [j] [k] = rounded;
283
      
284
0
      }
285
    
286
0
    }
287
    
288
0
  }
289
290
/*****************************************************************************/
291
292
dng_matrix_3by3::dng_matrix_3by3 ()
293
294
2.67k
  : dng_matrix (3, 3)
295
  
296
2.67k
  {
297
2.67k
  }
298
    
299
/*****************************************************************************/
300
301
dng_matrix_3by3::dng_matrix_3by3 (const dng_matrix &m)
302
303
2.67k
  : dng_matrix (m)
304
  
305
2.67k
  {
306
  
307
2.67k
  if (Rows () != 3 ||
308
2.67k
    Cols () != 3)
309
0
    {
310
    
311
0
    ThrowMatrixMath ();
312
    
313
0
    }
314
  
315
2.67k
  }
316
    
317
/*****************************************************************************/
318
319
dng_matrix_3by3::dng_matrix_3by3 (real64 a00, real64 a01, real64 a02,
320
                      real64 a10, real64 a11, real64 a12,
321
                      real64 a20, real64 a21, real64 a22)
322
                     
323
324
2.69k
  : dng_matrix (3, 3)
325
  
326
2.69k
  {
327
  
328
2.69k
  fData [0] [0] = a00;
329
2.69k
  fData [0] [1] = a01;
330
2.69k
  fData [0] [2] = a02;
331
  
332
2.69k
  fData [1] [0] = a10;
333
2.69k
  fData [1] [1] = a11;
334
2.69k
  fData [1] [2] = a12;
335
  
336
2.69k
  fData [2] [0] = a20;
337
2.69k
  fData [2] [1] = a21;
338
2.69k
  fData [2] [2] = a22;
339
  
340
2.69k
  }
341
342
/*****************************************************************************/
343
344
dng_matrix_3by3::dng_matrix_3by3 (real64 a00, real64 a11, real64 a22)
345
346
0
  : dng_matrix (3, 3)
347
  
348
0
  {
349
  
350
0
  fData [0] [0] = a00;
351
0
  fData [1] [1] = a11;
352
0
  fData [2] [2] = a22;
353
  
354
0
  }
355
356
/*****************************************************************************/
357
358
dng_matrix_4by3::dng_matrix_4by3 ()
359
360
0
  : dng_matrix (4, 3)
361
  
362
0
  {
363
0
  }
364
    
365
/*****************************************************************************/
366
367
dng_matrix_4by3::dng_matrix_4by3 (const dng_matrix &m)
368
369
0
  : dng_matrix (m)
370
  
371
0
  {
372
  
373
0
  if (Rows () != 4 ||
374
0
    Cols () != 3)
375
0
    {
376
    
377
0
    ThrowMatrixMath ();
378
    
379
0
    }
380
  
381
0
  }
382
    
383
/*****************************************************************************/
384
385
dng_matrix_4by3::dng_matrix_4by3 (real64 a00, real64 a01, real64 a02,
386
                      real64 a10, real64 a11, real64 a12,
387
                      real64 a20, real64 a21, real64 a22,
388
                      real64 a30, real64 a31, real64 a32)
389
                     
390
391
0
  : dng_matrix (4, 3)
392
  
393
0
  {
394
  
395
0
  fData [0] [0] = a00;
396
0
  fData [0] [1] = a01;
397
0
  fData [0] [2] = a02;
398
  
399
0
  fData [1] [0] = a10;
400
0
  fData [1] [1] = a11;
401
0
  fData [1] [2] = a12;
402
  
403
0
  fData [2] [0] = a20;
404
0
  fData [2] [1] = a21;
405
0
  fData [2] [2] = a22;
406
  
407
0
  fData [3] [0] = a30;
408
0
  fData [3] [1] = a31;
409
0
  fData [3] [2] = a32;
410
  
411
0
  }
412
413
/*****************************************************************************/
414
        
415
dng_vector::dng_vector ()
416
417
350k
  : fCount (0)
418
  
419
350k
  {
420
  
421
350k
  }
422
          
423
/*****************************************************************************/
424
        
425
dng_vector::dng_vector (uint32 count)
426
427
458k
  : fCount (0)
428
  
429
458k
  {
430
  
431
458k
  if (count < 1 || count > kMaxColorPlanes)
432
0
    {
433
    
434
0
    ThrowProgramError ();
435
    
436
0
    }
437
  
438
458k
  fCount = count;
439
  
440
1.84M
  for (uint32 index = 0; index < fCount; index++)
441
1.38M
    {
442
    
443
1.38M
    fData [index] = 0.0;
444
    
445
1.38M
    }
446
  
447
458k
  }
448
          
449
/*****************************************************************************/
450
        
451
dng_vector::dng_vector (const dng_vector &v)
452
453
14.6k
  : fCount (v.fCount)
454
  
455
14.6k
  {
456
  
457
58.4k
  for (uint32 index = 0; index < fCount; index++)
458
43.8k
    {
459
    
460
43.8k
    fData [index] = v.fData [index];
461
    
462
43.8k
    }
463
  
464
14.6k
  }
465
          
466
/*****************************************************************************/
467
        
468
void dng_vector::Clear () 
469
4.48k
  {
470
  
471
4.48k
  fCount = 0;
472
  
473
4.48k
  }
474
        
475
/*****************************************************************************/
476
        
477
void dng_vector::SetIdentity (uint32 count) 
478
7.24k
  {
479
  
480
7.24k
  *this = dng_vector (count);
481
  
482
28.9k
  for (uint32 j = 0; j < count; j++)
483
21.7k
    {
484
    
485
21.7k
    fData [j] = 1.0;
486
    
487
21.7k
    }
488
  
489
7.24k
  }
490
        
491
/******************************************************************************/
492
493
bool dng_vector::operator== (const dng_vector &v) const
494
0
  {
495
  
496
0
  if (Count () != v.Count ())
497
0
    {
498
    
499
0
    return false;
500
    
501
0
    }
502
  
503
0
  for (uint32 j = 0; j < Count (); j++) 
504
0
    {
505
    
506
0
    if (fData [j] != v.fData [j])
507
0
      {
508
      
509
0
      return false;
510
      
511
0
      }
512
    
513
0
    }
514
      
515
0
  return true;
516
  
517
0
  }
518
519
/******************************************************************************/
520
521
real64 dng_vector::MaxEntry () const
522
200k
  {
523
  
524
200k
  if (IsEmpty ())
525
0
    {
526
    
527
0
    return 0.0;
528
    
529
0
    }
530
  
531
200k
  real64 m = fData [0];
532
  
533
800k
  for (uint32 j = 0; j < Count (); j++)
534
600k
    {
535
    
536
600k
    m = Max_real64 (m, fData [j]);
537
    
538
600k
    }
539
      
540
200k
  return m;
541
  
542
200k
  }
543
    
544
/******************************************************************************/
545
546
real64 dng_vector::MinEntry () const
547
5.67k
  {
548
  
549
5.67k
  if (IsEmpty ())
550
0
    {
551
    
552
0
    return 0.0;
553
    
554
0
    }
555
  
556
5.67k
  real64 m = fData [0];
557
  
558
22.6k
  for (uint32 j = 0; j < Count (); j++)
559
16.9k
    {
560
    
561
16.9k
    m = Min_real64 (m, fData [j]);
562
    
563
16.9k
    }
564
      
565
5.67k
  return m;
566
  
567
5.67k
  }
568
    
569
/*****************************************************************************/
570
571
void dng_vector::Scale (real64 factor)
572
4.02k
  {
573
  
574
16.0k
  for (uint32 j = 0; j < Count (); j++)  
575
12.0k
    {
576
    
577
12.0k
    fData [j] *= factor;
578
    
579
12.0k
    }
580
    
581
4.02k
  }
582
      
583
/*****************************************************************************/
584
585
void dng_vector::Round (real64 factor)
586
4.02k
  {
587
  
588
4.02k
  real64 invFactor = 1.0 / factor;
589
  
590
15.9k
  for (uint32 j = 0; j < Count (); j++)  
591
11.9k
    {
592
    
593
11.9k
    fData [j] = Round_int32 (fData [j] * factor) * invFactor;
594
    
595
11.9k
    }
596
      
597
4.02k
  }
598
  
599
/*****************************************************************************/
600
        
601
dng_matrix dng_vector::AsDiagonal () const
602
6.04k
  {
603
  
604
6.04k
  dng_matrix M (Count (), Count ());
605
  
606
24.1k
  for (uint32 j = 0; j < Count (); j++)
607
18.0k
    {
608
    
609
18.0k
    M [j] [j] = fData [j];
610
    
611
18.0k
    }
612
    
613
6.04k
  return M;
614
  
615
6.04k
  }
616
617
/*****************************************************************************/
618
        
619
dng_matrix dng_vector::AsColumn () const
620
3
  {
621
  
622
3
  dng_matrix M (Count (), 1);
623
  
624
12
  for (uint32 j = 0; j < Count (); j++)
625
9
    {
626
    
627
9
    M [j] [0] = fData [j];
628
    
629
9
    }
630
    
631
3
  return M;
632
  
633
3
  }
634
635
/******************************************************************************/
636
637
dng_vector_3::dng_vector_3 ()
638
639
0
  : dng_vector (3)
640
  
641
0
  {
642
0
  }
643
    
644
/******************************************************************************/
645
646
dng_vector_3::dng_vector_3 (const dng_vector &v)
647
648
7.39k
  : dng_vector (v)
649
  
650
7.39k
  {
651
  
652
7.39k
  if (Count () != 3)
653
0
    {
654
    
655
0
    ThrowMatrixMath ();
656
           
657
0
    }
658
  
659
7.39k
  }
660
    
661
/******************************************************************************/
662
663
dng_vector_3::dng_vector_3 (real64 a0,
664
              real64 a1,
665
                real64 a2)
666
667
212k
  : dng_vector (3)
668
  
669
212k
  {
670
  
671
212k
  fData [0] = a0;
672
212k
  fData [1] = a1;
673
212k
  fData [2] = a2;
674
  
675
212k
  }
676
    
677
/******************************************************************************/
678
679
dng_vector_4::dng_vector_4 ()
680
681
0
  : dng_vector (4)
682
  
683
0
  {
684
0
  }
685
    
686
/******************************************************************************/
687
688
dng_vector_4::dng_vector_4 (const dng_vector &v)
689
690
0
  : dng_vector (v)
691
  
692
0
  {
693
  
694
0
  if (Count () != 4)
695
0
    {
696
    
697
0
    ThrowMatrixMath ();
698
           
699
0
    }
700
  
701
0
  }
702
    
703
/******************************************************************************/
704
705
dng_vector_4::dng_vector_4 (real64 a0,
706
              real64 a1,
707
                real64 a2,
708
                real64 a3)
709
710
0
  : dng_vector (4)
711
  
712
0
  {
713
  
714
0
  fData [0] = a0;
715
0
  fData [1] = a1;
716
0
  fData [2] = a2;
717
0
  fData [3] = a3;
718
  
719
0
  }
720
    
721
/******************************************************************************/
722
723
dng_matrix operator* (const dng_matrix &A,
724
            const dng_matrix &B)
725
37.1k
  {
726
  
727
37.1k
  if (A.Cols () != B.Rows ())
728
0
    {
729
    
730
0
    ThrowMatrixMath ();
731
           
732
0
    }
733
  
734
37.1k
  dng_matrix C (A.Rows (), B.Cols ());
735
  
736
138k
  for (uint32 j = 0; j < C.Rows (); j++)
737
403k
    for (uint32 k = 0; k < C.Cols (); k++)
738
302k
      {
739
      
740
302k
      C [j] [k] = 0.0;
741
      
742
1.20M
      for (uint32 m = 0; m < A.Cols (); m++)
743
907k
        {
744
        
745
907k
        real64 aa = A [j] [m];
746
        
747
907k
        real64 bb = B [m] [k];
748
        
749
907k
        C [j] [k] += aa * bb;
750
        
751
907k
        }
752
      
753
302k
      }
754
      
755
37.1k
  return C;
756
757
37.1k
  }
758
759
/******************************************************************************/
760
761
dng_vector operator* (const dng_matrix &A,
762
            const dng_vector &B)
763
214k
  {
764
  
765
214k
  if (A.Cols () != B.Count ())
766
0
    {
767
    
768
0
    ThrowMatrixMath ();
769
           
770
0
    }
771
  
772
214k
  dng_vector C (A.Rows ());
773
  
774
858k
  for (uint32 j = 0; j < C.Count (); j++)
775
643k
    {
776
    
777
643k
    C [j] = 0.0;
778
    
779
2.57M
    for (uint32 m = 0; m < A.Cols (); m++)
780
1.93M
      {
781
      
782
1.93M
      real64 aa = A [j] [m];
783
      
784
1.93M
      real64 bb = B [m];
785
      
786
1.93M
      C [j] += aa * bb;
787
      
788
1.93M
      }
789
    
790
643k
    }
791
      
792
214k
  return C;
793
794
214k
  }
795
796
/******************************************************************************/
797
798
dng_matrix operator* (real64 scale,
799
            const dng_matrix &A)
800
4.71k
  {
801
  
802
4.71k
  dng_matrix B (A);
803
  
804
4.71k
  B.Scale (scale);
805
  
806
4.71k
  return B;
807
    
808
4.71k
  }
809
810
/******************************************************************************/
811
812
dng_vector operator* (real64 scale,
813
            const dng_vector &A)
814
0
  {
815
  
816
0
  dng_vector B (A);
817
  
818
0
  B.Scale (scale);
819
  
820
0
  return B;
821
    
822
0
  }
823
824
/******************************************************************************/
825
826
dng_matrix operator+ (const dng_matrix &A,
827
            const dng_matrix &B)
828
1.02k
  {
829
  
830
1.02k
  if (A.Cols () != B.Cols () ||
831
1.02k
    A.Rows () != B.Rows ())
832
0
    {
833
    
834
0
    ThrowMatrixMath ();
835
           
836
0
    }
837
  
838
1.02k
  dng_matrix C (A);
839
  
840
4.52k
  for (uint32 j = 0; j < C.Rows (); j++)
841
14.1k
    for (uint32 k = 0; k < C.Cols (); k++)
842
10.5k
      {
843
      
844
10.5k
      C [j] [k] += B [j] [k];
845
            
846
10.5k
      }
847
      
848
1.02k
  return C;
849
850
1.02k
  }
851
852
/******************************************************************************/
853
854
const real64 kNearZero = 1.0E-10; 
855
856
/******************************************************************************/
857
858
// Work around bug #1294195, which may be a hardware problem on a specific machine.
859
// This pragma turns on "improved" floating-point consistency.
860
#ifdef _MSC_VER
861
#pragma optimize ("p", on)
862
#endif
863
864
static dng_matrix Invert3by3 (const dng_matrix &A)
865
191k
  {
866
  
867
191k
  real64 a00 = A [0] [0];
868
191k
  real64 a01 = A [0] [1];
869
191k
  real64 a02 = A [0] [2];
870
191k
  real64 a10 = A [1] [0];
871
191k
  real64 a11 = A [1] [1];
872
191k
  real64 a12 = A [1] [2];
873
191k
  real64 a20 = A [2] [0];
874
191k
  real64 a21 = A [2] [1];
875
191k
  real64 a22 = A [2] [2];
876
  
877
191k
  real64 temp [3] [3];
878
879
191k
  temp [0] [0] = a11 * a22 - a21 * a12;
880
191k
  temp [0] [1] = a21 * a02 - a01 * a22;
881
191k
  temp [0] [2] = a01 * a12 - a11 * a02;
882
191k
  temp [1] [0] = a20 * a12 - a10 * a22;
883
191k
  temp [1] [1] = a00 * a22 - a20 * a02;
884
191k
  temp [1] [2] = a10 * a02 - a00 * a12;
885
191k
  temp [2] [0] = a10 * a21 - a20 * a11;
886
191k
  temp [2] [1] = a20 * a01 - a00 * a21;
887
191k
  temp [2] [2] = a00 * a11 - a10 * a01;
888
889
191k
  real64 det = (a00 * temp [0] [0] +
890
191k
          a01 * temp [1] [0] +
891
191k
          a02 * temp [2] [0]);
892
893
191k
  if (Abs_real64 (det) < kNearZero)
894
4.70k
    {
895
    
896
4.70k
    ThrowMatrixMath ();
897
           
898
4.70k
    }
899
900
191k
  dng_matrix B (3, 3);
901
  
902
753k
  for (uint32 j = 0; j < 3; j++)  
903
2.24M
    for (uint32 k = 0; k < 3; k++)
904
1.68M
      {
905
      
906
1.68M
      B [j] [k] = temp [j] [k] / det;
907
      
908
1.68M
      }
909
      
910
191k
  return B;
911
912
191k
  }
913
    
914
// Reset floating-point optimization. See comment above.
915
#ifdef _MSC_VER
916
#pragma optimize ("p", off)
917
#endif
918
919
/******************************************************************************/
920
921
static dng_matrix InvertNbyN (const dng_matrix &A)
922
189
  {
923
  
924
189
  uint32 i;
925
189
  uint32 j;
926
189
  uint32 k;
927
  
928
189
  uint32 n = A.Rows ();
929
  
930
189
  real64 temp [kMaxColorPlanes] [kMaxColorPlanes * 2];
931
  
932
681
  for (i = 0; i < n; i++)
933
1.93k
    for (j = 0; j < n; j++)
934
1.44k
      {
935
      
936
1.44k
      temp [i] [j    ] = A [i] [j];
937
      
938
1.44k
      temp [i] [j + n] = (i == j ? 1.0 : 0.0);
939
      
940
1.44k
      }
941
      
942
628
  for (i = 0; i < n; i++)
943
439
    {
944
    
945
439
    real64 alpha = temp [i] [i];
946
    
947
439
    if (Abs_real64 (alpha) < kNearZero)
948
41
      {
949
      
950
41
      ThrowMatrixMath ();
951
             
952
41
      }
953
      
954
2.60k
    for (j = 0; j < n * 2; j++)
955
2.16k
      {
956
      
957
2.16k
      temp [i] [j] /= alpha;
958
      
959
2.16k
      }
960
      
961
1.52k
    for (k = 0; k < n; k++)
962
1.08k
      {
963
      
964
1.08k
      if (i != k)
965
686
        {
966
        
967
686
        real64 beta = temp [k] [i];
968
        
969
5.15k
        for (j = 0; j < n * 2; j++)
970
4.47k
          {
971
          
972
4.47k
          temp [k] [j] -= beta * temp [i] [j];
973
          
974
4.47k
          }
975
        
976
686
        }
977
      
978
1.08k
      }
979
      
980
439
    }
981
    
982
189
  dng_matrix B (n, n);
983
  
984
533
  for (i = 0; i < n; i++)
985
1.22k
    for (j = 0; j < n; j++)
986
880
      {
987
      
988
880
      B [i] [j] = temp [i] [j + n];
989
      
990
880
      }
991
      
992
189
  return B;
993
994
189
  }
995
    
996
/******************************************************************************/
997
998
dng_matrix Transpose (const dng_matrix &A)
999
4.82k
  {
1000
  
1001
4.82k
  dng_matrix B (A.Cols (), A.Rows ());
1002
  
1003
19.3k
  for (uint32 j = 0; j < B.Rows (); j++)
1004
53.9k
    for (uint32 k = 0; k < B.Cols (); k++)
1005
39.4k
      {
1006
      
1007
39.4k
      B [j] [k] = A [k] [j];
1008
      
1009
39.4k
      }
1010
      
1011
4.82k
  return B; 
1012
  
1013
4.82k
  }
1014
1015
/******************************************************************************/
1016
1017
dng_matrix Invert (const dng_matrix &A)
1018
196k
  {
1019
  
1020
196k
  if (A.Rows () < 2 || A.Cols () < 2)
1021
0
    {
1022
    
1023
0
    ThrowMatrixMath ();
1024
             
1025
0
    }
1026
  
1027
196k
  if (A.Rows () == A.Cols ())
1028
192k
    {
1029
    
1030
192k
    if (A.Rows () == 3)
1031
191k
      {
1032
      
1033
191k
      return Invert3by3 (A);
1034
      
1035
191k
      }
1036
      
1037
189
    return InvertNbyN (A);
1038
    
1039
192k
    }
1040
    
1041
4.82k
  else
1042
4.82k
    {
1043
    
1044
    // Compute the pseudo inverse.
1045
  
1046
4.82k
    dng_matrix B = Transpose (A);
1047
  
1048
4.82k
    return Invert (B * A) * B;
1049
    
1050
4.82k
    }
1051
    
1052
196k
  }
1053
    
1054
/******************************************************************************/
1055
1056
dng_matrix Invert (const dng_matrix &A,
1057
           const dng_matrix &hint)
1058
25.7k
  {
1059
  
1060
25.7k
  if (A.Rows () == A   .Cols () ||
1061
973
    A.Rows () != hint.Cols () ||
1062
47
    A.Cols () != hint.Rows ())
1063
25.7k
    {
1064
    
1065
25.7k
    return Invert (A);
1066
    
1067
25.7k
    }
1068
    
1069
47
  else
1070
47
    {
1071
    
1072
    // Use the specified hint matrix.
1073
    
1074
47
    return Invert (hint * A) * hint;
1075
    
1076
47
    }
1077
  
1078
25.7k
  }
1079
  
1080
/*****************************************************************************/