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