1/*****************************************************************************/
2// Copyright 2006-2009 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_reference.cpp#1 $ */
10/* $DateTime: 2012/05/30 13:28:51 $ */
11/* $Change: 832332 $ */
12/* $Author: tknoll $ */
13
14/*****************************************************************************/
15
16#include "dng_reference.h"
17
18#include "dng_1d_table.h"
19#include "dng_hue_sat_map.h"
20#include "dng_matrix.h"
21#include "dng_resample.h"
22#include "dng_utils.h"
23
24/*****************************************************************************/
25
26// This module contains routines that should be as fast as possible, even
27// at the expense of slight code size increases.
28
29#include "dng_fast_module.h"
30
31/*****************************************************************************/
32
33void RefZeroBytes (void *dPtr,
34 uint32 count)
35 {
36
37 memset (dPtr, 0, count);
38
39 }
40
41/*****************************************************************************/
42
43void RefCopyBytes (const void *sPtr,
44 void *dPtr,
45 uint32 count)
46 {
47
48 memcpy (dPtr, sPtr, count);
49
50 }
51
52/*****************************************************************************/
53
54void RefSwapBytes16 (uint16 *dPtr,
55 uint32 count)
56 {
57
58 for (uint32 j = 0; j < count; j++)
59 {
60
61 dPtr [j] = SwapBytes16 (dPtr [j]);
62
63 }
64
65 }
66
67/*****************************************************************************/
68
69void RefSwapBytes32 (uint32 *dPtr,
70 uint32 count)
71 {
72
73 for (uint32 j = 0; j < count; j++)
74 {
75
76 dPtr [j] = SwapBytes32 (dPtr [j]);
77
78 }
79
80 }
81
82/*****************************************************************************/
83
84void RefSetArea8 (uint8 *dPtr,
85 uint8 value,
86 uint32 rows,
87 uint32 cols,
88 uint32 planes,
89 int32 rowStep,
90 int32 colStep,
91 int32 planeStep)
92 {
93
94 for (uint32 row = 0; row < rows; row++)
95 {
96
97 uint8 *dPtr1 = dPtr;
98
99 for (uint32 col = 0; col < cols; col++)
100 {
101
102 uint8 *dPtr2 = dPtr1;
103
104 for (uint32 plane = 0; plane < planes; plane++)
105 {
106
107 *dPtr2 = value;
108
109 dPtr2 += planeStep;
110
111 }
112
113 dPtr1 += colStep;
114
115 }
116
117 dPtr += rowStep;
118
119 }
120
121 }
122
123/*****************************************************************************/
124
125void RefSetArea16 (uint16 *dPtr,
126 uint16 value,
127 uint32 rows,
128 uint32 cols,
129 uint32 planes,
130 int32 rowStep,
131 int32 colStep,
132 int32 planeStep)
133 {
134
135 for (uint32 row = 0; row < rows; row++)
136 {
137
138 uint16 *dPtr1 = dPtr;
139
140 for (uint32 col = 0; col < cols; col++)
141 {
142
143 uint16 *dPtr2 = dPtr1;
144
145 for (uint32 plane = 0; plane < planes; plane++)
146 {
147
148 *dPtr2 = value;
149
150 dPtr2 += planeStep;
151
152 }
153
154 dPtr1 += colStep;
155
156 }
157
158 dPtr += rowStep;
159
160 }
161
162 }
163
164/*****************************************************************************/
165
166void RefSetArea32 (uint32 *dPtr,
167 uint32 value,
168 uint32 rows,
169 uint32 cols,
170 uint32 planes,
171 int32 rowStep,
172 int32 colStep,
173 int32 planeStep)
174 {
175
176 for (uint32 row = 0; row < rows; row++)
177 {
178
179 uint32 *dPtr1 = dPtr;
180
181 for (uint32 col = 0; col < cols; col++)
182 {
183
184 uint32 *dPtr2 = dPtr1;
185
186 for (uint32 plane = 0; plane < planes; plane++)
187 {
188
189 *dPtr2 = value;
190
191 dPtr2 += planeStep;
192
193 }
194
195 dPtr1 += colStep;
196
197 }
198
199 dPtr += rowStep;
200
201 }
202
203 }
204
205/*****************************************************************************/
206
207void RefCopyArea8 (const uint8 *sPtr,
208 uint8 *dPtr,
209 uint32 rows,
210 uint32 cols,
211 uint32 planes,
212 int32 sRowStep,
213 int32 sColStep,
214 int32 sPlaneStep,
215 int32 dRowStep,
216 int32 dColStep,
217 int32 dPlaneStep)
218 {
219
220 for (uint32 row = 0; row < rows; row++)
221 {
222
223 const uint8 *sPtr1 = sPtr;
224 uint8 *dPtr1 = dPtr;
225
226 for (uint32 col = 0; col < cols; col++)
227 {
228
229 const uint8 *sPtr2 = sPtr1;
230 uint8 *dPtr2 = dPtr1;
231
232 for (uint32 plane = 0; plane < planes; plane++)
233 {
234
235 *dPtr2 = *sPtr2;
236
237 sPtr2 += sPlaneStep;
238 dPtr2 += dPlaneStep;
239
240 }
241
242 sPtr1 += sColStep;
243 dPtr1 += dColStep;
244
245 }
246
247 sPtr += sRowStep;
248 dPtr += dRowStep;
249
250 }
251
252 }
253
254/*****************************************************************************/
255
256void RefCopyArea16 (const uint16 *sPtr,
257 uint16 *dPtr,
258 uint32 rows,
259 uint32 cols,
260 uint32 planes,
261 int32 sRowStep,
262 int32 sColStep,
263 int32 sPlaneStep,
264 int32 dRowStep,
265 int32 dColStep,
266 int32 dPlaneStep)
267 {
268
269 for (uint32 row = 0; row < rows; row++)
270 {
271
272 const uint16 *sPtr1 = sPtr;
273 uint16 *dPtr1 = dPtr;
274
275 for (uint32 col = 0; col < cols; col++)
276 {
277
278 const uint16 *sPtr2 = sPtr1;
279 uint16 *dPtr2 = dPtr1;
280
281 for (uint32 plane = 0; plane < planes; plane++)
282 {
283
284 *dPtr2 = *sPtr2;
285
286 sPtr2 += sPlaneStep;
287 dPtr2 += dPlaneStep;
288
289 }
290
291 sPtr1 += sColStep;
292 dPtr1 += dColStep;
293
294 }
295
296 sPtr += sRowStep;
297 dPtr += dRowStep;
298
299 }
300
301 }
302
303/*****************************************************************************/
304
305void RefCopyArea32 (const uint32 *sPtr,
306 uint32 *dPtr,
307 uint32 rows,
308 uint32 cols,
309 uint32 planes,
310 int32 sRowStep,
311 int32 sColStep,
312 int32 sPlaneStep,
313 int32 dRowStep,
314 int32 dColStep,
315 int32 dPlaneStep)
316 {
317
318 for (uint32 row = 0; row < rows; row++)
319 {
320
321 const uint32 *sPtr1 = sPtr;
322 uint32 *dPtr1 = dPtr;
323
324 for (uint32 col = 0; col < cols; col++)
325 {
326
327 const uint32 *sPtr2 = sPtr1;
328 uint32 *dPtr2 = dPtr1;
329
330 for (uint32 plane = 0; plane < planes; plane++)
331 {
332
333 *dPtr2 = *sPtr2;
334
335 sPtr2 += sPlaneStep;
336 dPtr2 += dPlaneStep;
337
338 }
339
340 sPtr1 += sColStep;
341 dPtr1 += dColStep;
342
343 }
344
345 sPtr += sRowStep;
346 dPtr += dRowStep;
347
348 }
349
350 }
351
352/*****************************************************************************/
353
354void RefCopyArea8_16 (const uint8 *sPtr,
355 uint16 *dPtr,
356 uint32 rows,
357 uint32 cols,
358 uint32 planes,
359 int32 sRowStep,
360 int32 sColStep,
361 int32 sPlaneStep,
362 int32 dRowStep,
363 int32 dColStep,
364 int32 dPlaneStep)
365 {
366
367 for (uint32 row = 0; row < rows; row++)
368 {
369
370 const uint8 *sPtr1 = sPtr;
371 uint16 *dPtr1 = dPtr;
372
373 for (uint32 col = 0; col < cols; col++)
374 {
375
376 const uint8 *sPtr2 = sPtr1;
377 uint16 *dPtr2 = dPtr1;
378
379 for (uint32 plane = 0; plane < planes; plane++)
380 {
381
382 *dPtr2 = *sPtr2;
383
384 sPtr2 += sPlaneStep;
385 dPtr2 += dPlaneStep;
386
387 }
388
389 sPtr1 += sColStep;
390 dPtr1 += dColStep;
391
392 }
393
394 sPtr += sRowStep;
395 dPtr += dRowStep;
396
397 }
398
399 }
400
401/*****************************************************************************/
402
403void RefCopyArea8_S16 (const uint8 *sPtr,
404 int16 *dPtr,
405 uint32 rows,
406 uint32 cols,
407 uint32 planes,
408 int32 sRowStep,
409 int32 sColStep,
410 int32 sPlaneStep,
411 int32 dRowStep,
412 int32 dColStep,
413 int32 dPlaneStep)
414 {
415
416 for (uint32 row = 0; row < rows; row++)
417 {
418
419 const uint8 *sPtr1 = sPtr;
420 int16 *dPtr1 = dPtr;
421
422 for (uint32 col = 0; col < cols; col++)
423 {
424
425 const uint8 *sPtr2 = sPtr1;
426 int16 *dPtr2 = dPtr1;
427
428 for (uint32 plane = 0; plane < planes; plane++)
429 {
430
431 int16 x = *sPtr;
432
433 *dPtr2 = x ^ 0x8000;
434
435 sPtr2 += sPlaneStep;
436 dPtr2 += dPlaneStep;
437
438 }
439
440 sPtr1 += sColStep;
441 dPtr1 += dColStep;
442
443 }
444
445 sPtr += sRowStep;
446 dPtr += dRowStep;
447
448 }
449
450 }
451
452/*****************************************************************************/
453
454void RefCopyArea8_32 (const uint8 *sPtr,
455 uint32 *dPtr,
456 uint32 rows,
457 uint32 cols,
458 uint32 planes,
459 int32 sRowStep,
460 int32 sColStep,
461 int32 sPlaneStep,
462 int32 dRowStep,
463 int32 dColStep,
464 int32 dPlaneStep)
465 {
466
467 for (uint32 row = 0; row < rows; row++)
468 {
469
470 const uint8 *sPtr1 = sPtr;
471 uint32 *dPtr1 = dPtr;
472
473 for (uint32 col = 0; col < cols; col++)
474 {
475
476 const uint8 *sPtr2 = sPtr1;
477 uint32 *dPtr2 = dPtr1;
478
479 for (uint32 plane = 0; plane < planes; plane++)
480 {
481
482 *dPtr2 = *sPtr2;
483
484 sPtr2 += sPlaneStep;
485 dPtr2 += dPlaneStep;
486
487 }
488
489 sPtr1 += sColStep;
490 dPtr1 += dColStep;
491
492 }
493
494 sPtr += sRowStep;
495 dPtr += dRowStep;
496
497 }
498
499 }
500
501/*****************************************************************************/
502
503void RefCopyArea16_S16 (const uint16 *sPtr,
504 int16 *dPtr,
505 uint32 rows,
506 uint32 cols,
507 uint32 planes,
508 int32 sRowStep,
509 int32 sColStep,
510 int32 sPlaneStep,
511 int32 dRowStep,
512 int32 dColStep,
513 int32 dPlaneStep)
514 {
515
516 for (uint32 row = 0; row < rows; row++)
517 {
518
519 const uint16 *sPtr1 = sPtr;
520 int16 *dPtr1 = dPtr;
521
522 for (uint32 col = 0; col < cols; col++)
523 {
524
525 const uint16 *sPtr2 = sPtr1;
526 int16 *dPtr2 = dPtr1;
527
528 for (uint32 plane = 0; plane < planes; plane++)
529 {
530
531 *dPtr2 = *sPtr2 ^ 0x8000;
532
533 sPtr2 += sPlaneStep;
534 dPtr2 += dPlaneStep;
535
536 }
537
538 sPtr1 += sColStep;
539 dPtr1 += dColStep;
540
541 }
542
543 sPtr += sRowStep;
544 dPtr += dRowStep;
545
546 }
547
548 }
549
550/*****************************************************************************/
551
552void RefCopyArea16_32 (const uint16 *sPtr,
553 uint32 *dPtr,
554 uint32 rows,
555 uint32 cols,
556 uint32 planes,
557 int32 sRowStep,
558 int32 sColStep,
559 int32 sPlaneStep,
560 int32 dRowStep,
561 int32 dColStep,
562 int32 dPlaneStep)
563 {
564
565 for (uint32 row = 0; row < rows; row++)
566 {
567
568 const uint16 *sPtr1 = sPtr;
569 uint32 *dPtr1 = dPtr;
570
571 for (uint32 col = 0; col < cols; col++)
572 {
573
574 const uint16 *sPtr2 = sPtr1;
575 uint32 *dPtr2 = dPtr1;
576
577 for (uint32 plane = 0; plane < planes; plane++)
578 {
579
580 *dPtr2 = *sPtr2;
581
582 sPtr2 += sPlaneStep;
583 dPtr2 += dPlaneStep;
584
585 }
586
587 sPtr1 += sColStep;
588 dPtr1 += dColStep;
589
590 }
591
592 sPtr += sRowStep;
593 dPtr += dRowStep;
594
595 }
596
597 }
598
599/*****************************************************************************/
600
601void RefCopyArea8_R32 (const uint8 *sPtr,
602 real32 *dPtr,
603 uint32 rows,
604 uint32 cols,
605 uint32 planes,
606 int32 sRowStep,
607 int32 sColStep,
608 int32 sPlaneStep,
609 int32 dRowStep,
610 int32 dColStep,
611 int32 dPlaneStep,
612 uint32 pixelRange)
613 {
614
615 real32 scale = 1.0f / (real32) pixelRange;
616
617 for (uint32 row = 0; row < rows; row++)
618 {
619
620 const uint8 *sPtr1 = sPtr;
621 real32 *dPtr1 = dPtr;
622
623 for (uint32 col = 0; col < cols; col++)
624 {
625
626 const uint8 *sPtr2 = sPtr1;
627 real32 *dPtr2 = dPtr1;
628
629 for (uint32 plane = 0; plane < planes; plane++)
630 {
631
632 *dPtr2 = scale * (real32) *sPtr2;
633
634 sPtr2 += sPlaneStep;
635 dPtr2 += dPlaneStep;
636
637 }
638
639 sPtr1 += sColStep;
640 dPtr1 += dColStep;
641
642 }
643
644 sPtr += sRowStep;
645 dPtr += dRowStep;
646
647 }
648
649 }
650
651/*****************************************************************************/
652
653void RefCopyArea16_R32 (const uint16 *sPtr,
654 real32 *dPtr,
655 uint32 rows,
656 uint32 cols,
657 uint32 planes,
658 int32 sRowStep,
659 int32 sColStep,
660 int32 sPlaneStep,
661 int32 dRowStep,
662 int32 dColStep,
663 int32 dPlaneStep,
664 uint32 pixelRange)
665 {
666
667 real32 scale = 1.0f / (real32) pixelRange;
668
669 for (uint32 row = 0; row < rows; row++)
670 {
671
672 const uint16 *sPtr1 = sPtr;
673 real32 *dPtr1 = dPtr;
674
675 for (uint32 col = 0; col < cols; col++)
676 {
677
678 const uint16 *sPtr2 = sPtr1;
679 real32 *dPtr2 = dPtr1;
680
681 for (uint32 plane = 0; plane < planes; plane++)
682 {
683
684 *dPtr2 = scale * (real32) *sPtr2;
685
686 sPtr2 += sPlaneStep;
687 dPtr2 += dPlaneStep;
688
689 }
690
691 sPtr1 += sColStep;
692 dPtr1 += dColStep;
693
694 }
695
696 sPtr += sRowStep;
697 dPtr += dRowStep;
698
699 }
700
701 }
702
703/*****************************************************************************/
704
705void RefCopyAreaS16_R32 (const int16 *sPtr,
706 real32 *dPtr,
707 uint32 rows,
708 uint32 cols,
709 uint32 planes,
710 int32 sRowStep,
711 int32 sColStep,
712 int32 sPlaneStep,
713 int32 dRowStep,
714 int32 dColStep,
715 int32 dPlaneStep,
716 uint32 pixelRange)
717 {
718
719 real32 scale = 1.0f / (real32) pixelRange;
720
721 for (uint32 row = 0; row < rows; row++)
722 {
723
724 const int16 *sPtr1 = sPtr;
725 real32 *dPtr1 = dPtr;
726
727 for (uint32 col = 0; col < cols; col++)
728 {
729
730 const int16 *sPtr2 = sPtr1;
731 real32 *dPtr2 = dPtr1;
732
733 for (uint32 plane = 0; plane < planes; plane++)
734 {
735
736 int32 x = (*sPtr ^ 0x8000);
737
738 *dPtr2 = scale * (real32) x;
739
740 sPtr2 += sPlaneStep;
741 dPtr2 += dPlaneStep;
742
743 }
744
745 sPtr1 += sColStep;
746 dPtr1 += dColStep;
747
748 }
749
750 sPtr += sRowStep;
751 dPtr += dRowStep;
752
753 }
754
755 }
756
757/*****************************************************************************/
758
759void RefCopyAreaR32_8 (const real32 *sPtr,
760 uint8 *dPtr,
761 uint32 rows,
762 uint32 cols,
763 uint32 planes,
764 int32 sRowStep,
765 int32 sColStep,
766 int32 sPlaneStep,
767 int32 dRowStep,
768 int32 dColStep,
769 int32 dPlaneStep,
770 uint32 pixelRange)
771 {
772
773 real32 scale = (real32) pixelRange;
774
775 for (uint32 row = 0; row < rows; row++)
776 {
777
778 const real32 *sPtr1 = sPtr;
779 uint8 *dPtr1 = dPtr;
780
781 for (uint32 col = 0; col < cols; col++)
782 {
783
784 const real32 *sPtr2 = sPtr1;
785 uint8 *dPtr2 = dPtr1;
786
787 for (uint32 plane = 0; plane < planes; plane++)
788 {
789
790 *dPtr2 = (uint8) (Pin_Overrange (*sPtr2) * scale + 0.5f);
791
792 sPtr2 += sPlaneStep;
793 dPtr2 += dPlaneStep;
794
795 }
796
797 sPtr1 += sColStep;
798 dPtr1 += dColStep;
799
800 }
801
802 sPtr += sRowStep;
803 dPtr += dRowStep;
804
805 }
806
807 }
808
809/*****************************************************************************/
810
811void RefCopyAreaR32_16 (const real32 *sPtr,
812 uint16 *dPtr,
813 uint32 rows,
814 uint32 cols,
815 uint32 planes,
816 int32 sRowStep,
817 int32 sColStep,
818 int32 sPlaneStep,
819 int32 dRowStep,
820 int32 dColStep,
821 int32 dPlaneStep,
822 uint32 pixelRange)
823 {
824
825 real32 scale = (real32) pixelRange;
826
827 for (uint32 row = 0; row < rows; row++)
828 {
829
830 const real32 *sPtr1 = sPtr;
831 uint16 *dPtr1 = dPtr;
832
833 for (uint32 col = 0; col < cols; col++)
834 {
835
836 const real32 *sPtr2 = sPtr1;
837 uint16 *dPtr2 = dPtr1;
838
839 for (uint32 plane = 0; plane < planes; plane++)
840 {
841
842 *dPtr2 = (uint16) (Pin_Overrange (*sPtr2) * scale + 0.5f);
843
844 sPtr2 += sPlaneStep;
845 dPtr2 += dPlaneStep;
846
847 }
848
849 sPtr1 += sColStep;
850 dPtr1 += dColStep;
851
852 }
853
854 sPtr += sRowStep;
855 dPtr += dRowStep;
856
857 }
858
859 }
860
861/*****************************************************************************/
862
863void RefCopyAreaR32_S16 (const real32 *sPtr,
864 int16 *dPtr,
865 uint32 rows,
866 uint32 cols,
867 uint32 planes,
868 int32 sRowStep,
869 int32 sColStep,
870 int32 sPlaneStep,
871 int32 dRowStep,
872 int32 dColStep,
873 int32 dPlaneStep,
874 uint32 pixelRange)
875 {
876
877 real32 scale = (real32) pixelRange;
878
879 for (uint32 row = 0; row < rows; row++)
880 {
881
882 const real32 *sPtr1 = sPtr;
883 int16 *dPtr1 = dPtr;
884
885 for (uint32 col = 0; col < cols; col++)
886 {
887
888 const real32 *sPtr2 = sPtr1;
889 int16 *dPtr2 = dPtr1;
890
891 for (uint32 plane = 0; plane < planes; plane++)
892 {
893
894 int32 x = (int32) (Pin_Overrange (*sPtr2) * scale + 0.5f);
895
896 *dPtr2 = (int16) (x ^ 0x8000);
897
898 sPtr2 += sPlaneStep;
899 dPtr2 += dPlaneStep;
900
901 }
902
903 sPtr1 += sColStep;
904 dPtr1 += dColStep;
905
906 }
907
908 sPtr += sRowStep;
909 dPtr += dRowStep;
910
911 }
912
913 }
914
915/*****************************************************************************/
916
917void RefRepeatArea8 (const uint8 *sPtr,
918 uint8 *dPtr,
919 uint32 rows,
920 uint32 cols,
921 uint32 planes,
922 int32 rowStep,
923 int32 colStep,
924 int32 planeStep,
925 uint32 repeatV,
926 uint32 repeatH,
927 uint32 phaseV,
928 uint32 phaseH)
929 {
930
931 const uint8 *sPtr0 = sPtr + phaseV * rowStep +
932 phaseH * colStep;
933
934 int32 backStepV = (repeatV - 1) * rowStep;
935 int32 backStepH = (repeatH - 1) * colStep;
936
937 for (uint32 row = 0; row < rows; row++)
938 {
939
940 const uint8 *sPtr1 = sPtr0;
941 uint8 *dPtr1 = dPtr;
942
943 uint32 colPhase = phaseH;
944
945 for (uint32 col = 0; col < cols; col++)
946 {
947
948 const uint8 *sPtr2 = sPtr1;
949 uint8 *dPtr2 = dPtr1;
950
951 for (uint32 plane = 0; plane < planes; plane++)
952 {
953
954 *dPtr2 = *sPtr2;
955
956 sPtr2 += planeStep;
957 dPtr2 += planeStep;
958
959 }
960
961 if (++colPhase == repeatH)
962 {
963 colPhase = 0;
964 sPtr1 -= backStepH;
965 }
966 else
967 {
968 sPtr1 += colStep;
969 }
970
971 dPtr1 += colStep;
972
973 }
974
975 if (++phaseV == repeatV)
976 {
977 phaseV = 0;
978 sPtr0 -= backStepV;
979 }
980 else
981 {
982 sPtr0 += rowStep;
983 }
984
985 dPtr += rowStep;
986
987 }
988
989 }
990
991/*****************************************************************************/
992
993void RefRepeatArea16 (const uint16 *sPtr,
994 uint16 *dPtr,
995 uint32 rows,
996 uint32 cols,
997 uint32 planes,
998 int32 rowStep,
999 int32 colStep,
1000 int32 planeStep,
1001 uint32 repeatV,
1002 uint32 repeatH,
1003 uint32 phaseV,
1004 uint32 phaseH)
1005 {
1006
1007 const uint16 *sPtr0 = sPtr + phaseV * rowStep +
1008 phaseH * colStep;
1009
1010 int32 backStepV = (repeatV - 1) * rowStep;
1011 int32 backStepH = (repeatH - 1) * colStep;
1012
1013 for (uint32 row = 0; row < rows; row++)
1014 {
1015
1016 const uint16 *sPtr1 = sPtr0;
1017 uint16 *dPtr1 = dPtr;
1018
1019 uint32 colPhase = phaseH;
1020
1021 for (uint32 col = 0; col < cols; col++)
1022 {
1023
1024 const uint16 *sPtr2 = sPtr1;
1025 uint16 *dPtr2 = dPtr1;
1026
1027 for (uint32 plane = 0; plane < planes; plane++)
1028 {
1029
1030 *dPtr2 = *sPtr2;
1031
1032 sPtr2 += planeStep;
1033 dPtr2 += planeStep;
1034
1035 }
1036
1037 if (++colPhase == repeatH)
1038 {
1039 colPhase = 0;
1040 sPtr1 -= backStepH;
1041 }
1042 else
1043 {
1044 sPtr1 += colStep;
1045 }
1046
1047 dPtr1 += colStep;
1048
1049 }
1050
1051 if (++phaseV == repeatV)
1052 {
1053 phaseV = 0;
1054 sPtr0 -= backStepV;
1055 }
1056 else
1057 {
1058 sPtr0 += rowStep;
1059 }
1060
1061 dPtr += rowStep;
1062
1063 }
1064
1065 }
1066
1067/*****************************************************************************/
1068
1069void RefRepeatArea32 (const uint32 *sPtr,
1070 uint32 *dPtr,
1071 uint32 rows,
1072 uint32 cols,
1073 uint32 planes,
1074 int32 rowStep,
1075 int32 colStep,
1076 int32 planeStep,
1077 uint32 repeatV,
1078 uint32 repeatH,
1079 uint32 phaseV,
1080 uint32 phaseH)
1081 {
1082
1083 const uint32 *sPtr0 = sPtr + phaseV * rowStep +
1084 phaseH * colStep;
1085
1086 int32 backStepV = (repeatV - 1) * rowStep;
1087 int32 backStepH = (repeatH - 1) * colStep;
1088
1089 for (uint32 row = 0; row < rows; row++)
1090 {
1091
1092 const uint32 *sPtr1 = sPtr0;
1093 uint32 *dPtr1 = dPtr;
1094
1095 uint32 colPhase = phaseH;
1096
1097 for (uint32 col = 0; col < cols; col++)
1098 {
1099
1100 const uint32 *sPtr2 = sPtr1;
1101 uint32 *dPtr2 = dPtr1;
1102
1103 for (uint32 plane = 0; plane < planes; plane++)
1104 {
1105
1106 *dPtr2 = *sPtr2;
1107
1108 sPtr2 += planeStep;
1109 dPtr2 += planeStep;
1110
1111 }
1112
1113 if (++colPhase == repeatH)
1114 {
1115 colPhase = 0;
1116 sPtr1 -= backStepH;
1117 }
1118 else
1119 {
1120 sPtr1 += colStep;
1121 }
1122
1123 dPtr1 += colStep;
1124
1125 }
1126
1127 if (++phaseV == repeatV)
1128 {
1129 phaseV = 0;
1130 sPtr0 -= backStepV;
1131 }
1132 else
1133 {
1134 sPtr0 += rowStep;
1135 }
1136
1137 dPtr += rowStep;
1138
1139 }
1140
1141 }
1142
1143/*****************************************************************************/
1144
1145void RefShiftRight16 (uint16 *dPtr,
1146 uint32 rows,
1147 uint32 cols,
1148 uint32 planes,
1149 int32 rowStep,
1150 int32 colStep,
1151 int32 planeStep,
1152 uint32 shift)
1153 {
1154
1155 for (uint32 row = 0; row < rows; row++)
1156 {
1157
1158 uint16 *dPtr1 = dPtr;
1159
1160 for (uint32 col = 0; col < cols; col++)
1161 {
1162
1163 uint16 *dPtr2 = dPtr1;
1164
1165 for (uint32 plane = 0; plane < planes; plane++)
1166 {
1167
1168 *dPtr2 >>= shift;
1169
1170 dPtr2 += planeStep;
1171
1172 }
1173
1174 dPtr1 += colStep;
1175
1176 }
1177
1178 dPtr += rowStep;
1179
1180 }
1181
1182 }
1183
1184/*****************************************************************************/
1185
1186void RefBilinearRow16 (const uint16 *sPtr,
1187 uint16 *dPtr,
1188 uint32 cols,
1189 uint32 patPhase,
1190 uint32 patCount,
1191 const uint32 * kernCounts,
1192 const int32 * const * kernOffsets,
1193 const uint16 * const * kernWeights,
1194 uint32 sShift)
1195 {
1196
1197 for (uint32 j = 0; j < cols; j++)
1198 {
1199
1200 const uint16 *p = sPtr + (j >> sShift);
1201
1202 uint32 count = kernCounts [patPhase];
1203
1204 const int32 *offsets = kernOffsets [patPhase];
1205 const uint16 *weights = kernWeights [patPhase];
1206
1207 if (++patPhase == patCount)
1208 {
1209 patPhase = 0;
1210 }
1211
1212 uint32 total = 128;
1213
1214 for (uint32 k = 0; k < count; k++)
1215 {
1216
1217 int32 offset = offsets [k];
1218 uint32 weight = weights [k];
1219
1220 uint32 pixel = p [offset];
1221
1222 total += pixel * weight;
1223
1224 }
1225
1226 dPtr [j] = (uint16) (total >> 8);
1227
1228 }
1229
1230 }
1231
1232/*****************************************************************************/
1233
1234void RefBilinearRow32 (const real32 *sPtr,
1235 real32 *dPtr,
1236 uint32 cols,
1237 uint32 patPhase,
1238 uint32 patCount,
1239 const uint32 * kernCounts,
1240 const int32 * const * kernOffsets,
1241 const real32 * const * kernWeights,
1242 uint32 sShift)
1243 {
1244
1245 for (uint32 j = 0; j < cols; j++)
1246 {
1247
1248 const real32 *p = sPtr + (j >> sShift);
1249
1250 uint32 count = kernCounts [patPhase];
1251
1252 const int32 *offsets = kernOffsets [patPhase];
1253 const real32 *weights = kernWeights [patPhase];
1254
1255 if (++patPhase == patCount)
1256 {
1257 patPhase = 0;
1258 }
1259
1260 real32 total = 0.0f;
1261
1262 for (uint32 k = 0; k < count; k++)
1263 {
1264
1265 int32 offset = offsets [k];
1266 real32 weight = weights [k];
1267
1268 real32 pixel = p [offset];
1269
1270 total += pixel * weight;
1271
1272 }
1273
1274 dPtr [j] = total;
1275
1276 }
1277
1278 }
1279
1280/*****************************************************************************/
1281
1282void RefBaselineABCtoRGB (const real32 *sPtrA,
1283 const real32 *sPtrB,
1284 const real32 *sPtrC,
1285 real32 *dPtrR,
1286 real32 *dPtrG,
1287 real32 *dPtrB,
1288 uint32 count,
1289 const dng_vector &cameraWhite,
1290 const dng_matrix &cameraToRGB)
1291 {
1292
1293 real32 clipA = (real32) cameraWhite [0];
1294 real32 clipB = (real32) cameraWhite [1];
1295 real32 clipC = (real32) cameraWhite [2];
1296
1297 real32 m00 = (real32) cameraToRGB [0] [0];
1298 real32 m01 = (real32) cameraToRGB [0] [1];
1299 real32 m02 = (real32) cameraToRGB [0] [2];
1300
1301 real32 m10 = (real32) cameraToRGB [1] [0];
1302 real32 m11 = (real32) cameraToRGB [1] [1];
1303 real32 m12 = (real32) cameraToRGB [1] [2];
1304
1305 real32 m20 = (real32) cameraToRGB [2] [0];
1306 real32 m21 = (real32) cameraToRGB [2] [1];
1307 real32 m22 = (real32) cameraToRGB [2] [2];
1308
1309 for (uint32 col = 0; col < count; col++)
1310 {
1311
1312 real32 A = sPtrA [col];
1313 real32 B = sPtrB [col];
1314 real32 C = sPtrC [col];
1315
1316 A = Min_real32 (A, clipA);
1317 B = Min_real32 (B, clipB);
1318 C = Min_real32 (C, clipC);
1319
1320 real32 r = m00 * A + m01 * B + m02 * C;
1321 real32 g = m10 * A + m11 * B + m12 * C;
1322 real32 b = m20 * A + m21 * B + m22 * C;
1323
1324 r = Pin_real32 (0.0f, r, 1.0f);
1325 g = Pin_real32 (0.0f, g, 1.0f);
1326 b = Pin_real32 (0.0f, b, 1.0f);
1327
1328 dPtrR [col] = r;
1329 dPtrG [col] = g;
1330 dPtrB [col] = b;
1331
1332 }
1333
1334 }
1335
1336/*****************************************************************************/
1337
1338void RefBaselineABCDtoRGB (const real32 *sPtrA,
1339 const real32 *sPtrB,
1340 const real32 *sPtrC,
1341 const real32 *sPtrD,
1342 real32 *dPtrR,
1343 real32 *dPtrG,
1344 real32 *dPtrB,
1345 uint32 count,
1346 const dng_vector &cameraWhite,
1347 const dng_matrix &cameraToRGB)
1348 {
1349
1350 real32 clipA = (real32) cameraWhite [0];
1351 real32 clipB = (real32) cameraWhite [1];
1352 real32 clipC = (real32) cameraWhite [2];
1353 real32 clipD = (real32) cameraWhite [3];
1354
1355 real32 m00 = (real32) cameraToRGB [0] [0];
1356 real32 m01 = (real32) cameraToRGB [0] [1];
1357 real32 m02 = (real32) cameraToRGB [0] [2];
1358 real32 m03 = (real32) cameraToRGB [0] [3];
1359
1360 real32 m10 = (real32) cameraToRGB [1] [0];
1361 real32 m11 = (real32) cameraToRGB [1] [1];
1362 real32 m12 = (real32) cameraToRGB [1] [2];
1363 real32 m13 = (real32) cameraToRGB [1] [3];
1364
1365 real32 m20 = (real32) cameraToRGB [2] [0];
1366 real32 m21 = (real32) cameraToRGB [2] [1];
1367 real32 m22 = (real32) cameraToRGB [2] [2];
1368 real32 m23 = (real32) cameraToRGB [2] [3];
1369
1370 for (uint32 col = 0; col < count; col++)
1371 {
1372
1373 real32 A = sPtrA [col];
1374 real32 B = sPtrB [col];
1375 real32 C = sPtrC [col];
1376 real32 D = sPtrD [col];
1377
1378 A = Min_real32 (A, clipA);
1379 B = Min_real32 (B, clipB);
1380 C = Min_real32 (C, clipC);
1381 D = Min_real32 (D, clipD);
1382
1383 real32 r = m00 * A + m01 * B + m02 * C + m03 * D;
1384 real32 g = m10 * A + m11 * B + m12 * C + m13 * D;
1385 real32 b = m20 * A + m21 * B + m22 * C + m23 * D;
1386
1387 r = Pin_real32 (0.0f, r, 1.0f);
1388 g = Pin_real32 (0.0f, g, 1.0f);
1389 b = Pin_real32 (0.0f, b, 1.0f);
1390
1391 dPtrR [col] = r;
1392 dPtrG [col] = g;
1393 dPtrB [col] = b;
1394
1395 }
1396
1397 }
1398
1399/*****************************************************************************/
1400
1401void RefBaselineHueSatMap (const real32 *sPtrR,
1402 const real32 *sPtrG,
1403 const real32 *sPtrB,
1404 real32 *dPtrR,
1405 real32 *dPtrG,
1406 real32 *dPtrB,
1407 uint32 count,
1408 const dng_hue_sat_map &lut,
1409 const dng_1d_table *encodeTable,
1410 const dng_1d_table *decodeTable)
1411 {
1412
1413 uint32 hueDivisions;
1414 uint32 satDivisions;
1415 uint32 valDivisions;
1416
1417 lut.GetDivisions (hueDivisions,
1418 satDivisions,
1419 valDivisions);
1420
1421 real32 hScale = (hueDivisions < 2) ? 0.0f : (hueDivisions * (1.0f / 6.0f));
1422 real32 sScale = (real32) ((int32) satDivisions - 1);
1423 real32 vScale = (real32) ((int32) valDivisions - 1);
1424
1425 int32 maxHueIndex0 = (int32) hueDivisions - 1;
1426 int32 maxSatIndex0 = (int32) satDivisions - 2;
1427 int32 maxValIndex0 = (int32) valDivisions - 2;
1428
1429 const bool hasEncodeTable = ((encodeTable != NULL) && (encodeTable->Table () != NULL));
1430 const bool hasDecodeTable = ((decodeTable != NULL) && (decodeTable->Table () != NULL));
1431
1432 const bool hasTable = hasEncodeTable && hasDecodeTable;
1433
1434 const dng_hue_sat_map::HSBModify *tableBase = lut.GetConstDeltas ();
1435
1436 int32 hueStep = satDivisions;
1437 int32 valStep = hueDivisions * hueStep;
1438
1439 #if 0 // Not required with "2.5D" table optimization.
1440
1441 if (valDivisions < 2)
1442 {
1443 valStep = 0;
1444 maxValIndex0 = 0;
1445 }
1446
1447 #endif
1448
1449 for (uint32 j = 0; j < count; j++)
1450 {
1451
1452 real32 r = sPtrR [j];
1453 real32 g = sPtrG [j];
1454 real32 b = sPtrB [j];
1455
1456 real32 h, s, v;
1457
1458 DNG_RGBtoHSV (r, g, b, h, s, v);
1459
1460 real32 vEncoded = v;
1461
1462 real32 hueShift;
1463 real32 satScale;
1464 real32 valScale;
1465
1466 if (valDivisions < 2) // Optimize most common case of "2.5D" table.
1467 {
1468
1469 real32 hScaled = h * hScale;
1470 real32 sScaled = s * sScale;
1471
1472 int32 hIndex0 = (int32) hScaled;
1473 int32 sIndex0 = (int32) sScaled;
1474
1475 sIndex0 = Min_int32 (sIndex0, maxSatIndex0);
1476
1477 int32 hIndex1 = hIndex0 + 1;
1478
1479 if (hIndex0 >= maxHueIndex0)
1480 {
1481 hIndex0 = maxHueIndex0;
1482 hIndex1 = 0;
1483 }
1484
1485 real32 hFract1 = hScaled - (real32) hIndex0;
1486 real32 sFract1 = sScaled - (real32) sIndex0;
1487
1488 real32 hFract0 = 1.0f - hFract1;
1489 real32 sFract0 = 1.0f - sFract1;
1490
1491 const dng_hue_sat_map::HSBModify *entry00 = tableBase + hIndex0 * hueStep +
1492 sIndex0;
1493
1494 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep;
1495
1496 real32 hueShift0 = hFract0 * entry00->fHueShift +
1497 hFract1 * entry01->fHueShift;
1498
1499 real32 satScale0 = hFract0 * entry00->fSatScale +
1500 hFract1 * entry01->fSatScale;
1501
1502 real32 valScale0 = hFract0 * entry00->fValScale +
1503 hFract1 * entry01->fValScale;
1504
1505 entry00++;
1506 entry01++;
1507
1508 real32 hueShift1 = hFract0 * entry00->fHueShift +
1509 hFract1 * entry01->fHueShift;
1510
1511 real32 satScale1 = hFract0 * entry00->fSatScale +
1512 hFract1 * entry01->fSatScale;
1513
1514 real32 valScale1 = hFract0 * entry00->fValScale +
1515 hFract1 * entry01->fValScale;
1516
1517 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1;
1518 satScale = sFract0 * satScale0 + sFract1 * satScale1;
1519 valScale = sFract0 * valScale0 + sFract1 * valScale1;
1520
1521 }
1522
1523 else
1524 {
1525
1526 if (hasTable)
1527 {
1528 vEncoded = encodeTable->Interpolate (Pin_real32 (v));
1529 }
1530
1531 real32 hScaled = h * hScale;
1532 real32 sScaled = s * sScale;
1533 real32 vScaled = vEncoded * vScale;
1534
1535 int32 hIndex0 = (int32) hScaled;
1536 int32 sIndex0 = (int32) sScaled;
1537 int32 vIndex0 = (int32) vScaled;
1538
1539 sIndex0 = Min_int32 (sIndex0, maxSatIndex0);
1540 vIndex0 = Min_int32 (vIndex0, maxValIndex0);
1541
1542 int32 hIndex1 = hIndex0 + 1;
1543
1544 if (hIndex0 >= maxHueIndex0)
1545 {
1546 hIndex0 = maxHueIndex0;
1547 hIndex1 = 0;
1548 }
1549
1550 real32 hFract1 = hScaled - (real32) hIndex0;
1551 real32 sFract1 = sScaled - (real32) sIndex0;
1552 real32 vFract1 = vScaled - (real32) vIndex0;
1553
1554 real32 hFract0 = 1.0f - hFract1;
1555 real32 sFract0 = 1.0f - sFract1;
1556 real32 vFract0 = 1.0f - vFract1;
1557
1558 const dng_hue_sat_map::HSBModify *entry00 = tableBase + vIndex0 * valStep +
1559 hIndex0 * hueStep +
1560 sIndex0;
1561
1562 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep;
1563
1564 const dng_hue_sat_map::HSBModify *entry10 = entry00 + valStep;
1565 const dng_hue_sat_map::HSBModify *entry11 = entry01 + valStep;
1566
1567 real32 hueShift0 = vFract0 * (hFract0 * entry00->fHueShift +
1568 hFract1 * entry01->fHueShift) +
1569 vFract1 * (hFract0 * entry10->fHueShift +
1570 hFract1 * entry11->fHueShift);
1571
1572 real32 satScale0 = vFract0 * (hFract0 * entry00->fSatScale +
1573 hFract1 * entry01->fSatScale) +
1574 vFract1 * (hFract0 * entry10->fSatScale +
1575 hFract1 * entry11->fSatScale);
1576
1577 real32 valScale0 = vFract0 * (hFract0 * entry00->fValScale +
1578 hFract1 * entry01->fValScale) +
1579 vFract1 * (hFract0 * entry10->fValScale +
1580 hFract1 * entry11->fValScale);
1581
1582 entry00++;
1583 entry01++;
1584 entry10++;
1585 entry11++;
1586
1587 real32 hueShift1 = vFract0 * (hFract0 * entry00->fHueShift +
1588 hFract1 * entry01->fHueShift) +
1589 vFract1 * (hFract0 * entry10->fHueShift +
1590 hFract1 * entry11->fHueShift);
1591
1592 real32 satScale1 = vFract0 * (hFract0 * entry00->fSatScale +
1593 hFract1 * entry01->fSatScale) +
1594 vFract1 * (hFract0 * entry10->fSatScale +
1595 hFract1 * entry11->fSatScale);
1596
1597 real32 valScale1 = vFract0 * (hFract0 * entry00->fValScale +
1598 hFract1 * entry01->fValScale) +
1599 vFract1 * (hFract0 * entry10->fValScale +
1600 hFract1 * entry11->fValScale);
1601
1602 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1;
1603 satScale = sFract0 * satScale0 + sFract1 * satScale1;
1604 valScale = sFract0 * valScale0 + sFract1 * valScale1;
1605
1606 }
1607
1608 hueShift *= (6.0f / 360.0f); // Convert to internal hue range.
1609
1610 h += hueShift;
1611
1612 s = Min_real32 (s * satScale, 1.0f);
1613
1614 vEncoded = Pin_real32 (vEncoded * valScale);
1615
1616 v = hasTable ? decodeTable->Interpolate (vEncoded) : vEncoded;
1617
1618 DNG_HSVtoRGB (h, s, v, r, g, b);
1619
1620 dPtrR [j] = r;
1621 dPtrG [j] = g;
1622 dPtrB [j] = b;
1623
1624 }
1625
1626 }
1627
1628/*****************************************************************************/
1629
1630void RefBaselineRGBtoGray (const real32 *sPtrR,
1631 const real32 *sPtrG,
1632 const real32 *sPtrB,
1633 real32 *dPtrG,
1634 uint32 count,
1635 const dng_matrix &matrix)
1636 {
1637
1638 real32 m00 = (real32) matrix [0] [0];
1639 real32 m01 = (real32) matrix [0] [1];
1640 real32 m02 = (real32) matrix [0] [2];
1641
1642 for (uint32 col = 0; col < count; col++)
1643 {
1644
1645 real32 R = sPtrR [col];
1646 real32 G = sPtrG [col];
1647 real32 B = sPtrB [col];
1648
1649 real32 g = m00 * R + m01 * G + m02 * B;
1650
1651 g = Pin_real32 (0.0f, g, 1.0f);
1652
1653 dPtrG [col] = g;
1654
1655 }
1656
1657 }
1658
1659/*****************************************************************************/
1660
1661void RefBaselineRGBtoRGB (const real32 *sPtrR,
1662 const real32 *sPtrG,
1663 const real32 *sPtrB,
1664 real32 *dPtrR,
1665 real32 *dPtrG,
1666 real32 *dPtrB,
1667 uint32 count,
1668 const dng_matrix &matrix)
1669 {
1670
1671 real32 m00 = (real32) matrix [0] [0];
1672 real32 m01 = (real32) matrix [0] [1];
1673 real32 m02 = (real32) matrix [0] [2];
1674
1675 real32 m10 = (real32) matrix [1] [0];
1676 real32 m11 = (real32) matrix [1] [1];
1677 real32 m12 = (real32) matrix [1] [2];
1678
1679 real32 m20 = (real32) matrix [2] [0];
1680 real32 m21 = (real32) matrix [2] [1];
1681 real32 m22 = (real32) matrix [2] [2];
1682
1683 for (uint32 col = 0; col < count; col++)
1684 {
1685
1686 real32 R = sPtrR [col];
1687 real32 G = sPtrG [col];
1688 real32 B = sPtrB [col];
1689
1690 real32 r = m00 * R + m01 * G + m02 * B;
1691 real32 g = m10 * R + m11 * G + m12 * B;
1692 real32 b = m20 * R + m21 * G + m22 * B;
1693
1694 r = Pin_real32 (0.0f, r, 1.0f);
1695 g = Pin_real32 (0.0f, g, 1.0f);
1696 b = Pin_real32 (0.0f, b, 1.0f);
1697
1698 dPtrR [col] = r;
1699 dPtrG [col] = g;
1700 dPtrB [col] = b;
1701
1702 }
1703
1704 }
1705
1706/*****************************************************************************/
1707
1708void RefBaseline1DTable (const real32 *sPtr,
1709 real32 *dPtr,
1710 uint32 count,
1711 const dng_1d_table &table)
1712 {
1713
1714 for (uint32 col = 0; col < count; col++)
1715 {
1716
1717 real32 x = sPtr [col];
1718
1719 real32 y = table.Interpolate (x);
1720
1721 dPtr [col] = y;
1722
1723 }
1724
1725 }
1726
1727/*****************************************************************************/
1728
1729void RefBaselineRGBTone (const real32 *sPtrR,
1730 const real32 *sPtrG,
1731 const real32 *sPtrB,
1732 real32 *dPtrR,
1733 real32 *dPtrG,
1734 real32 *dPtrB,
1735 uint32 count,
1736 const dng_1d_table &table)
1737 {
1738
1739 for (uint32 col = 0; col < count; col++)
1740 {
1741
1742 real32 r = sPtrR [col];
1743 real32 g = sPtrG [col];
1744 real32 b = sPtrB [col];
1745
1746 real32 rr;
1747 real32 gg;
1748 real32 bb;
1749
1750 #define RGBTone(r, g, b, rr, gg, bb)\
1751 {\
1752 \
1753 DNG_ASSERT (r >= g && g >= b && r > b, "Logic Error RGBTone");\
1754 \
1755 rr = table.Interpolate (r);\
1756 bb = table.Interpolate (b);\
1757 \
1758 gg = bb + ((rr - bb) * (g - b) / (r - b));\
1759 \
1760 }
1761
1762 if (r >= g)
1763 {
1764
1765 if (g > b)
1766 {
1767
1768 // Case 1: r >= g > b
1769
1770 RGBTone (r, g, b, rr, gg, bb);
1771
1772 }
1773
1774 else if (b > r)
1775 {
1776
1777 // Case 2: b > r >= g
1778
1779 RGBTone (b, r, g, bb, rr, gg);
1780
1781 }
1782
1783 else if (b > g)
1784 {
1785
1786 // Case 3: r >= b > g
1787
1788 RGBTone (r, b, g, rr, bb, gg);
1789
1790 }
1791
1792 else
1793 {
1794
1795 // Case 4: r >= g == b
1796
1797 DNG_ASSERT (r >= g && g == b, "Logic Error 2");
1798
1799 rr = table.Interpolate (r);
1800 gg = table.Interpolate (g);
1801 bb = gg;
1802
1803 }
1804
1805 }
1806
1807 else
1808 {
1809
1810 if (r >= b)
1811 {
1812
1813 // Case 5: g > r >= b
1814
1815 RGBTone (g, r, b, gg, rr, bb);
1816
1817 }
1818
1819 else if (b > g)
1820 {
1821
1822 // Case 6: b > g > r
1823
1824 RGBTone (b, g, r, bb, gg, rr);
1825
1826 }
1827
1828 else
1829 {
1830
1831 // Case 7: g >= b > r
1832
1833 RGBTone (g, b, r, gg, bb, rr);
1834
1835 }
1836
1837 }
1838
1839 #undef RGBTone
1840
1841 dPtrR [col] = rr;
1842 dPtrG [col] = gg;
1843 dPtrB [col] = bb;
1844
1845 }
1846
1847 }
1848
1849/*****************************************************************************/
1850
1851void RefResampleDown16 (const uint16 *sPtr,
1852 uint16 *dPtr,
1853 uint32 sCount,
1854 int32 sRowStep,
1855 const int16 *wPtr,
1856 uint32 wCount,
1857 uint32 pixelRange)
1858 {
1859
1860 for (uint32 j = 0; j < sCount; j++)
1861 {
1862
1863 int32 total = 8192;
1864
1865 const uint16 *s = sPtr + j;
1866
1867 for (uint32 k = 0; k < wCount; k++)
1868 {
1869
1870 total += wPtr [k] * (int32) s [0];
1871
1872 s += sRowStep;
1873
1874 }
1875
1876 dPtr [j] = (uint16) Pin_int32 (0,
1877 total >> 14,
1878 pixelRange);
1879
1880 }
1881
1882 }
1883
1884/*****************************************************************************/
1885
1886void RefResampleDown32 (const real32 *sPtr,
1887 real32 *dPtr,
1888 uint32 sCount,
1889 int32 sRowStep,
1890 const real32 *wPtr,
1891 uint32 wCount)
1892 {
1893
1894 uint32 col;
1895
1896 // Process first row.
1897
1898 real32 w = wPtr [0];
1899
1900 for (col = 0; col < sCount; col++)
1901 {
1902
1903 dPtr [col] = w * sPtr [col];
1904
1905 }
1906
1907 sPtr += sRowStep;
1908
1909 // Process middle rows.
1910
1911 for (uint32 j = 1; j < wCount - 1; j++)
1912 {
1913
1914 w = wPtr [j];
1915
1916 for (col = 0; col < sCount; col++)
1917 {
1918
1919 dPtr [col] += w * sPtr [col];
1920
1921 }
1922
1923 sPtr += sRowStep;
1924
1925 }
1926
1927 // Process last row.
1928
1929 w = wPtr [wCount - 1];
1930
1931 for (col = 0; col < sCount; col++)
1932 {
1933
1934 dPtr [col] = Pin_real32 (0.0f,
1935 dPtr [col] + w * sPtr [col],
1936 1.0f);
1937
1938 }
1939
1940 }
1941
1942/******************************************************************************/
1943
1944void RefResampleAcross16 (const uint16 *sPtr,
1945 uint16 *dPtr,
1946 uint32 dCount,
1947 const int32 *coord,
1948 const int16 *wPtr,
1949 uint32 wCount,
1950 uint32 wStep,
1951 uint32 pixelRange)
1952 {
1953
1954 for (uint32 j = 0; j < dCount; j++)
1955 {
1956
1957 int32 sCoord = coord [j];
1958
1959 int32 sFract = sCoord & kResampleSubsampleMask;
1960 int32 sPixel = sCoord >> kResampleSubsampleBits;
1961
1962 const int16 *w = wPtr + sFract * wStep;
1963 const uint16 *s = sPtr + sPixel;
1964
1965 int32 total = w [0] * (int32) s [0];
1966
1967 for (uint32 k = 1; k < wCount; k++)
1968 {
1969
1970 total += w [k] * (int32) s [k];
1971
1972 }
1973
1974 dPtr [j] = (uint16) Pin_int32 (0,
1975 (total + 8192) >> 14,
1976 pixelRange);
1977
1978 }
1979
1980 }
1981
1982/******************************************************************************/
1983
1984void RefResampleAcross32 (const real32 *sPtr,
1985 real32 *dPtr,
1986 uint32 dCount,
1987 const int32 *coord,
1988 const real32 *wPtr,
1989 uint32 wCount,
1990 uint32 wStep)
1991 {
1992
1993 for (uint32 j = 0; j < dCount; j++)
1994 {
1995
1996 int32 sCoord = coord [j];
1997
1998 int32 sFract = sCoord & kResampleSubsampleMask;
1999 int32 sPixel = sCoord >> kResampleSubsampleBits;
2000
2001 const real32 *w = wPtr + sFract * wStep;
2002 const real32 *s = sPtr + sPixel;
2003
2004 real32 total = w [0] * s [0];
2005
2006 for (uint32 k = 1; k < wCount; k++)
2007 {
2008
2009 total += w [k] * s [k];
2010
2011 }
2012
2013 dPtr [j] = Pin_real32 (0.0f, total, 1.0f);
2014
2015 }
2016
2017 }
2018
2019/*****************************************************************************/
2020
2021bool RefEqualBytes (const void *sPtr,
2022 const void *dPtr,
2023 uint32 count)
2024 {
2025
2026 return memcmp (dPtr, sPtr, count) == 0;
2027
2028 }
2029
2030/*****************************************************************************/
2031
2032bool RefEqualArea8 (const uint8 *sPtr,
2033 const uint8 *dPtr,
2034 uint32 rows,
2035 uint32 cols,
2036 uint32 planes,
2037 int32 sRowStep,
2038 int32 sColStep,
2039 int32 sPlaneStep,
2040 int32 dRowStep,
2041 int32 dColStep,
2042 int32 dPlaneStep)
2043 {
2044
2045 for (uint32 row = 0; row < rows; row++)
2046 {
2047
2048 const uint8 *sPtr1 = sPtr;
2049 const uint8 *dPtr1 = dPtr;
2050
2051 for (uint32 col = 0; col < cols; col++)
2052 {
2053
2054 const uint8 *sPtr2 = sPtr1;
2055 const uint8 *dPtr2 = dPtr1;
2056
2057 for (uint32 plane = 0; plane < planes; plane++)
2058 {
2059
2060 if (*dPtr2 != *sPtr2)
2061 return false;
2062
2063 sPtr2 += sPlaneStep;
2064 dPtr2 += dPlaneStep;
2065
2066 }
2067
2068 sPtr1 += sColStep;
2069 dPtr1 += dColStep;
2070
2071 }
2072
2073 sPtr += sRowStep;
2074 dPtr += dRowStep;
2075
2076 }
2077
2078 return true;
2079
2080 }
2081
2082/*****************************************************************************/
2083
2084bool RefEqualArea16 (const uint16 *sPtr,
2085 const uint16 *dPtr,
2086 uint32 rows,
2087 uint32 cols,
2088 uint32 planes,
2089 int32 sRowStep,
2090 int32 sColStep,
2091 int32 sPlaneStep,
2092 int32 dRowStep,
2093 int32 dColStep,
2094 int32 dPlaneStep)
2095 {
2096
2097 for (uint32 row = 0; row < rows; row++)
2098 {
2099
2100 const uint16 *sPtr1 = sPtr;
2101 const uint16 *dPtr1 = dPtr;
2102
2103 for (uint32 col = 0; col < cols; col++)
2104 {
2105
2106 const uint16 *sPtr2 = sPtr1;
2107 const uint16 *dPtr2 = dPtr1;
2108
2109 for (uint32 plane = 0; plane < planes; plane++)
2110 {
2111
2112 if (*dPtr2 != *sPtr2)
2113 return false;
2114
2115 sPtr2 += sPlaneStep;
2116 dPtr2 += dPlaneStep;
2117
2118 }
2119
2120 sPtr1 += sColStep;
2121 dPtr1 += dColStep;
2122
2123 }
2124
2125 sPtr += sRowStep;
2126 dPtr += dRowStep;
2127
2128 }
2129
2130 return true;
2131
2132 }
2133
2134/*****************************************************************************/
2135
2136bool RefEqualArea32 (const uint32 *sPtr,
2137 const uint32 *dPtr,
2138 uint32 rows,
2139 uint32 cols,
2140 uint32 planes,
2141 int32 sRowStep,
2142 int32 sColStep,
2143 int32 sPlaneStep,
2144 int32 dRowStep,
2145 int32 dColStep,
2146 int32 dPlaneStep)
2147 {
2148
2149 for (uint32 row = 0; row < rows; row++)
2150 {
2151
2152 const uint32 *sPtr1 = sPtr;
2153 const uint32 *dPtr1 = dPtr;
2154
2155 for (uint32 col = 0; col < cols; col++)
2156 {
2157
2158 const uint32 *sPtr2 = sPtr1;
2159 const uint32 *dPtr2 = dPtr1;
2160
2161 for (uint32 plane = 0; plane < planes; plane++)
2162 {
2163
2164 if (*dPtr2 != *sPtr2)
2165 return false;
2166
2167 sPtr2 += sPlaneStep;
2168 dPtr2 += dPlaneStep;
2169
2170 }
2171
2172 sPtr1 += sColStep;
2173 dPtr1 += dColStep;
2174
2175 }
2176
2177 sPtr += sRowStep;
2178 dPtr += dRowStep;
2179
2180 }
2181
2182 return true;
2183
2184 }
2185
2186/*****************************************************************************/
2187
2188void RefVignetteMask16 (uint16 *mPtr,
2189 uint32 rows,
2190 uint32 cols,
2191 int32 rowStep,
2192 int64 offsetH,
2193 int64 offsetV,
2194 int64 stepH,
2195 int64 stepV,
2196 uint32 tBits,
2197 const uint16 *table)
2198 {
2199
2200 uint32 tShift = 32 - tBits;
2201 uint32 tRound = (1 << (tShift - 1));
2202 uint32 tLimit = 1 << tBits;
2203
2204 for (uint32 row = 0; row < rows; row++)
2205 {
2206
2207 int64 baseDelta = (offsetV + 32768) >> 16;
2208
2209 baseDelta = baseDelta * baseDelta + tRound;
2210
2211 int64 deltaH = offsetH + 32768;
2212
2213 for (uint32 col = 0; col < cols; col++)
2214 {
2215
2216 int64 temp = deltaH >> 16;
2217
2218 int64 delta = baseDelta + (temp * temp);
2219
2220 uint32 index = Min_uint32 ((uint32) (delta >> tShift), tLimit);
2221
2222 mPtr [col] = table [index];
2223
2224 deltaH += stepH;
2225
2226 }
2227
2228 offsetV += stepV;
2229
2230 mPtr += rowStep;
2231
2232 }
2233
2234 }
2235
2236/*****************************************************************************/
2237
2238void RefVignette16 (int16 *sPtr,
2239 const uint16 *mPtr,
2240 uint32 rows,
2241 uint32 cols,
2242 uint32 planes,
2243 int32 sRowStep,
2244 int32 sPlaneStep,
2245 int32 mRowStep,
2246 uint32 mBits)
2247 {
2248
2249 const uint32 mRound = 1 << (mBits - 1);
2250
2251 switch (planes)
2252 {
2253
2254 case 1:
2255 {
2256
2257 for (uint32 row = 0; row < rows; row++)
2258 {
2259
2260 for (uint32 col = 0; col < cols; col++)
2261 {
2262
2263 uint32 s = sPtr [col] + 32768;
2264
2265 uint32 m = mPtr [col];
2266
2267 s = (s * m + mRound) >> mBits;
2268
2269 s = Min_uint32 (s, 65535);
2270
2271 sPtr [col] = (int16) (s - 32768);
2272
2273 }
2274
2275 sPtr += sRowStep;
2276
2277 mPtr += mRowStep;
2278
2279 }
2280
2281 break;
2282
2283 }
2284
2285 case 3:
2286 {
2287
2288 int16 *rPtr = sPtr;
2289 int16 *gPtr = rPtr + sPlaneStep;
2290 int16 *bPtr = gPtr + sPlaneStep;
2291
2292 for (uint32 row = 0; row < rows; row++)
2293 {
2294
2295 for (uint32 col = 0; col < cols; col++)
2296 {
2297
2298 uint32 r = rPtr [col] + 32768;
2299 uint32 g = gPtr [col] + 32768;
2300 uint32 b = bPtr [col] + 32768;
2301
2302 uint32 m = mPtr [col];
2303
2304 r = (r * m + mRound) >> mBits;
2305 g = (g * m + mRound) >> mBits;
2306 b = (b * m + mRound) >> mBits;
2307
2308 r = Min_uint32 (r, 65535);
2309 g = Min_uint32 (g, 65535);
2310 b = Min_uint32 (b, 65535);
2311
2312 rPtr [col] = (int16) (r - 32768);
2313 gPtr [col] = (int16) (g - 32768);
2314 bPtr [col] = (int16) (b - 32768);
2315
2316 }
2317
2318 rPtr += sRowStep;
2319 gPtr += sRowStep;
2320 bPtr += sRowStep;
2321
2322 mPtr += mRowStep;
2323
2324 }
2325
2326 break;
2327
2328 }
2329
2330 case 4:
2331 {
2332
2333 int16 *aPtr = sPtr;
2334 int16 *bPtr = aPtr + sPlaneStep;
2335 int16 *cPtr = bPtr + sPlaneStep;
2336 int16 *dPtr = cPtr + sPlaneStep;
2337
2338 for (uint32 row = 0; row < rows; row++)
2339 {
2340
2341 for (uint32 col = 0; col < cols; col++)
2342 {
2343
2344 uint32 a = aPtr [col] + 32768;
2345 uint32 b = bPtr [col] + 32768;
2346 uint32 c = cPtr [col] + 32768;
2347 uint32 d = dPtr [col] + 32768;
2348
2349 uint32 m = mPtr [col];
2350
2351 a = (a * m + mRound) >> mBits;
2352 b = (b * m + mRound) >> mBits;
2353 c = (c * m + mRound) >> mBits;
2354 d = (d * m + mRound) >> mBits;
2355
2356 a = Min_uint32 (a, 65535);
2357 b = Min_uint32 (b, 65535);
2358 c = Min_uint32 (c, 65535);
2359 d = Min_uint32 (d, 65535);
2360
2361 aPtr [col] = (int16) (a - 32768);
2362 bPtr [col] = (int16) (b - 32768);
2363 cPtr [col] = (int16) (c - 32768);
2364 dPtr [col] = (int16) (d - 32768);
2365
2366 }
2367
2368 aPtr += sRowStep;
2369 bPtr += sRowStep;
2370 cPtr += sRowStep;
2371 dPtr += sRowStep;
2372
2373 mPtr += mRowStep;
2374
2375 }
2376
2377 break;
2378
2379 }
2380
2381 default:
2382 {
2383
2384 for (uint32 plane = 0; plane < planes; plane++)
2385 {
2386
2387 int16 *planePtr = sPtr;
2388
2389 const uint16 *maskPtr = mPtr;
2390
2391 for (uint32 row = 0; row < rows; row++)
2392 {
2393
2394 for (uint32 col = 0; col < cols; col++)
2395 {
2396
2397 uint32 s = planePtr [col] + 32768;
2398
2399 uint32 m = maskPtr [col];
2400
2401 s = (s * m + mRound) >> mBits;
2402
2403 s = Min_uint32 (s, 65535);
2404
2405 planePtr [col] = (int16) (s - 32768);
2406
2407 }
2408
2409 planePtr += sRowStep;
2410
2411 maskPtr += mRowStep;
2412
2413 }
2414
2415 sPtr += sPlaneStep;
2416
2417 }
2418
2419 break;
2420
2421 }
2422
2423 }
2424
2425 }
2426
2427/*****************************************************************************/
2428
2429void RefVignette32 (real32 *sPtr,
2430 const uint16 *mPtr,
2431 uint32 rows,
2432 uint32 cols,
2433 uint32 planes,
2434 int32 sRowStep,
2435 int32 sPlaneStep,
2436 int32 mRowStep,
2437 uint32 mBits)
2438 {
2439
2440 const real32 kNorm = 1.0f / (1 << mBits);
2441
2442 switch (planes)
2443 {
2444
2445 case 1:
2446 {
2447
2448 for (uint32 row = 0; row < rows; row++)
2449 {
2450
2451 for (uint32 col = 0; col < cols; col++)
2452 {
2453
2454 real32 s = sPtr [col];
2455
2456 uint16 m = mPtr [col];
2457
2458 real32 scale = m * kNorm;
2459
2460 s = Min_real32 (s * scale, 1.0f);
2461
2462 sPtr [col] = s;
2463
2464 }
2465
2466 sPtr += sRowStep;
2467
2468 mPtr += mRowStep;
2469
2470 }
2471
2472 break;
2473
2474 }
2475
2476 case 3:
2477 {
2478
2479 real32 *rPtr = sPtr;
2480 real32 *gPtr = rPtr + sPlaneStep;
2481 real32 *bPtr = gPtr + sPlaneStep;
2482
2483 for (uint32 row = 0; row < rows; row++)
2484 {
2485
2486 for (uint32 col = 0; col < cols; col++)
2487 {
2488
2489 real32 r = rPtr [col];
2490 real32 g = gPtr [col];
2491 real32 b = bPtr [col];
2492
2493 uint16 m = mPtr [col];
2494
2495 real32 scale = m * kNorm;
2496
2497 r = Min_real32 (r * scale, 1.0f);
2498 g = Min_real32 (g * scale, 1.0f);
2499 b = Min_real32 (b * scale, 1.0f);
2500
2501 rPtr [col] = r;
2502 gPtr [col] = g;
2503 bPtr [col] = b;
2504
2505 }
2506
2507 rPtr += sRowStep;
2508 gPtr += sRowStep;
2509 bPtr += sRowStep;
2510
2511 mPtr += mRowStep;
2512
2513 }
2514
2515 break;
2516
2517 }
2518
2519 case 4:
2520 {
2521
2522 real32 *aPtr = sPtr;
2523 real32 *bPtr = aPtr + sPlaneStep;
2524 real32 *cPtr = bPtr + sPlaneStep;
2525 real32 *dPtr = cPtr + sPlaneStep;
2526
2527 for (uint32 row = 0; row < rows; row++)
2528 {
2529
2530 for (uint32 col = 0; col < cols; col++)
2531 {
2532
2533 real32 a = aPtr [col];
2534 real32 b = bPtr [col];
2535 real32 c = cPtr [col];
2536 real32 d = dPtr [col];
2537
2538 uint16 m = mPtr [col];
2539
2540 real32 scale = m * kNorm;
2541
2542 a = Min_real32 (a * scale, 1.0f);
2543 b = Min_real32 (b * scale, 1.0f);
2544 c = Min_real32 (c * scale, 1.0f);
2545 d = Min_real32 (d * scale, 1.0f);
2546
2547 aPtr [col] = a;
2548 bPtr [col] = b;
2549 cPtr [col] = c;
2550 dPtr [col] = d;
2551
2552 }
2553
2554 aPtr += sRowStep;
2555 bPtr += sRowStep;
2556 cPtr += sRowStep;
2557 dPtr += sRowStep;
2558
2559 mPtr += mRowStep;
2560
2561 }
2562
2563 break;
2564
2565 }
2566
2567 default:
2568 {
2569
2570 for (uint32 plane = 0; plane < planes; plane++)
2571 {
2572
2573 real32 *planePtr = sPtr;
2574
2575 const uint16 *maskPtr = mPtr;
2576
2577 for (uint32 row = 0; row < rows; row++)
2578 {
2579
2580 for (uint32 col = 0; col < cols; col++)
2581 {
2582
2583 real32 s = planePtr [col];
2584
2585 uint16 m = maskPtr [col];
2586
2587 real32 scale = m * kNorm;
2588
2589 s = Min_real32 (s * scale, 1.0f);
2590
2591 planePtr [col] = s;
2592
2593 }
2594
2595 planePtr += sRowStep;
2596
2597 maskPtr += mRowStep;
2598
2599 }
2600
2601 sPtr += sPlaneStep;
2602
2603 }
2604
2605 break;
2606
2607 }
2608
2609 }
2610
2611 }
2612
2613/******************************************************************************/
2614
2615void RefMapArea16 (uint16 *dPtr,
2616 uint32 count0,
2617 uint32 count1,
2618 uint32 count2,
2619 int32 step0,
2620 int32 step1,
2621 int32 step2,
2622 const uint16 *map)
2623 {
2624
2625 if (step2 == 1 && count2 >= 32)
2626 {
2627
2628 for (uint32 index0 = 0; index0 < count0; index0++)
2629 {
2630
2631 uint16 *d1 = dPtr;
2632
2633 for (uint32 index1 = 0; index1 < count1; index1++)
2634 {
2635
2636 uint16 *d2 = d1;
2637
2638 uint32 count = count2;
2639
2640 // Get the data 32-bit aligned if it is not.
2641
2642 if (!IsAligned32 (dPtr))
2643 {
2644
2645 d2 [0] = map [d2 [0]];
2646
2647 count--;
2648
2649 d2++;
2650
2651 }
2652
2653 // Use 32-bit reads and writes for bulk processing.
2654
2655 uint32 *dPtr32 = (uint32 *) d2;
2656
2657 // Process in blocks of 16 pixels.
2658
2659 uint32 blocks = count >> 4;
2660
2661 count -= blocks << 4;
2662 d2 += blocks << 4;
2663
2664 while (blocks--)
2665 {
2666
2667 uint32 x0, x1, x2, x3, x4, x5, x6, x7;
2668 uint32 p0, p1, p2, p3, p4, p5, p6, p7;
2669
2670 // Use 32 bit reads & writes, and pack and unpack the 16-bit values.
2671 // This results in slightly higher performance.
2672
2673 // Note that this code runs on both little-endian and big-endian systems,
2674 // since the pixels are either never swapped or double swapped.
2675
2676 x0 = dPtr32 [0];
2677 x1 = dPtr32 [1];
2678 x2 = dPtr32 [2];
2679 x3 = dPtr32 [3];
2680
2681 p0 = map [x0 >> 16 ];
2682 p1 = map [x0 & 0x0FFFF];
2683 p2 = map [x1 >> 16 ];
2684 p3 = map [x1 & 0x0FFFF];
2685 p4 = map [x2 >> 16 ];
2686 p5 = map [x2 & 0x0FFFF];
2687 p6 = map [x3 >> 16 ];
2688 p7 = map [x3 & 0x0FFFF];
2689
2690 x0 = (p0 << 16) | p1;
2691 x1 = (p2 << 16) | p3;
2692 x2 = (p4 << 16) | p5;
2693 x3 = (p6 << 16) | p7;
2694
2695 x4 = dPtr32 [4];
2696 x5 = dPtr32 [5];
2697 x6 = dPtr32 [6];
2698 x7 = dPtr32 [7];
2699
2700 dPtr32 [0] = x0;
2701 dPtr32 [1] = x1;
2702 dPtr32 [2] = x2;
2703 dPtr32 [3] = x3;
2704
2705 p0 = map [x4 >> 16 ];
2706 p1 = map [x4 & 0x0FFFF];
2707 p2 = map [x5 >> 16 ];
2708 p3 = map [x5 & 0x0FFFF];
2709 p4 = map [x6 >> 16 ];
2710 p5 = map [x6 & 0x0FFFF];
2711 p6 = map [x7 >> 16 ];
2712 p7 = map [x7 & 0x0FFFF];
2713
2714 x4 = (p0 << 16) | p1;
2715 x5 = (p2 << 16) | p3;
2716 x6 = (p4 << 16) | p5;
2717 x7 = (p6 << 16) | p7;
2718
2719 dPtr32 [4] = x4;
2720 dPtr32 [5] = x5;
2721 dPtr32 [6] = x6;
2722 dPtr32 [7] = x7;
2723
2724 dPtr32 += 8;
2725
2726 }
2727
2728 // Process remaining columns.
2729
2730 for (uint32 j = 0; j < count; j++)
2731 {
2732
2733 d2 [j] = map [d2 [j]];
2734
2735 }
2736
2737 d1 += step1;
2738
2739 }
2740
2741 dPtr += step0;
2742
2743 }
2744
2745 }
2746
2747 else
2748 {
2749
2750 for (uint32 index0 = 0; index0 < count0; index0++)
2751 {
2752
2753 uint16 *d1 = dPtr;
2754
2755 for (uint32 index1 = 0; index1 < count1; index1++)
2756 {
2757
2758 uint16 *d2 = d1;
2759
2760 for (uint32 index2 = 0; index2 < count2; index2++)
2761 {
2762
2763 d2 [0] = map [d2 [0]];
2764
2765 d2 += step2;
2766
2767 }
2768
2769 d1 += step1;
2770
2771 }
2772
2773 dPtr += step0;
2774
2775 }
2776
2777 }
2778
2779 }
2780
2781/*****************************************************************************/
2782