Home | History | Annotate | Download | only in source
      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 
     33 void RefZeroBytes (void *dPtr,
     34 				   uint32 count)
     35 	{
     36 
     37 	memset (dPtr, 0, count);
     38 
     39 	}
     40 
     41 /*****************************************************************************/
     42 
     43 void RefCopyBytes (const void *sPtr,
     44 				   void *dPtr,
     45 				   uint32 count)
     46 	{
     47 
     48 	memcpy (dPtr, sPtr, count);
     49 
     50 	}
     51 
     52 /*****************************************************************************/
     53 
     54 void 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 
     69 void 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 
     84 void 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 
    125 void 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 
    166 void 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 
    207 void 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 
    256 void 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 
    305 void 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 
    354 void 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 
    403 void 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 
    454 void 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 
    503 void 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 
    552 void 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 
    601 void 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 
    653 void 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 
    705 void 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 
    759 void 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 
    811 void 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 
    863 void 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 
    917 void 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 
    993 void 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 
   1069 void 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 
   1145 void 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 
   1186 void 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 
   1234 void 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 
   1282 void 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 
   1338 void 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 
   1401 void 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 
   1630 void 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 
   1661 void 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 
   1708 void 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 
   1729 void 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 
   1851 void 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 
   1886 void 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 
   1944 void 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 
   1984 void 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 
   2021 bool 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 
   2032 bool 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 
   2084 bool 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 
   2136 bool 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 
   2188 void 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 
   2238 void 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 
   2429 void 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 
   2615 void 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