File indexing completed on 2025-01-19 03:55:14
0001 /*****************************************************************************/ 0002 // Copyright 2006-2019 Adobe Systems Incorporated 0003 // All Rights Reserved. 0004 // 0005 // NOTICE: Adobe permits you to use, modify, and distribute this file in 0006 // accordance with the terms of the Adobe license agreement accompanying it. 0007 /*****************************************************************************/ 0008 0009 #include "dng_reference.h" 0010 0011 #include "dng_1d_table.h" 0012 #include "dng_flags.h" 0013 #include "dng_hue_sat_map.h" 0014 #include "dng_matrix.h" 0015 #include "dng_resample.h" 0016 #include "dng_simd_type.h" 0017 #include "dng_utils.h" 0018 0019 /*****************************************************************************/ 0020 0021 // This module contains routines that should be as fast as possible, even 0022 // at the expense of slight code size increases. 0023 0024 #include "dng_fast_module.h" 0025 0026 /*****************************************************************************/ 0027 0028 void RefZeroBytes (void *dPtr, 0029 uint32 count) 0030 { 0031 0032 memset (dPtr, 0, count); 0033 0034 } 0035 0036 /*****************************************************************************/ 0037 0038 void RefCopyBytes (const void *sPtr, 0039 void *dPtr, 0040 uint32 count) 0041 { 0042 0043 memcpy (dPtr, sPtr, count); 0044 0045 } 0046 0047 /*****************************************************************************/ 0048 0049 void RefSwapBytes16 (uint16 *dPtr, 0050 uint32 count) 0051 { 0052 0053 for (uint32 j = 0; j < count; j++) 0054 { 0055 0056 dPtr [j] = SwapBytes16 (dPtr [j]); 0057 0058 } 0059 0060 } 0061 0062 /*****************************************************************************/ 0063 0064 void RefSwapBytes32 (uint32 *dPtr, 0065 uint32 count) 0066 { 0067 0068 for (uint32 j = 0; j < count; j++) 0069 { 0070 0071 dPtr [j] = SwapBytes32 (dPtr [j]); 0072 0073 } 0074 0075 } 0076 0077 /*****************************************************************************/ 0078 0079 void RefSetArea8 (uint8 *dPtr, 0080 uint8 value, 0081 uint32 rows, 0082 uint32 cols, 0083 uint32 planes, 0084 int32 rowStep, 0085 int32 colStep, 0086 int32 planeStep) 0087 { 0088 0089 for (uint32 row = 0; row < rows; row++) 0090 { 0091 0092 uint8 *dPtr1 = dPtr; 0093 0094 for (uint32 col = 0; col < cols; col++) 0095 { 0096 0097 uint8 *dPtr2 = dPtr1; 0098 0099 for (uint32 plane = 0; plane < planes; plane++) 0100 { 0101 0102 *dPtr2 = value; 0103 0104 dPtr2 += planeStep; 0105 0106 } 0107 0108 dPtr1 += colStep; 0109 0110 } 0111 0112 dPtr += rowStep; 0113 0114 } 0115 0116 } 0117 0118 /*****************************************************************************/ 0119 0120 template <SIMDType simd, typename destType> 0121 void RefSetArea (destType *dPtr, 0122 destType value, 0123 uint32 rows, 0124 uint32 cols, 0125 uint32 planes, 0126 int32 rowStep, 0127 int32 colStep, 0128 int32 planeStep) 0129 { 0130 0131 INTEL_COMPILER_NEEDED_NOTE 0132 SET_CPU_FEATURE(simd); 0133 0134 if ((planeStep == 0) && (colStep == 1)) 0135 { 0136 0137 for (uint32 row = 0; row < rows; row++) 0138 { 0139 0140 INTEL_PRAGMA_SIMD_ASSERT 0141 for (uint32 col = 0; col < cols; col++) 0142 { 0143 0144 dPtr [col] = value; 0145 0146 } 0147 0148 dPtr += rowStep; 0149 0150 } 0151 } 0152 0153 else if (planeStep == 1) 0154 { 0155 0156 for (uint32 row = 0; row < rows; row++) 0157 { 0158 0159 destType *dPtr1 = dPtr; 0160 0161 for (uint32 col = 0; col < cols; col++) 0162 { 0163 0164 destType *dPtr2 = dPtr1; 0165 0166 INTEL_PRAGMA_SIMD_ASSERT 0167 for (uint32 plane = 0; plane < planes; plane++) 0168 { 0169 0170 dPtr2 [plane] = value; 0171 0172 } 0173 0174 dPtr1 += colStep; 0175 0176 } 0177 0178 dPtr += rowStep; 0179 0180 } 0181 0182 } 0183 0184 else 0185 { 0186 0187 for (uint32 row = 0; row < rows; row++) 0188 { 0189 0190 destType *dPtr1 = dPtr; 0191 0192 for (uint32 col = 0; col < cols; col++) 0193 { 0194 0195 destType *dPtr2 = dPtr1; 0196 0197 for (uint32 plane = 0; plane < planes; plane++) 0198 { 0199 0200 *dPtr2 = value; 0201 0202 dPtr2 += planeStep; 0203 0204 } 0205 0206 dPtr1 += colStep; 0207 0208 } 0209 0210 dPtr += rowStep; 0211 0212 } 0213 0214 } 0215 0216 } 0217 0218 /*****************************************************************************/ 0219 0220 #if !qDNGIntelCompiler 0221 template 0222 void RefSetArea<Scalar, uint16>(uint16 *dPtr, 0223 uint16 value, 0224 uint32 rows, 0225 uint32 cols, 0226 uint32 planes, 0227 int32 rowStep, 0228 int32 colStep, 0229 int32 planeStep); 0230 template 0231 void RefSetArea<Scalar, uint32>(uint32 *dPtr, 0232 uint32 value, 0233 uint32 rows, 0234 uint32 cols, 0235 uint32 planes, 0236 int32 rowStep, 0237 int32 colStep, 0238 int32 planeStep); 0239 #else 0240 template SetArea16Proc RefSetArea<Scalar, uint16>; 0241 template SetArea16Proc RefSetArea<AVX2, uint16>; 0242 template SetArea32Proc RefSetArea<Scalar, uint32>; 0243 template SetArea32Proc RefSetArea<AVX2, uint32>; 0244 #endif 0245 0246 /*****************************************************************************/ 0247 0248 void RefCopyArea8 (const uint8 *sPtr, 0249 uint8 *dPtr, 0250 uint32 rows, 0251 uint32 cols, 0252 uint32 planes, 0253 int32 sRowStep, 0254 int32 sColStep, 0255 int32 sPlaneStep, 0256 int32 dRowStep, 0257 int32 dColStep, 0258 int32 dPlaneStep) 0259 { 0260 0261 for (uint32 row = 0; row < rows; row++) 0262 { 0263 0264 const uint8 *sPtr1 = sPtr; 0265 uint8 *dPtr1 = dPtr; 0266 0267 for (uint32 col = 0; col < cols; col++) 0268 { 0269 0270 const uint8 *sPtr2 = sPtr1; 0271 uint8 *dPtr2 = dPtr1; 0272 0273 for (uint32 plane = 0; plane < planes; plane++) 0274 { 0275 0276 *dPtr2 = *sPtr2; 0277 0278 sPtr2 += sPlaneStep; 0279 dPtr2 += dPlaneStep; 0280 0281 } 0282 0283 sPtr1 += sColStep; 0284 dPtr1 += dColStep; 0285 0286 } 0287 0288 sPtr += sRowStep; 0289 dPtr += dRowStep; 0290 0291 } 0292 0293 } 0294 0295 /*****************************************************************************/ 0296 0297 void RefCopyArea16 (const uint16 *sPtr, 0298 uint16 *dPtr, 0299 uint32 rows, 0300 uint32 cols, 0301 uint32 planes, 0302 int32 sRowStep, 0303 int32 sColStep, 0304 int32 sPlaneStep, 0305 int32 dRowStep, 0306 int32 dColStep, 0307 int32 dPlaneStep) 0308 { 0309 0310 for (uint32 row = 0; row < rows; row++) 0311 { 0312 0313 const uint16 *sPtr1 = sPtr; 0314 uint16 *dPtr1 = dPtr; 0315 0316 for (uint32 col = 0; col < cols; col++) 0317 { 0318 0319 const uint16 *sPtr2 = sPtr1; 0320 uint16 *dPtr2 = dPtr1; 0321 0322 for (uint32 plane = 0; plane < planes; plane++) 0323 { 0324 0325 *dPtr2 = *sPtr2; 0326 0327 sPtr2 += sPlaneStep; 0328 dPtr2 += dPlaneStep; 0329 0330 } 0331 0332 sPtr1 += sColStep; 0333 dPtr1 += dColStep; 0334 0335 } 0336 0337 sPtr += sRowStep; 0338 dPtr += dRowStep; 0339 0340 } 0341 0342 } 0343 0344 /*****************************************************************************/ 0345 0346 void RefCopyArea32 (const uint32 *sPtr, 0347 uint32 *dPtr, 0348 uint32 rows, 0349 uint32 cols, 0350 uint32 planes, 0351 int32 sRowStep, 0352 int32 sColStep, 0353 int32 sPlaneStep, 0354 int32 dRowStep, 0355 int32 dColStep, 0356 int32 dPlaneStep) 0357 { 0358 0359 for (uint32 row = 0; row < rows; row++) 0360 { 0361 0362 const uint32 *sPtr1 = sPtr; 0363 uint32 *dPtr1 = dPtr; 0364 0365 for (uint32 col = 0; col < cols; col++) 0366 { 0367 0368 const uint32 *sPtr2 = sPtr1; 0369 uint32 *dPtr2 = dPtr1; 0370 0371 for (uint32 plane = 0; plane < planes; plane++) 0372 { 0373 0374 *dPtr2 = *sPtr2; 0375 0376 sPtr2 += sPlaneStep; 0377 dPtr2 += dPlaneStep; 0378 0379 } 0380 0381 sPtr1 += sColStep; 0382 dPtr1 += dColStep; 0383 0384 } 0385 0386 sPtr += sRowStep; 0387 dPtr += dRowStep; 0388 0389 } 0390 0391 } 0392 0393 /*****************************************************************************/ 0394 0395 void RefCopyArea8_16 (const uint8 *sPtr, 0396 uint16 *dPtr, 0397 uint32 rows, 0398 uint32 cols, 0399 uint32 planes, 0400 int32 sRowStep, 0401 int32 sColStep, 0402 int32 sPlaneStep, 0403 int32 dRowStep, 0404 int32 dColStep, 0405 int32 dPlaneStep) 0406 { 0407 0408 for (uint32 row = 0; row < rows; row++) 0409 { 0410 0411 const uint8 *sPtr1 = sPtr; 0412 uint16 *dPtr1 = dPtr; 0413 0414 for (uint32 col = 0; col < cols; col++) 0415 { 0416 0417 const uint8 *sPtr2 = sPtr1; 0418 uint16 *dPtr2 = dPtr1; 0419 0420 for (uint32 plane = 0; plane < planes; plane++) 0421 { 0422 0423 *dPtr2 = *sPtr2; 0424 0425 sPtr2 += sPlaneStep; 0426 dPtr2 += dPlaneStep; 0427 0428 } 0429 0430 sPtr1 += sColStep; 0431 dPtr1 += dColStep; 0432 0433 } 0434 0435 sPtr += sRowStep; 0436 dPtr += dRowStep; 0437 0438 } 0439 0440 } 0441 0442 /*****************************************************************************/ 0443 0444 void RefCopyArea8_S16 (const uint8 *sPtr, 0445 int16 *dPtr, 0446 uint32 rows, 0447 uint32 cols, 0448 uint32 planes, 0449 int32 sRowStep, 0450 int32 sColStep, 0451 int32 sPlaneStep, 0452 int32 dRowStep, 0453 int32 dColStep, 0454 int32 dPlaneStep) 0455 { 0456 0457 for (uint32 row = 0; row < rows; row++) 0458 { 0459 0460 const uint8 *sPtr1 = sPtr; 0461 int16 *dPtr1 = dPtr; 0462 0463 for (uint32 col = 0; col < cols; col++) 0464 { 0465 0466 const uint8 *sPtr2 = sPtr1; 0467 int16 *dPtr2 = dPtr1; 0468 0469 for (uint32 plane = 0; plane < planes; plane++) 0470 { 0471 0472 int16 x = *sPtr; 0473 0474 *dPtr2 = x ^ 0x8000; 0475 0476 sPtr2 += sPlaneStep; 0477 dPtr2 += dPlaneStep; 0478 0479 } 0480 0481 sPtr1 += sColStep; 0482 dPtr1 += dColStep; 0483 0484 } 0485 0486 sPtr += sRowStep; 0487 dPtr += dRowStep; 0488 0489 } 0490 0491 } 0492 0493 /*****************************************************************************/ 0494 0495 void RefCopyArea8_32 (const uint8 *sPtr, 0496 uint32 *dPtr, 0497 uint32 rows, 0498 uint32 cols, 0499 uint32 planes, 0500 int32 sRowStep, 0501 int32 sColStep, 0502 int32 sPlaneStep, 0503 int32 dRowStep, 0504 int32 dColStep, 0505 int32 dPlaneStep) 0506 { 0507 0508 for (uint32 row = 0; row < rows; row++) 0509 { 0510 0511 const uint8 *sPtr1 = sPtr; 0512 uint32 *dPtr1 = dPtr; 0513 0514 for (uint32 col = 0; col < cols; col++) 0515 { 0516 0517 const uint8 *sPtr2 = sPtr1; 0518 uint32 *dPtr2 = dPtr1; 0519 0520 for (uint32 plane = 0; plane < planes; plane++) 0521 { 0522 0523 *dPtr2 = *sPtr2; 0524 0525 sPtr2 += sPlaneStep; 0526 dPtr2 += dPlaneStep; 0527 0528 } 0529 0530 sPtr1 += sColStep; 0531 dPtr1 += dColStep; 0532 0533 } 0534 0535 sPtr += sRowStep; 0536 dPtr += dRowStep; 0537 0538 } 0539 0540 } 0541 0542 /*****************************************************************************/ 0543 0544 template <SIMDType simd> 0545 void RefCopyArea16_S16 (const uint16 *sPtr, 0546 int16 *dPtr, 0547 uint32 rows, 0548 uint32 cols, 0549 uint32 planes, 0550 int32 sRowStep, 0551 int32 sColStep, 0552 int32 sPlaneStep, 0553 int32 dRowStep, 0554 int32 dColStep, 0555 int32 dPlaneStep) 0556 { 0557 0558 INTEL_COMPILER_NEEDED_NOTE 0559 SET_CPU_FEATURE(simd); 0560 0561 for (uint32 row = 0; row < rows; row++) 0562 { 0563 0564 const uint16 *sPtr1 = sPtr; 0565 int16 *dPtr1 = dPtr; 0566 0567 for (uint32 col = 0; col < cols; col++) 0568 { 0569 0570 const uint16 *sPtr2 = sPtr1; 0571 int16 *dPtr2 = dPtr1; 0572 0573 // Vectorizing if both sPlaneStep and dPlaneStep are 1. Else, 0574 // regular operation is performed. 0575 0576 if (sPlaneStep == 1 && dPlaneStep == 1) 0577 { 0578 0579 INTEL_PRAGMA_SIMD_ASSERT 0580 for (uint32 plane = 0; plane < planes; plane++) 0581 { 0582 0583 *dPtr2 = *sPtr2 ^ 0x8000; 0584 0585 sPtr2 += sPlaneStep; 0586 dPtr2 += dPlaneStep; 0587 } 0588 0589 } 0590 0591 else 0592 { 0593 0594 for (uint32 plane = 0; plane < planes; plane++) 0595 { 0596 0597 *dPtr2 = *sPtr2 ^ 0x8000; 0598 0599 sPtr2 += sPlaneStep; 0600 dPtr2 += dPlaneStep; 0601 0602 } 0603 0604 } 0605 0606 sPtr1 += sColStep; 0607 dPtr1 += dColStep; 0608 0609 } 0610 0611 sPtr += sRowStep; 0612 dPtr += dRowStep; 0613 0614 } 0615 0616 } 0617 0618 /*****************************************************************************/ 0619 0620 INTEL_COMPILER_NEEDED_NOTE 0621 #if !qDNGIntelCompiler 0622 template 0623 void RefCopyArea16_S16<Scalar> (const uint16 *sPtr, 0624 int16 *dPtr, 0625 uint32 rows, 0626 uint32 cols, 0627 uint32 planes, 0628 int32 sRowStep, 0629 int32 sColStep, 0630 int32 sPlaneStep, 0631 int32 dRowStep, 0632 int32 dColStep, 0633 int32 dPlaneStep); 0634 #else 0635 template CopyArea16_S16Proc RefCopyArea16_S16<Scalar>; 0636 template CopyArea16_S16Proc RefCopyArea16_S16<AVX2>; 0637 #endif 0638 0639 /*****************************************************************************/ 0640 0641 void RefCopyArea16_32 (const uint16 *sPtr, 0642 uint32 *dPtr, 0643 uint32 rows, 0644 uint32 cols, 0645 uint32 planes, 0646 int32 sRowStep, 0647 int32 sColStep, 0648 int32 sPlaneStep, 0649 int32 dRowStep, 0650 int32 dColStep, 0651 int32 dPlaneStep) 0652 { 0653 0654 for (uint32 row = 0; row < rows; row++) 0655 { 0656 0657 const uint16 *sPtr1 = sPtr; 0658 uint32 *dPtr1 = dPtr; 0659 0660 for (uint32 col = 0; col < cols; col++) 0661 { 0662 0663 const uint16 *sPtr2 = sPtr1; 0664 uint32 *dPtr2 = dPtr1; 0665 0666 for (uint32 plane = 0; plane < planes; plane++) 0667 { 0668 0669 *dPtr2 = *sPtr2; 0670 0671 sPtr2 += sPlaneStep; 0672 dPtr2 += dPlaneStep; 0673 0674 } 0675 0676 sPtr1 += sColStep; 0677 dPtr1 += dColStep; 0678 0679 } 0680 0681 sPtr += sRowStep; 0682 dPtr += dRowStep; 0683 0684 } 0685 0686 } 0687 0688 /*****************************************************************************/ 0689 0690 void RefCopyArea8_R32 (const uint8 *sPtr, 0691 real32 *dPtr, 0692 uint32 rows, 0693 uint32 cols, 0694 uint32 planes, 0695 int32 sRowStep, 0696 int32 sColStep, 0697 int32 sPlaneStep, 0698 int32 dRowStep, 0699 int32 dColStep, 0700 int32 dPlaneStep, 0701 uint32 pixelRange) 0702 { 0703 0704 real32 scale = 1.0f / (real32) pixelRange; 0705 0706 for (uint32 row = 0; row < rows; row++) 0707 { 0708 0709 const uint8 *sPtr1 = sPtr; 0710 real32 *dPtr1 = dPtr; 0711 0712 for (uint32 col = 0; col < cols; col++) 0713 { 0714 0715 const uint8 *sPtr2 = sPtr1; 0716 real32 *dPtr2 = dPtr1; 0717 0718 for (uint32 plane = 0; plane < planes; plane++) 0719 { 0720 0721 *dPtr2 = scale * (real32) *sPtr2; 0722 0723 sPtr2 += sPlaneStep; 0724 dPtr2 += dPlaneStep; 0725 0726 } 0727 0728 sPtr1 += sColStep; 0729 dPtr1 += dColStep; 0730 0731 } 0732 0733 sPtr += sRowStep; 0734 dPtr += dRowStep; 0735 0736 } 0737 0738 } 0739 0740 /*****************************************************************************/ 0741 0742 void RefCopyArea16_R32 (const uint16 *sPtr, 0743 real32 *dPtr, 0744 uint32 rows, 0745 uint32 cols, 0746 uint32 planes, 0747 int32 sRowStep, 0748 int32 sColStep, 0749 int32 sPlaneStep, 0750 int32 dRowStep, 0751 int32 dColStep, 0752 int32 dPlaneStep, 0753 uint32 pixelRange) 0754 { 0755 0756 real32 scale = 1.0f / (real32) pixelRange; 0757 0758 for (uint32 row = 0; row < rows; row++) 0759 { 0760 0761 const uint16 *sPtr1 = sPtr; 0762 real32 *dPtr1 = dPtr; 0763 0764 for (uint32 col = 0; col < cols; col++) 0765 { 0766 0767 const uint16 *sPtr2 = sPtr1; 0768 real32 *dPtr2 = dPtr1; 0769 0770 for (uint32 plane = 0; plane < planes; plane++) 0771 { 0772 0773 *dPtr2 = scale * (real32) *sPtr2; 0774 0775 sPtr2 += sPlaneStep; 0776 dPtr2 += dPlaneStep; 0777 0778 } 0779 0780 sPtr1 += sColStep; 0781 dPtr1 += dColStep; 0782 0783 } 0784 0785 sPtr += sRowStep; 0786 dPtr += dRowStep; 0787 0788 } 0789 0790 } 0791 0792 /*****************************************************************************/ 0793 0794 void RefCopyAreaS16_R32 (const int16 *sPtr, 0795 real32 *dPtr, 0796 uint32 rows, 0797 uint32 cols, 0798 uint32 planes, 0799 int32 sRowStep, 0800 int32 sColStep, 0801 int32 sPlaneStep, 0802 int32 dRowStep, 0803 int32 dColStep, 0804 int32 dPlaneStep, 0805 uint32 pixelRange) 0806 { 0807 0808 real32 scale = 1.0f / (real32) pixelRange; 0809 0810 for (uint32 row = 0; row < rows; row++) 0811 { 0812 0813 const int16 *sPtr1 = sPtr; 0814 real32 *dPtr1 = dPtr; 0815 0816 for (uint32 col = 0; col < cols; col++) 0817 { 0818 0819 const int16 *sPtr2 = sPtr1; 0820 real32 *dPtr2 = dPtr1; 0821 0822 for (uint32 plane = 0; plane < planes; plane++) 0823 { 0824 0825 int32 x = (*sPtr ^ 0x8000); 0826 0827 *dPtr2 = scale * (real32) x; 0828 0829 sPtr2 += sPlaneStep; 0830 dPtr2 += dPlaneStep; 0831 0832 } 0833 0834 sPtr1 += sColStep; 0835 dPtr1 += dColStep; 0836 0837 } 0838 0839 sPtr += sRowStep; 0840 dPtr += dRowStep; 0841 0842 } 0843 0844 } 0845 0846 /*****************************************************************************/ 0847 0848 void RefCopyAreaR32_8 (const real32 *sPtr, 0849 uint8 *dPtr, 0850 uint32 rows, 0851 uint32 cols, 0852 uint32 planes, 0853 int32 sRowStep, 0854 int32 sColStep, 0855 int32 sPlaneStep, 0856 int32 dRowStep, 0857 int32 dColStep, 0858 int32 dPlaneStep, 0859 uint32 pixelRange) 0860 { 0861 0862 real32 scale = (real32) pixelRange; 0863 0864 for (uint32 row = 0; row < rows; row++) 0865 { 0866 0867 const real32 *sPtr1 = sPtr; 0868 uint8 *dPtr1 = dPtr; 0869 0870 for (uint32 col = 0; col < cols; col++) 0871 { 0872 0873 const real32 *sPtr2 = sPtr1; 0874 uint8 *dPtr2 = dPtr1; 0875 0876 for (uint32 plane = 0; plane < planes; plane++) 0877 { 0878 0879 *dPtr2 = (uint8) (Pin_Overrange (*sPtr2) * scale + 0.5f); 0880 0881 sPtr2 += sPlaneStep; 0882 dPtr2 += dPlaneStep; 0883 0884 } 0885 0886 sPtr1 += sColStep; 0887 dPtr1 += dColStep; 0888 0889 } 0890 0891 sPtr += sRowStep; 0892 dPtr += dRowStep; 0893 0894 } 0895 0896 } 0897 0898 /*****************************************************************************/ 0899 0900 void RefCopyAreaR32_16 (const real32 *sPtr, 0901 uint16 *dPtr, 0902 uint32 rows, 0903 uint32 cols, 0904 uint32 planes, 0905 int32 sRowStep, 0906 int32 sColStep, 0907 int32 sPlaneStep, 0908 int32 dRowStep, 0909 int32 dColStep, 0910 int32 dPlaneStep, 0911 uint32 pixelRange) 0912 { 0913 0914 real32 scale = (real32) pixelRange; 0915 0916 for (uint32 row = 0; row < rows; row++) 0917 { 0918 0919 const real32 *sPtr1 = sPtr; 0920 uint16 *dPtr1 = dPtr; 0921 0922 for (uint32 col = 0; col < cols; col++) 0923 { 0924 0925 const real32 *sPtr2 = sPtr1; 0926 uint16 *dPtr2 = dPtr1; 0927 0928 for (uint32 plane = 0; plane < planes; plane++) 0929 { 0930 0931 *dPtr2 = (uint16) (Pin_Overrange (*sPtr2) * scale + 0.5f); 0932 0933 sPtr2 += sPlaneStep; 0934 dPtr2 += dPlaneStep; 0935 0936 } 0937 0938 sPtr1 += sColStep; 0939 dPtr1 += dColStep; 0940 0941 } 0942 0943 sPtr += sRowStep; 0944 dPtr += dRowStep; 0945 0946 } 0947 0948 } 0949 0950 /*****************************************************************************/ 0951 0952 void RefCopyAreaR32_S16 (const real32 *sPtr, 0953 int16 *dPtr, 0954 uint32 rows, 0955 uint32 cols, 0956 uint32 planes, 0957 int32 sRowStep, 0958 int32 sColStep, 0959 int32 sPlaneStep, 0960 int32 dRowStep, 0961 int32 dColStep, 0962 int32 dPlaneStep, 0963 uint32 pixelRange) 0964 { 0965 0966 real32 scale = (real32) pixelRange; 0967 0968 for (uint32 row = 0; row < rows; row++) 0969 { 0970 0971 const real32 *sPtr1 = sPtr; 0972 int16 *dPtr1 = dPtr; 0973 0974 for (uint32 col = 0; col < cols; col++) 0975 { 0976 0977 const real32 *sPtr2 = sPtr1; 0978 int16 *dPtr2 = dPtr1; 0979 0980 for (uint32 plane = 0; plane < planes; plane++) 0981 { 0982 0983 int32 x = (int32) (Pin_Overrange (*sPtr2) * scale + 0.5f); 0984 0985 *dPtr2 = (int16) (x ^ 0x8000); 0986 0987 sPtr2 += sPlaneStep; 0988 dPtr2 += dPlaneStep; 0989 0990 } 0991 0992 sPtr1 += sColStep; 0993 dPtr1 += dColStep; 0994 0995 } 0996 0997 sPtr += sRowStep; 0998 dPtr += dRowStep; 0999 1000 } 1001 1002 } 1003 1004 /*****************************************************************************/ 1005 1006 void RefRepeatArea8 (const uint8 *sPtr, 1007 uint8 *dPtr, 1008 uint32 rows, 1009 uint32 cols, 1010 uint32 planes, 1011 int32 rowStep, 1012 int32 colStep, 1013 int32 planeStep, 1014 uint32 repeatV, 1015 uint32 repeatH, 1016 uint32 phaseV, 1017 uint32 phaseH) 1018 { 1019 1020 const uint8 *sPtr0 = sPtr + phaseV * rowStep + 1021 phaseH * colStep; 1022 1023 int32 backStepV = (repeatV - 1) * rowStep; 1024 int32 backStepH = (repeatH - 1) * colStep; 1025 1026 for (uint32 row = 0; row < rows; row++) 1027 { 1028 1029 const uint8 *sPtr1 = sPtr0; 1030 uint8 *dPtr1 = dPtr; 1031 1032 uint32 colPhase = phaseH; 1033 1034 for (uint32 col = 0; col < cols; col++) 1035 { 1036 1037 const uint8 *sPtr2 = sPtr1; 1038 uint8 *dPtr2 = dPtr1; 1039 1040 for (uint32 plane = 0; plane < planes; plane++) 1041 { 1042 1043 *dPtr2 = *sPtr2; 1044 1045 sPtr2 += planeStep; 1046 dPtr2 += planeStep; 1047 1048 } 1049 1050 if (++colPhase == repeatH) 1051 { 1052 colPhase = 0; 1053 sPtr1 -= backStepH; 1054 } 1055 else 1056 { 1057 sPtr1 += colStep; 1058 } 1059 1060 dPtr1 += colStep; 1061 1062 } 1063 1064 if (++phaseV == repeatV) 1065 { 1066 phaseV = 0; 1067 sPtr0 -= backStepV; 1068 } 1069 else 1070 { 1071 sPtr0 += rowStep; 1072 } 1073 1074 dPtr += rowStep; 1075 1076 } 1077 1078 } 1079 1080 /*****************************************************************************/ 1081 1082 void RefRepeatArea16 (const uint16 *sPtr, 1083 uint16 *dPtr, 1084 uint32 rows, 1085 uint32 cols, 1086 uint32 planes, 1087 int32 rowStep, 1088 int32 colStep, 1089 int32 planeStep, 1090 uint32 repeatV, 1091 uint32 repeatH, 1092 uint32 phaseV, 1093 uint32 phaseH) 1094 { 1095 1096 const uint16 *sPtr0 = sPtr + phaseV * rowStep + 1097 phaseH * colStep; 1098 1099 int32 backStepV = (repeatV - 1) * rowStep; 1100 int32 backStepH = (repeatH - 1) * colStep; 1101 1102 for (uint32 row = 0; row < rows; row++) 1103 { 1104 1105 const uint16 *sPtr1 = sPtr0; 1106 uint16 *dPtr1 = dPtr; 1107 1108 uint32 colPhase = phaseH; 1109 1110 for (uint32 col = 0; col < cols; col++) 1111 { 1112 1113 const uint16 *sPtr2 = sPtr1; 1114 uint16 *dPtr2 = dPtr1; 1115 1116 for (uint32 plane = 0; plane < planes; plane++) 1117 { 1118 1119 *dPtr2 = *sPtr2; 1120 1121 sPtr2 += planeStep; 1122 dPtr2 += planeStep; 1123 1124 } 1125 1126 if (++colPhase == repeatH) 1127 { 1128 colPhase = 0; 1129 sPtr1 -= backStepH; 1130 } 1131 else 1132 { 1133 sPtr1 += colStep; 1134 } 1135 1136 dPtr1 += colStep; 1137 1138 } 1139 1140 if (++phaseV == repeatV) 1141 { 1142 phaseV = 0; 1143 sPtr0 -= backStepV; 1144 } 1145 else 1146 { 1147 sPtr0 += rowStep; 1148 } 1149 1150 dPtr += rowStep; 1151 1152 } 1153 1154 } 1155 1156 /*****************************************************************************/ 1157 1158 void RefRepeatArea32 (const uint32 *sPtr, 1159 uint32 *dPtr, 1160 uint32 rows, 1161 uint32 cols, 1162 uint32 planes, 1163 int32 rowStep, 1164 int32 colStep, 1165 int32 planeStep, 1166 uint32 repeatV, 1167 uint32 repeatH, 1168 uint32 phaseV, 1169 uint32 phaseH) 1170 { 1171 1172 const uint32 *sPtr0 = sPtr + phaseV * rowStep + 1173 phaseH * colStep; 1174 1175 int32 backStepV = (repeatV - 1) * rowStep; 1176 int32 backStepH = (repeatH - 1) * colStep; 1177 1178 for (uint32 row = 0; row < rows; row++) 1179 { 1180 1181 const uint32 *sPtr1 = sPtr0; 1182 uint32 *dPtr1 = dPtr; 1183 1184 uint32 colPhase = phaseH; 1185 1186 for (uint32 col = 0; col < cols; col++) 1187 { 1188 1189 const uint32 *sPtr2 = sPtr1; 1190 uint32 *dPtr2 = dPtr1; 1191 1192 for (uint32 plane = 0; plane < planes; plane++) 1193 { 1194 1195 *dPtr2 = *sPtr2; 1196 1197 sPtr2 += planeStep; 1198 dPtr2 += planeStep; 1199 1200 } 1201 1202 if (++colPhase == repeatH) 1203 { 1204 colPhase = 0; 1205 sPtr1 -= backStepH; 1206 } 1207 else 1208 { 1209 sPtr1 += colStep; 1210 } 1211 1212 dPtr1 += colStep; 1213 1214 } 1215 1216 if (++phaseV == repeatV) 1217 { 1218 phaseV = 0; 1219 sPtr0 -= backStepV; 1220 } 1221 else 1222 { 1223 sPtr0 += rowStep; 1224 } 1225 1226 dPtr += rowStep; 1227 1228 } 1229 1230 } 1231 1232 /*****************************************************************************/ 1233 1234 void RefShiftRight16 (uint16 *dPtr, 1235 uint32 rows, 1236 uint32 cols, 1237 uint32 planes, 1238 int32 rowStep, 1239 int32 colStep, 1240 int32 planeStep, 1241 uint32 shift) 1242 { 1243 1244 for (uint32 row = 0; row < rows; row++) 1245 { 1246 1247 uint16 *dPtr1 = dPtr; 1248 1249 for (uint32 col = 0; col < cols; col++) 1250 { 1251 1252 uint16 *dPtr2 = dPtr1; 1253 1254 for (uint32 plane = 0; plane < planes; plane++) 1255 { 1256 1257 *dPtr2 >>= shift; 1258 1259 dPtr2 += planeStep; 1260 1261 } 1262 1263 dPtr1 += colStep; 1264 1265 } 1266 1267 dPtr += rowStep; 1268 1269 } 1270 1271 } 1272 1273 /*****************************************************************************/ 1274 1275 void RefBilinearRow16 (const uint16 *sPtr, 1276 uint16 *dPtr, 1277 uint32 cols, 1278 uint32 patPhase, 1279 uint32 patCount, 1280 const uint32 * kernCounts, 1281 const int32 * const * kernOffsets, 1282 const uint16 * const * kernWeights, 1283 uint32 sShift) 1284 { 1285 1286 for (uint32 j = 0; j < cols; j++) 1287 { 1288 1289 const uint16 *p = sPtr + (j >> sShift); 1290 1291 uint32 count = kernCounts [patPhase]; 1292 1293 const int32 *offsets = kernOffsets [patPhase]; 1294 const uint16 *weights = kernWeights [patPhase]; 1295 1296 if (++patPhase == patCount) 1297 { 1298 patPhase = 0; 1299 } 1300 1301 uint32 total = 128; 1302 1303 for (uint32 k = 0; k < count; k++) 1304 { 1305 1306 int32 offset = offsets [k]; 1307 uint32 weight = weights [k]; 1308 1309 uint32 pixel = p [offset]; 1310 1311 total += pixel * weight; 1312 1313 } 1314 1315 dPtr [j] = (uint16) (total >> 8); 1316 1317 } 1318 1319 } 1320 1321 /*****************************************************************************/ 1322 1323 void RefBilinearRow32 (const real32 *sPtr, 1324 real32 *dPtr, 1325 uint32 cols, 1326 uint32 patPhase, 1327 uint32 patCount, 1328 const uint32 * kernCounts, 1329 const int32 * const * kernOffsets, 1330 const real32 * const * kernWeights, 1331 uint32 sShift) 1332 { 1333 1334 for (uint32 j = 0; j < cols; j++) 1335 { 1336 1337 const real32 *p = sPtr + (j >> sShift); 1338 1339 uint32 count = kernCounts [patPhase]; 1340 1341 const int32 *offsets = kernOffsets [patPhase]; 1342 const real32 *weights = kernWeights [patPhase]; 1343 1344 if (++patPhase == patCount) 1345 { 1346 patPhase = 0; 1347 } 1348 1349 real32 total = 0.0f; 1350 1351 for (uint32 k = 0; k < count; k++) 1352 { 1353 1354 int32 offset = offsets [k]; 1355 real32 weight = weights [k]; 1356 1357 real32 pixel = p [offset]; 1358 1359 total += pixel * weight; 1360 1361 } 1362 1363 dPtr [j] = total; 1364 1365 } 1366 1367 } 1368 1369 /*****************************************************************************/ 1370 1371 void RefBaselineABCtoRGB (const real32 *sPtrA, 1372 const real32 *sPtrB, 1373 const real32 *sPtrC, 1374 real32 *dPtrR, 1375 real32 *dPtrG, 1376 real32 *dPtrB, 1377 uint32 count, 1378 const dng_vector &cameraWhite, 1379 const dng_matrix &cameraToRGB) 1380 { 1381 1382 real32 clipA = (real32) cameraWhite [0]; 1383 real32 clipB = (real32) cameraWhite [1]; 1384 real32 clipC = (real32) cameraWhite [2]; 1385 1386 real32 m00 = (real32) cameraToRGB [0] [0]; 1387 real32 m01 = (real32) cameraToRGB [0] [1]; 1388 real32 m02 = (real32) cameraToRGB [0] [2]; 1389 1390 real32 m10 = (real32) cameraToRGB [1] [0]; 1391 real32 m11 = (real32) cameraToRGB [1] [1]; 1392 real32 m12 = (real32) cameraToRGB [1] [2]; 1393 1394 real32 m20 = (real32) cameraToRGB [2] [0]; 1395 real32 m21 = (real32) cameraToRGB [2] [1]; 1396 real32 m22 = (real32) cameraToRGB [2] [2]; 1397 1398 for (uint32 col = 0; col < count; col++) 1399 { 1400 1401 real32 A = sPtrA [col]; 1402 real32 B = sPtrB [col]; 1403 real32 C = sPtrC [col]; 1404 1405 A = Min_real32 (A, clipA); 1406 B = Min_real32 (B, clipB); 1407 C = Min_real32 (C, clipC); 1408 1409 real32 r = m00 * A + m01 * B + m02 * C; 1410 real32 g = m10 * A + m11 * B + m12 * C; 1411 real32 b = m20 * A + m21 * B + m22 * C; 1412 1413 r = Pin_real32 (0.0f, r, 1.0f); 1414 g = Pin_real32 (0.0f, g, 1.0f); 1415 b = Pin_real32 (0.0f, b, 1.0f); 1416 1417 dPtrR [col] = r; 1418 dPtrG [col] = g; 1419 dPtrB [col] = b; 1420 1421 } 1422 1423 } 1424 1425 /*****************************************************************************/ 1426 1427 void RefBaselineABCDtoRGB (const real32 *sPtrA, 1428 const real32 *sPtrB, 1429 const real32 *sPtrC, 1430 const real32 *sPtrD, 1431 real32 *dPtrR, 1432 real32 *dPtrG, 1433 real32 *dPtrB, 1434 uint32 count, 1435 const dng_vector &cameraWhite, 1436 const dng_matrix &cameraToRGB) 1437 { 1438 1439 real32 clipA = (real32) cameraWhite [0]; 1440 real32 clipB = (real32) cameraWhite [1]; 1441 real32 clipC = (real32) cameraWhite [2]; 1442 real32 clipD = (real32) cameraWhite [3]; 1443 1444 real32 m00 = (real32) cameraToRGB [0] [0]; 1445 real32 m01 = (real32) cameraToRGB [0] [1]; 1446 real32 m02 = (real32) cameraToRGB [0] [2]; 1447 real32 m03 = (real32) cameraToRGB [0] [3]; 1448 1449 real32 m10 = (real32) cameraToRGB [1] [0]; 1450 real32 m11 = (real32) cameraToRGB [1] [1]; 1451 real32 m12 = (real32) cameraToRGB [1] [2]; 1452 real32 m13 = (real32) cameraToRGB [1] [3]; 1453 1454 real32 m20 = (real32) cameraToRGB [2] [0]; 1455 real32 m21 = (real32) cameraToRGB [2] [1]; 1456 real32 m22 = (real32) cameraToRGB [2] [2]; 1457 real32 m23 = (real32) cameraToRGB [2] [3]; 1458 1459 for (uint32 col = 0; col < count; col++) 1460 { 1461 1462 real32 A = sPtrA [col]; 1463 real32 B = sPtrB [col]; 1464 real32 C = sPtrC [col]; 1465 real32 D = sPtrD [col]; 1466 1467 A = Min_real32 (A, clipA); 1468 B = Min_real32 (B, clipB); 1469 C = Min_real32 (C, clipC); 1470 D = Min_real32 (D, clipD); 1471 1472 real32 r = m00 * A + m01 * B + m02 * C + m03 * D; 1473 real32 g = m10 * A + m11 * B + m12 * C + m13 * D; 1474 real32 b = m20 * A + m21 * B + m22 * C + m23 * D; 1475 1476 r = Pin_real32 (0.0f, r, 1.0f); 1477 g = Pin_real32 (0.0f, g, 1.0f); 1478 b = Pin_real32 (0.0f, b, 1.0f); 1479 1480 dPtrR [col] = r; 1481 dPtrG [col] = g; 1482 dPtrB [col] = b; 1483 1484 } 1485 1486 } 1487 1488 /*****************************************************************************/ 1489 1490 void RefBaselineHueSatMap (const real32 *sPtrR, 1491 const real32 *sPtrG, 1492 const real32 *sPtrB, 1493 real32 *dPtrR, 1494 real32 *dPtrG, 1495 real32 *dPtrB, 1496 uint32 count, 1497 const dng_hue_sat_map &lut, 1498 const dng_1d_table *encodeTable, 1499 const dng_1d_table *decodeTable) 1500 { 1501 1502 uint32 hueDivisions; 1503 uint32 satDivisions; 1504 uint32 valDivisions; 1505 1506 lut.GetDivisions (hueDivisions, 1507 satDivisions, 1508 valDivisions); 1509 1510 real32 hScale = (hueDivisions < 2) ? 0.0f : (hueDivisions * (1.0f / 6.0f)); 1511 real32 sScale = (real32) ((int32) satDivisions - 1); 1512 real32 vScale = (real32) ((int32) valDivisions - 1); 1513 1514 int32 maxHueIndex0 = (int32) hueDivisions - 1; 1515 int32 maxSatIndex0 = (int32) satDivisions - 2; 1516 int32 maxValIndex0 = (int32) valDivisions - 2; 1517 1518 const bool hasEncodeTable = ((encodeTable != NULL) && (encodeTable->Table () != NULL)); 1519 const bool hasDecodeTable = ((decodeTable != NULL) && (decodeTable->Table () != NULL)); 1520 1521 const bool hasTable = hasEncodeTable && hasDecodeTable; 1522 1523 const dng_hue_sat_map::HSBModify *tableBase = lut.GetConstDeltas (); 1524 1525 int32 hueStep = satDivisions; 1526 int32 valStep = hueDivisions * hueStep; 1527 1528 #if 0 // Not required with "2.5D" table optimization. 1529 1530 if (valDivisions < 2) 1531 { 1532 valStep = 0; 1533 maxValIndex0 = 0; 1534 } 1535 1536 #endif 1537 1538 for (uint32 j = 0; j < count; j++) 1539 { 1540 1541 real32 r = sPtrR [j]; 1542 real32 g = sPtrG [j]; 1543 real32 b = sPtrB [j]; 1544 1545 real32 h, s, v; 1546 1547 DNG_RGBtoHSV (r, g, b, h, s, v); 1548 1549 real32 vEncoded = v; 1550 1551 real32 hueShift; 1552 real32 satScale; 1553 real32 valScale; 1554 1555 if (valDivisions < 2) // Optimize most common case of "2.5D" table. 1556 { 1557 1558 real32 hScaled = h * hScale; 1559 real32 sScaled = s * sScale; 1560 1561 int32 hIndex0 = (int32) hScaled; 1562 int32 sIndex0 = (int32) sScaled; 1563 1564 sIndex0 = Min_int32 (sIndex0, maxSatIndex0); 1565 1566 int32 hIndex1 = hIndex0 + 1; 1567 1568 if (hIndex0 >= maxHueIndex0) 1569 { 1570 hIndex0 = maxHueIndex0; 1571 hIndex1 = 0; 1572 } 1573 1574 real32 hFract1 = hScaled - (real32) hIndex0; 1575 real32 sFract1 = sScaled - (real32) sIndex0; 1576 1577 real32 hFract0 = 1.0f - hFract1; 1578 real32 sFract0 = 1.0f - sFract1; 1579 1580 const dng_hue_sat_map::HSBModify *entry00 = tableBase + hIndex0 * hueStep + 1581 sIndex0; 1582 1583 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep; 1584 1585 real32 hueShift0 = hFract0 * entry00->fHueShift + 1586 hFract1 * entry01->fHueShift; 1587 1588 real32 satScale0 = hFract0 * entry00->fSatScale + 1589 hFract1 * entry01->fSatScale; 1590 1591 real32 valScale0 = hFract0 * entry00->fValScale + 1592 hFract1 * entry01->fValScale; 1593 1594 entry00++; 1595 entry01++; 1596 1597 real32 hueShift1 = hFract0 * entry00->fHueShift + 1598 hFract1 * entry01->fHueShift; 1599 1600 real32 satScale1 = hFract0 * entry00->fSatScale + 1601 hFract1 * entry01->fSatScale; 1602 1603 real32 valScale1 = hFract0 * entry00->fValScale + 1604 hFract1 * entry01->fValScale; 1605 1606 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; 1607 satScale = sFract0 * satScale0 + sFract1 * satScale1; 1608 valScale = sFract0 * valScale0 + sFract1 * valScale1; 1609 1610 } 1611 1612 else 1613 { 1614 1615 if (hasTable) 1616 { 1617 vEncoded = encodeTable->Interpolate (Pin_real32 (v)); 1618 } 1619 1620 real32 hScaled = h * hScale; 1621 real32 sScaled = s * sScale; 1622 real32 vScaled = vEncoded * vScale; 1623 1624 int32 hIndex0 = (int32) hScaled; 1625 int32 sIndex0 = (int32) sScaled; 1626 int32 vIndex0 = (int32) vScaled; 1627 1628 sIndex0 = Min_int32 (sIndex0, maxSatIndex0); 1629 vIndex0 = Min_int32 (vIndex0, maxValIndex0); 1630 1631 int32 hIndex1 = hIndex0 + 1; 1632 1633 if (hIndex0 >= maxHueIndex0) 1634 { 1635 hIndex0 = maxHueIndex0; 1636 hIndex1 = 0; 1637 } 1638 1639 real32 hFract1 = hScaled - (real32) hIndex0; 1640 real32 sFract1 = sScaled - (real32) sIndex0; 1641 real32 vFract1 = vScaled - (real32) vIndex0; 1642 1643 real32 hFract0 = 1.0f - hFract1; 1644 real32 sFract0 = 1.0f - sFract1; 1645 real32 vFract0 = 1.0f - vFract1; 1646 1647 const dng_hue_sat_map::HSBModify *entry00 = tableBase + vIndex0 * valStep + 1648 hIndex0 * hueStep + 1649 sIndex0; 1650 1651 const dng_hue_sat_map::HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * hueStep; 1652 1653 const dng_hue_sat_map::HSBModify *entry10 = entry00 + valStep; 1654 const dng_hue_sat_map::HSBModify *entry11 = entry01 + valStep; 1655 1656 real32 hueShift0 = vFract0 * (hFract0 * entry00->fHueShift + 1657 hFract1 * entry01->fHueShift) + 1658 vFract1 * (hFract0 * entry10->fHueShift + 1659 hFract1 * entry11->fHueShift); 1660 1661 real32 satScale0 = vFract0 * (hFract0 * entry00->fSatScale + 1662 hFract1 * entry01->fSatScale) + 1663 vFract1 * (hFract0 * entry10->fSatScale + 1664 hFract1 * entry11->fSatScale); 1665 1666 real32 valScale0 = vFract0 * (hFract0 * entry00->fValScale + 1667 hFract1 * entry01->fValScale) + 1668 vFract1 * (hFract0 * entry10->fValScale + 1669 hFract1 * entry11->fValScale); 1670 1671 entry00++; 1672 entry01++; 1673 entry10++; 1674 entry11++; 1675 1676 real32 hueShift1 = vFract0 * (hFract0 * entry00->fHueShift + 1677 hFract1 * entry01->fHueShift) + 1678 vFract1 * (hFract0 * entry10->fHueShift + 1679 hFract1 * entry11->fHueShift); 1680 1681 real32 satScale1 = vFract0 * (hFract0 * entry00->fSatScale + 1682 hFract1 * entry01->fSatScale) + 1683 vFract1 * (hFract0 * entry10->fSatScale + 1684 hFract1 * entry11->fSatScale); 1685 1686 real32 valScale1 = vFract0 * (hFract0 * entry00->fValScale + 1687 hFract1 * entry01->fValScale) + 1688 vFract1 * (hFract0 * entry10->fValScale + 1689 hFract1 * entry11->fValScale); 1690 1691 hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; 1692 satScale = sFract0 * satScale0 + sFract1 * satScale1; 1693 valScale = sFract0 * valScale0 + sFract1 * valScale1; 1694 1695 } 1696 1697 hueShift *= (6.0f / 360.0f); // Convert to internal hue range. 1698 1699 h += hueShift; 1700 1701 s = Min_real32 (s * satScale, 1.0f); 1702 1703 vEncoded = Pin_real32 (vEncoded * valScale); 1704 1705 v = hasTable ? decodeTable->Interpolate (vEncoded) : vEncoded; 1706 1707 DNG_HSVtoRGB (h, s, v, r, g, b); 1708 1709 dPtrR [j] = r; 1710 dPtrG [j] = g; 1711 dPtrB [j] = b; 1712 1713 } 1714 1715 } 1716 1717 /*****************************************************************************/ 1718 1719 void RefBaselineRGBtoGray (const real32 *sPtrR, 1720 const real32 *sPtrG, 1721 const real32 *sPtrB, 1722 real32 *dPtrG, 1723 uint32 count, 1724 const dng_matrix &matrix) 1725 { 1726 1727 real32 m00 = (real32) matrix [0] [0]; 1728 real32 m01 = (real32) matrix [0] [1]; 1729 real32 m02 = (real32) matrix [0] [2]; 1730 1731 for (uint32 col = 0; col < count; col++) 1732 { 1733 1734 real32 R = sPtrR [col]; 1735 real32 G = sPtrG [col]; 1736 real32 B = sPtrB [col]; 1737 1738 real32 g = m00 * R + m01 * G + m02 * B; 1739 1740 g = Pin_real32 (0.0f, g, 1.0f); 1741 1742 dPtrG [col] = g; 1743 1744 } 1745 1746 } 1747 1748 /*****************************************************************************/ 1749 1750 void RefBaselineRGBtoRGB (const real32 *sPtrR, 1751 const real32 *sPtrG, 1752 const real32 *sPtrB, 1753 real32 *dPtrR, 1754 real32 *dPtrG, 1755 real32 *dPtrB, 1756 uint32 count, 1757 const dng_matrix &matrix) 1758 { 1759 1760 real32 m00 = (real32) matrix [0] [0]; 1761 real32 m01 = (real32) matrix [0] [1]; 1762 real32 m02 = (real32) matrix [0] [2]; 1763 1764 real32 m10 = (real32) matrix [1] [0]; 1765 real32 m11 = (real32) matrix [1] [1]; 1766 real32 m12 = (real32) matrix [1] [2]; 1767 1768 real32 m20 = (real32) matrix [2] [0]; 1769 real32 m21 = (real32) matrix [2] [1]; 1770 real32 m22 = (real32) matrix [2] [2]; 1771 1772 for (uint32 col = 0; col < count; col++) 1773 { 1774 1775 real32 R = sPtrR [col]; 1776 real32 G = sPtrG [col]; 1777 real32 B = sPtrB [col]; 1778 1779 real32 r = m00 * R + m01 * G + m02 * B; 1780 real32 g = m10 * R + m11 * G + m12 * B; 1781 real32 b = m20 * R + m21 * G + m22 * B; 1782 1783 r = Pin_real32 (0.0f, r, 1.0f); 1784 g = Pin_real32 (0.0f, g, 1.0f); 1785 b = Pin_real32 (0.0f, b, 1.0f); 1786 1787 dPtrR [col] = r; 1788 dPtrG [col] = g; 1789 dPtrB [col] = b; 1790 1791 } 1792 1793 } 1794 1795 /*****************************************************************************/ 1796 1797 void RefBaseline1DTable (const real32 *sPtr, 1798 real32 *dPtr, 1799 uint32 count, 1800 const dng_1d_table &table) 1801 { 1802 1803 for (uint32 col = 0; col < count; col++) 1804 { 1805 1806 real32 x = sPtr [col]; 1807 1808 real32 y = table.Interpolate (x); 1809 1810 dPtr [col] = y; 1811 1812 } 1813 1814 } 1815 1816 /*****************************************************************************/ 1817 1818 void RefBaselineRGBTone (const real32 *sPtrR, 1819 const real32 *sPtrG, 1820 const real32 *sPtrB, 1821 real32 *dPtrR, 1822 real32 *dPtrG, 1823 real32 *dPtrB, 1824 uint32 count, 1825 const dng_1d_table &table) 1826 { 1827 1828 for (uint32 col = 0; col < count; col++) 1829 { 1830 1831 real32 r = sPtrR [col]; 1832 real32 g = sPtrG [col]; 1833 real32 b = sPtrB [col]; 1834 1835 real32 rr; 1836 real32 gg; 1837 real32 bb; 1838 1839 #define RGBTone(r, g, b, rr, gg, bb)\ 1840 {\ 1841 \ 1842 DNG_ASSERT (r >= g && g >= b && r > b, "Logic Error RGBTone");\ 1843 \ 1844 rr = table.Interpolate (r);\ 1845 bb = table.Interpolate (b);\ 1846 \ 1847 gg = bb + ((rr - bb) * (g - b) / (r - b));\ 1848 \ 1849 } 1850 1851 if (r >= g) 1852 { 1853 1854 if (g > b) 1855 { 1856 1857 // Case 1: r >= g > b 1858 1859 RGBTone (r, g, b, rr, gg, bb); 1860 1861 } 1862 1863 else if (b > r) 1864 { 1865 1866 // Case 2: b > r >= g 1867 1868 RGBTone (b, r, g, bb, rr, gg); 1869 1870 } 1871 1872 else if (b > g) 1873 { 1874 1875 // Case 3: r >= b > g 1876 1877 RGBTone (r, b, g, rr, bb, gg); 1878 1879 } 1880 1881 else 1882 { 1883 1884 // Case 4: r >= g == b 1885 1886 DNG_ASSERT (r >= g && g == b, "Logic Error 2"); 1887 1888 rr = table.Interpolate (r); 1889 gg = table.Interpolate (g); 1890 bb = gg; 1891 1892 } 1893 1894 } 1895 1896 else 1897 { 1898 1899 if (r >= b) 1900 { 1901 1902 // Case 5: g > r >= b 1903 1904 RGBTone (g, r, b, gg, rr, bb); 1905 1906 } 1907 1908 else if (b > g) 1909 { 1910 1911 // Case 6: b > g > r 1912 1913 RGBTone (b, g, r, bb, gg, rr); 1914 1915 } 1916 1917 else 1918 { 1919 1920 // Case 7: g >= b > r 1921 1922 RGBTone (g, b, r, gg, bb, rr); 1923 1924 } 1925 1926 } 1927 1928 #undef RGBTone 1929 1930 dPtrR [col] = rr; 1931 dPtrG [col] = gg; 1932 dPtrB [col] = bb; 1933 1934 } 1935 1936 } 1937 1938 /*****************************************************************************/ 1939 1940 void RefResampleDown16 (const uint16 *sPtr, 1941 uint16 *dPtr, 1942 uint32 sCount, 1943 int32 sRowStep, 1944 const int16 *wPtr, 1945 uint32 wCount, 1946 uint32 pixelRange) 1947 { 1948 1949 for (uint32 j = 0; j < sCount; j++) 1950 { 1951 1952 int32 total = 8192; 1953 1954 const uint16 *s = sPtr + j; 1955 1956 for (uint32 k = 0; k < wCount; k++) 1957 { 1958 1959 total += wPtr [k] * (int32) s [0]; 1960 1961 s += sRowStep; 1962 1963 } 1964 1965 dPtr [j] = (uint16) Pin_int32 (0, 1966 total >> 14, 1967 pixelRange); 1968 1969 } 1970 1971 } 1972 1973 /*****************************************************************************/ 1974 1975 void RefResampleDown32 (const real32 *sPtr, 1976 real32 *dPtr, 1977 uint32 sCount, 1978 int32 sRowStep, 1979 const real32 *wPtr, 1980 uint32 wCount) 1981 { 1982 1983 uint32 col; 1984 1985 // Process first row. 1986 1987 real32 w = wPtr [0]; 1988 1989 for (col = 0; col < sCount; col++) 1990 { 1991 1992 dPtr [col] = w * sPtr [col]; 1993 1994 } 1995 1996 sPtr += sRowStep; 1997 1998 // Process middle rows. 1999 2000 for (uint32 j = 1; j < wCount - 1; j++) 2001 { 2002 2003 w = wPtr [j]; 2004 2005 for (col = 0; col < sCount; col++) 2006 { 2007 2008 dPtr [col] += w * sPtr [col]; 2009 2010 } 2011 2012 sPtr += sRowStep; 2013 2014 } 2015 2016 // Process last row. 2017 2018 w = wPtr [wCount - 1]; 2019 2020 for (col = 0; col < sCount; col++) 2021 { 2022 2023 dPtr [col] = Pin_real32 (0.0f, 2024 dPtr [col] + w * sPtr [col], 2025 1.0f); 2026 2027 } 2028 2029 } 2030 2031 /******************************************************************************/ 2032 2033 void RefResampleAcross16 (const uint16 *sPtr, 2034 uint16 *dPtr, 2035 uint32 dCount, 2036 const int32 *coord, 2037 const int16 *wPtr, 2038 uint32 wCount, 2039 uint32 wStep, 2040 uint32 pixelRange) 2041 { 2042 2043 for (uint32 j = 0; j < dCount; j++) 2044 { 2045 2046 int32 sCoord = coord [j]; 2047 2048 int32 sFract = sCoord & kResampleSubsampleMask; 2049 int32 sPixel = sCoord >> kResampleSubsampleBits; 2050 2051 const int16 *w = wPtr + sFract * wStep; 2052 const uint16 *s = sPtr + sPixel; 2053 2054 int32 total = w [0] * (int32) s [0]; 2055 2056 for (uint32 k = 1; k < wCount; k++) 2057 { 2058 2059 total += w [k] * (int32) s [k]; 2060 2061 } 2062 2063 dPtr [j] = (uint16) Pin_int32 (0, 2064 (total + 8192) >> 14, 2065 pixelRange); 2066 2067 } 2068 2069 } 2070 2071 /******************************************************************************/ 2072 2073 void RefResampleAcross32 (const real32 *sPtr, 2074 real32 *dPtr, 2075 uint32 dCount, 2076 const int32 *coord, 2077 const real32 *wPtr, 2078 uint32 wCount, 2079 uint32 wStep) 2080 { 2081 2082 for (uint32 j = 0; j < dCount; j++) 2083 { 2084 2085 int32 sCoord = coord [j]; 2086 2087 int32 sFract = sCoord & kResampleSubsampleMask; 2088 int32 sPixel = sCoord >> kResampleSubsampleBits; 2089 2090 const real32 *w = wPtr + sFract * wStep; 2091 const real32 *s = sPtr + sPixel; 2092 2093 real32 total = w [0] * s [0]; 2094 2095 for (uint32 k = 1; k < wCount; k++) 2096 { 2097 2098 total += w [k] * s [k]; 2099 2100 } 2101 2102 dPtr [j] = Pin_real32 (0.0f, total, 1.0f); 2103 2104 } 2105 2106 } 2107 2108 /*****************************************************************************/ 2109 2110 bool RefEqualBytes (const void *sPtr, 2111 const void *dPtr, 2112 uint32 count) 2113 { 2114 2115 return memcmp (dPtr, sPtr, count) == 0; 2116 2117 } 2118 2119 /*****************************************************************************/ 2120 2121 bool RefEqualArea8 (const uint8 *sPtr, 2122 const uint8 *dPtr, 2123 uint32 rows, 2124 uint32 cols, 2125 uint32 planes, 2126 int32 sRowStep, 2127 int32 sColStep, 2128 int32 sPlaneStep, 2129 int32 dRowStep, 2130 int32 dColStep, 2131 int32 dPlaneStep) 2132 { 2133 2134 for (uint32 row = 0; row < rows; row++) 2135 { 2136 2137 const uint8 *sPtr1 = sPtr; 2138 const uint8 *dPtr1 = dPtr; 2139 2140 for (uint32 col = 0; col < cols; col++) 2141 { 2142 2143 const uint8 *sPtr2 = sPtr1; 2144 const uint8 *dPtr2 = dPtr1; 2145 2146 for (uint32 plane = 0; plane < planes; plane++) 2147 { 2148 2149 if (*dPtr2 != *sPtr2) 2150 return false; 2151 2152 sPtr2 += sPlaneStep; 2153 dPtr2 += dPlaneStep; 2154 2155 } 2156 2157 sPtr1 += sColStep; 2158 dPtr1 += dColStep; 2159 2160 } 2161 2162 sPtr += sRowStep; 2163 dPtr += dRowStep; 2164 2165 } 2166 2167 return true; 2168 2169 } 2170 2171 /*****************************************************************************/ 2172 2173 bool RefEqualArea16 (const uint16 *sPtr, 2174 const uint16 *dPtr, 2175 uint32 rows, 2176 uint32 cols, 2177 uint32 planes, 2178 int32 sRowStep, 2179 int32 sColStep, 2180 int32 sPlaneStep, 2181 int32 dRowStep, 2182 int32 dColStep, 2183 int32 dPlaneStep) 2184 { 2185 2186 for (uint32 row = 0; row < rows; row++) 2187 { 2188 2189 const uint16 *sPtr1 = sPtr; 2190 const uint16 *dPtr1 = dPtr; 2191 2192 for (uint32 col = 0; col < cols; col++) 2193 { 2194 2195 const uint16 *sPtr2 = sPtr1; 2196 const uint16 *dPtr2 = dPtr1; 2197 2198 for (uint32 plane = 0; plane < planes; plane++) 2199 { 2200 2201 if (*dPtr2 != *sPtr2) 2202 return false; 2203 2204 sPtr2 += sPlaneStep; 2205 dPtr2 += dPlaneStep; 2206 2207 } 2208 2209 sPtr1 += sColStep; 2210 dPtr1 += dColStep; 2211 2212 } 2213 2214 sPtr += sRowStep; 2215 dPtr += dRowStep; 2216 2217 } 2218 2219 return true; 2220 2221 } 2222 2223 /*****************************************************************************/ 2224 2225 bool RefEqualArea32 (const uint32 *sPtr, 2226 const uint32 *dPtr, 2227 uint32 rows, 2228 uint32 cols, 2229 uint32 planes, 2230 int32 sRowStep, 2231 int32 sColStep, 2232 int32 sPlaneStep, 2233 int32 dRowStep, 2234 int32 dColStep, 2235 int32 dPlaneStep) 2236 { 2237 2238 for (uint32 row = 0; row < rows; row++) 2239 { 2240 2241 const uint32 *sPtr1 = sPtr; 2242 const uint32 *dPtr1 = dPtr; 2243 2244 for (uint32 col = 0; col < cols; col++) 2245 { 2246 2247 const uint32 *sPtr2 = sPtr1; 2248 const uint32 *dPtr2 = dPtr1; 2249 2250 for (uint32 plane = 0; plane < planes; plane++) 2251 { 2252 2253 if (*dPtr2 != *sPtr2) 2254 return false; 2255 2256 sPtr2 += sPlaneStep; 2257 dPtr2 += dPlaneStep; 2258 2259 } 2260 2261 sPtr1 += sColStep; 2262 dPtr1 += dColStep; 2263 2264 } 2265 2266 sPtr += sRowStep; 2267 dPtr += dRowStep; 2268 2269 } 2270 2271 return true; 2272 2273 } 2274 2275 /*****************************************************************************/ 2276 2277 void RefVignetteMask16 (uint16 *mPtr, 2278 uint32 rows, 2279 uint32 cols, 2280 int32 rowStep, 2281 int64 offsetH, 2282 int64 offsetV, 2283 int64 stepH, 2284 int64 stepV, 2285 uint32 tBits, 2286 const uint16 *table) 2287 { 2288 2289 uint32 tShift = 32 - tBits; 2290 uint32 tRound = (1 << (tShift - 1)); 2291 uint32 tLimit = 1 << tBits; 2292 2293 for (uint32 row = 0; row < rows; row++) 2294 { 2295 2296 int64 baseDelta = (offsetV + 32768) >> 16; 2297 2298 baseDelta = baseDelta * baseDelta + tRound; 2299 2300 int64 deltaH = offsetH + 32768; 2301 2302 for (uint32 col = 0; col < cols; col++) 2303 { 2304 2305 int64 temp = deltaH >> 16; 2306 2307 int64 delta = baseDelta + (temp * temp); 2308 2309 uint32 index = Min_uint32 ((uint32) (delta >> tShift), tLimit); 2310 2311 mPtr [col] = table [index]; 2312 2313 deltaH += stepH; 2314 2315 } 2316 2317 offsetV += stepV; 2318 2319 mPtr += rowStep; 2320 2321 } 2322 2323 } 2324 2325 /*****************************************************************************/ 2326 2327 void RefVignette16 (int16 *sPtr, 2328 const uint16 *mPtr, 2329 uint32 rows, 2330 uint32 cols, 2331 uint32 planes, 2332 int32 sRowStep, 2333 int32 sPlaneStep, 2334 int32 mRowStep, 2335 uint32 mBits) 2336 { 2337 2338 const uint32 mRound = 1 << (mBits - 1); 2339 2340 switch (planes) 2341 { 2342 2343 case 1: 2344 { 2345 2346 for (uint32 row = 0; row < rows; row++) 2347 { 2348 2349 for (uint32 col = 0; col < cols; col++) 2350 { 2351 2352 uint32 s = sPtr [col] + 32768; 2353 2354 uint32 m = mPtr [col]; 2355 2356 s = (s * m + mRound) >> mBits; 2357 2358 s = Min_uint32 (s, 65535); 2359 2360 sPtr [col] = (int16) (s - 32768); 2361 2362 } 2363 2364 sPtr += sRowStep; 2365 2366 mPtr += mRowStep; 2367 2368 } 2369 2370 break; 2371 2372 } 2373 2374 case 3: 2375 { 2376 2377 int16 *rPtr = sPtr; 2378 int16 *gPtr = rPtr + sPlaneStep; 2379 int16 *bPtr = gPtr + sPlaneStep; 2380 2381 for (uint32 row = 0; row < rows; row++) 2382 { 2383 2384 for (uint32 col = 0; col < cols; col++) 2385 { 2386 2387 uint32 r = rPtr [col] + 32768; 2388 uint32 g = gPtr [col] + 32768; 2389 uint32 b = bPtr [col] + 32768; 2390 2391 uint32 m = mPtr [col]; 2392 2393 r = (r * m + mRound) >> mBits; 2394 g = (g * m + mRound) >> mBits; 2395 b = (b * m + mRound) >> mBits; 2396 2397 r = Min_uint32 (r, 65535); 2398 g = Min_uint32 (g, 65535); 2399 b = Min_uint32 (b, 65535); 2400 2401 rPtr [col] = (int16) (r - 32768); 2402 gPtr [col] = (int16) (g - 32768); 2403 bPtr [col] = (int16) (b - 32768); 2404 2405 } 2406 2407 rPtr += sRowStep; 2408 gPtr += sRowStep; 2409 bPtr += sRowStep; 2410 2411 mPtr += mRowStep; 2412 2413 } 2414 2415 break; 2416 2417 } 2418 2419 case 4: 2420 { 2421 2422 int16 *aPtr = sPtr; 2423 int16 *bPtr = aPtr + sPlaneStep; 2424 int16 *cPtr = bPtr + sPlaneStep; 2425 int16 *dPtr = cPtr + sPlaneStep; 2426 2427 for (uint32 row = 0; row < rows; row++) 2428 { 2429 2430 for (uint32 col = 0; col < cols; col++) 2431 { 2432 2433 uint32 a = aPtr [col] + 32768; 2434 uint32 b = bPtr [col] + 32768; 2435 uint32 c = cPtr [col] + 32768; 2436 uint32 d = dPtr [col] + 32768; 2437 2438 uint32 m = mPtr [col]; 2439 2440 a = (a * m + mRound) >> mBits; 2441 b = (b * m + mRound) >> mBits; 2442 c = (c * m + mRound) >> mBits; 2443 d = (d * m + mRound) >> mBits; 2444 2445 a = Min_uint32 (a, 65535); 2446 b = Min_uint32 (b, 65535); 2447 c = Min_uint32 (c, 65535); 2448 d = Min_uint32 (d, 65535); 2449 2450 aPtr [col] = (int16) (a - 32768); 2451 bPtr [col] = (int16) (b - 32768); 2452 cPtr [col] = (int16) (c - 32768); 2453 dPtr [col] = (int16) (d - 32768); 2454 2455 } 2456 2457 aPtr += sRowStep; 2458 bPtr += sRowStep; 2459 cPtr += sRowStep; 2460 dPtr += sRowStep; 2461 2462 mPtr += mRowStep; 2463 2464 } 2465 2466 break; 2467 2468 } 2469 2470 default: 2471 { 2472 2473 for (uint32 plane = 0; plane < planes; plane++) 2474 { 2475 2476 int16 *planePtr = sPtr; 2477 2478 const uint16 *maskPtr = mPtr; 2479 2480 for (uint32 row = 0; row < rows; row++) 2481 { 2482 2483 for (uint32 col = 0; col < cols; col++) 2484 { 2485 2486 uint32 s = planePtr [col] + 32768; 2487 2488 uint32 m = maskPtr [col]; 2489 2490 s = (s * m + mRound) >> mBits; 2491 2492 s = Min_uint32 (s, 65535); 2493 2494 planePtr [col] = (int16) (s - 32768); 2495 2496 } 2497 2498 planePtr += sRowStep; 2499 2500 maskPtr += mRowStep; 2501 2502 } 2503 2504 sPtr += sPlaneStep; 2505 2506 } 2507 2508 break; 2509 2510 } 2511 2512 } 2513 2514 } 2515 2516 /*****************************************************************************/ 2517 2518 void RefVignette32 (real32 *sPtr, 2519 const uint16 *mPtr, 2520 uint32 rows, 2521 uint32 cols, 2522 uint32 planes, 2523 int32 sRowStep, 2524 int32 sPlaneStep, 2525 int32 mRowStep, 2526 uint32 mBits, 2527 uint16 blackLevel) 2528 { 2529 2530 real32 *basePtr = sPtr; 2531 2532 real32 blackScale1 = 1.0f; 2533 real32 blackScale2 = 1.0f; 2534 real32 blackOffset1 = 0.0f; 2535 real32 blackOffset2 = 0.0f; 2536 2537 if (blackLevel != 0) 2538 { 2539 2540 blackOffset2 = ((real32) blackLevel) / 65535.0f; 2541 blackScale2 = 1.0f - blackOffset2; 2542 blackScale1 = 1.0f / blackScale2; 2543 blackOffset1 = 1.0f - blackScale1; 2544 2545 for (uint32 plane = 0; plane < planes; plane++) 2546 { 2547 2548 real32 *dPtr = basePtr + plane * sPlaneStep; 2549 2550 for (uint32 row = 0; row < rows; row++) 2551 { 2552 2553 for (uint32 col = 0; col < cols; col++) 2554 { 2555 2556 dPtr [col] = dPtr [col] * blackScale1 + blackOffset1; 2557 2558 } 2559 2560 dPtr += sRowStep; 2561 2562 } 2563 2564 } 2565 2566 } 2567 2568 const real32 kNorm = 1.0f / (1 << mBits); 2569 2570 switch (planes) 2571 { 2572 2573 case 1: 2574 { 2575 2576 for (uint32 row = 0; row < rows; row++) 2577 { 2578 2579 for (uint32 col = 0; col < cols; col++) 2580 { 2581 2582 real32 s = sPtr [col]; 2583 2584 uint16 m = mPtr [col]; 2585 2586 real32 scale = m * kNorm; 2587 2588 s = Min_real32 (s * scale, 1.0f); 2589 2590 sPtr [col] = s; 2591 2592 } 2593 2594 sPtr += sRowStep; 2595 2596 mPtr += mRowStep; 2597 2598 } 2599 2600 break; 2601 2602 } 2603 2604 case 3: 2605 { 2606 2607 real32 *rPtr = sPtr; 2608 real32 *gPtr = rPtr + sPlaneStep; 2609 real32 *bPtr = gPtr + sPlaneStep; 2610 2611 for (uint32 row = 0; row < rows; row++) 2612 { 2613 2614 for (uint32 col = 0; col < cols; col++) 2615 { 2616 2617 real32 r = rPtr [col]; 2618 real32 g = gPtr [col]; 2619 real32 b = bPtr [col]; 2620 2621 uint16 m = mPtr [col]; 2622 2623 real32 scale = m * kNorm; 2624 2625 r = Min_real32 (r * scale, 1.0f); 2626 g = Min_real32 (g * scale, 1.0f); 2627 b = Min_real32 (b * scale, 1.0f); 2628 2629 rPtr [col] = r; 2630 gPtr [col] = g; 2631 bPtr [col] = b; 2632 2633 } 2634 2635 rPtr += sRowStep; 2636 gPtr += sRowStep; 2637 bPtr += sRowStep; 2638 2639 mPtr += mRowStep; 2640 2641 } 2642 2643 break; 2644 2645 } 2646 2647 case 4: 2648 { 2649 2650 real32 *aPtr = sPtr; 2651 real32 *bPtr = aPtr + sPlaneStep; 2652 real32 *cPtr = bPtr + sPlaneStep; 2653 real32 *dPtr = cPtr + sPlaneStep; 2654 2655 for (uint32 row = 0; row < rows; row++) 2656 { 2657 2658 for (uint32 col = 0; col < cols; col++) 2659 { 2660 2661 real32 a = aPtr [col]; 2662 real32 b = bPtr [col]; 2663 real32 c = cPtr [col]; 2664 real32 d = dPtr [col]; 2665 2666 uint16 m = mPtr [col]; 2667 2668 real32 scale = m * kNorm; 2669 2670 a = Min_real32 (a * scale, 1.0f); 2671 b = Min_real32 (b * scale, 1.0f); 2672 c = Min_real32 (c * scale, 1.0f); 2673 d = Min_real32 (d * scale, 1.0f); 2674 2675 aPtr [col] = a; 2676 bPtr [col] = b; 2677 cPtr [col] = c; 2678 dPtr [col] = d; 2679 2680 } 2681 2682 aPtr += sRowStep; 2683 bPtr += sRowStep; 2684 cPtr += sRowStep; 2685 dPtr += sRowStep; 2686 2687 mPtr += mRowStep; 2688 2689 } 2690 2691 break; 2692 2693 } 2694 2695 default: 2696 { 2697 2698 for (uint32 plane = 0; plane < planes; plane++) 2699 { 2700 2701 real32 *planePtr = sPtr; 2702 2703 const uint16 *maskPtr = mPtr; 2704 2705 for (uint32 row = 0; row < rows; row++) 2706 { 2707 2708 for (uint32 col = 0; col < cols; col++) 2709 { 2710 2711 real32 s = planePtr [col]; 2712 2713 uint16 m = maskPtr [col]; 2714 2715 real32 scale = m * kNorm; 2716 2717 s = Min_real32 (s * scale, 1.0f); 2718 2719 planePtr [col] = s; 2720 2721 } 2722 2723 planePtr += sRowStep; 2724 2725 maskPtr += mRowStep; 2726 2727 } 2728 2729 sPtr += sPlaneStep; 2730 2731 } 2732 2733 break; 2734 2735 } 2736 2737 } 2738 2739 if (blackLevel != 0) 2740 { 2741 2742 for (uint32 plane = 0; plane < planes; plane++) 2743 { 2744 2745 real32 *dPtr = basePtr + plane * sPlaneStep; 2746 2747 for (uint32 row = 0; row < rows; row++) 2748 { 2749 2750 for (uint32 col = 0; col < cols; col++) 2751 { 2752 2753 dPtr [col] = dPtr [col] * blackScale2 + blackOffset2; 2754 2755 } 2756 2757 dPtr += sRowStep; 2758 2759 } 2760 2761 } 2762 2763 } 2764 2765 } 2766 2767 /******************************************************************************/ 2768 2769 void RefMapArea16 (uint16 *dPtr, 2770 uint32 count0, 2771 uint32 count1, 2772 uint32 count2, 2773 int32 step0, 2774 int32 step1, 2775 int32 step2, 2776 const uint16 *map) 2777 { 2778 2779 if (step2 == 1 && count2 >= 32) 2780 { 2781 2782 for (uint32 index0 = 0; index0 < count0; index0++) 2783 { 2784 2785 uint16 *d1 = dPtr; 2786 2787 for (uint32 index1 = 0; index1 < count1; index1++) 2788 { 2789 2790 uint16 *d2 = d1; 2791 2792 uint32 count = count2; 2793 2794 // Get the data 32-bit aligned if it is not. 2795 2796 if (!IsAligned32 (dPtr)) 2797 { 2798 2799 d2 [0] = map [d2 [0]]; 2800 2801 count--; 2802 2803 d2++; 2804 2805 } 2806 2807 // Use 32-bit reads and writes for bulk processing. 2808 2809 uint32 *dPtr32 = (uint32 *) d2; 2810 2811 // Process in blocks of 16 pixels. 2812 2813 uint32 blocks = count >> 4; 2814 2815 count -= blocks << 4; 2816 d2 += blocks << 4; 2817 2818 while (blocks--) 2819 { 2820 2821 uint32 x0, x1, x2, x3, x4, x5, x6, x7; 2822 uint32 p0, p1, p2, p3, p4, p5, p6, p7; 2823 2824 // Use 32 bit reads & writes, and pack and unpack the 16-bit values. 2825 // This results in slightly higher performance. 2826 2827 // Note that this code runs on both little-endian and big-endian systems, 2828 // since the pixels are either never swapped or double swapped. 2829 2830 x0 = dPtr32 [0]; 2831 x1 = dPtr32 [1]; 2832 x2 = dPtr32 [2]; 2833 x3 = dPtr32 [3]; 2834 2835 p0 = map [x0 >> 16 ]; 2836 p1 = map [x0 & 0x0FFFF]; 2837 p2 = map [x1 >> 16 ]; 2838 p3 = map [x1 & 0x0FFFF]; 2839 p4 = map [x2 >> 16 ]; 2840 p5 = map [x2 & 0x0FFFF]; 2841 p6 = map [x3 >> 16 ]; 2842 p7 = map [x3 & 0x0FFFF]; 2843 2844 x0 = (p0 << 16) | p1; 2845 x1 = (p2 << 16) | p3; 2846 x2 = (p4 << 16) | p5; 2847 x3 = (p6 << 16) | p7; 2848 2849 x4 = dPtr32 [4]; 2850 x5 = dPtr32 [5]; 2851 x6 = dPtr32 [6]; 2852 x7 = dPtr32 [7]; 2853 2854 dPtr32 [0] = x0; 2855 dPtr32 [1] = x1; 2856 dPtr32 [2] = x2; 2857 dPtr32 [3] = x3; 2858 2859 p0 = map [x4 >> 16 ]; 2860 p1 = map [x4 & 0x0FFFF]; 2861 p2 = map [x5 >> 16 ]; 2862 p3 = map [x5 & 0x0FFFF]; 2863 p4 = map [x6 >> 16 ]; 2864 p5 = map [x6 & 0x0FFFF]; 2865 p6 = map [x7 >> 16 ]; 2866 p7 = map [x7 & 0x0FFFF]; 2867 2868 x4 = (p0 << 16) | p1; 2869 x5 = (p2 << 16) | p3; 2870 x6 = (p4 << 16) | p5; 2871 x7 = (p6 << 16) | p7; 2872 2873 dPtr32 [4] = x4; 2874 dPtr32 [5] = x5; 2875 dPtr32 [6] = x6; 2876 dPtr32 [7] = x7; 2877 2878 dPtr32 += 8; 2879 2880 } 2881 2882 // Process remaining columns. 2883 2884 for (uint32 j = 0; j < count; j++) 2885 { 2886 2887 d2 [j] = map [d2 [j]]; 2888 2889 } 2890 2891 d1 += step1; 2892 2893 } 2894 2895 dPtr += step0; 2896 2897 } 2898 2899 } 2900 2901 else 2902 { 2903 2904 for (uint32 index0 = 0; index0 < count0; index0++) 2905 { 2906 2907 uint16 *d1 = dPtr; 2908 2909 for (uint32 index1 = 0; index1 < count1; index1++) 2910 { 2911 2912 uint16 *d2 = d1; 2913 2914 for (uint32 index2 = 0; index2 < count2; index2++) 2915 { 2916 2917 d2 [0] = map [d2 [0]]; 2918 2919 d2 += step2; 2920 2921 } 2922 2923 d1 += step1; 2924 2925 } 2926 2927 dPtr += step0; 2928 2929 } 2930 2931 } 2932 2933 } 2934 2935 /*****************************************************************************/ 2936 2937 void RefBaselineMapPoly32 (real32 *dPtr, 2938 const int32 rowStep, 2939 const uint32 rows, 2940 const uint32 cols, 2941 const uint32 rowPitch, 2942 const uint32 colPitch, 2943 const real32 *coefficients, 2944 const uint32 degree, 2945 uint16 blackLevel) 2946 { 2947 2948 real32 blackScale1 = 1.0f; 2949 real32 blackScale2 = 1.0f; 2950 real32 blackOffset1 = 0.0f; 2951 real32 blackOffset2 = 0.0f; 2952 2953 if (blackLevel != 0) 2954 { 2955 2956 blackOffset2 = ((real32) blackLevel) / 65535.0f; 2957 blackScale2 = 1.0f - blackOffset2; 2958 blackScale1 = 1.0f / blackScale2; 2959 blackOffset1 = 1.0f - blackScale1; 2960 2961 } 2962 2963 for (uint32 row = 0; row < rows; row += rowPitch) 2964 { 2965 2966 if (blackLevel != 0) 2967 { 2968 2969 for (uint32 col = 0; col < cols; col += colPitch) 2970 { 2971 2972 dPtr [col] = dPtr [col] * blackScale1 + blackOffset1; 2973 2974 } 2975 2976 } 2977 2978 switch (degree) 2979 { 2980 2981 case 0: 2982 { 2983 2984 real32 y = Pin_real32 (-1.0f, 2985 coefficients [0], 2986 1.0f); 2987 2988 for (uint32 col = 0; col < cols; col += colPitch) 2989 { 2990 2991 dPtr [col] = y; 2992 2993 } 2994 2995 break; 2996 2997 } 2998 2999 case 1: 3000 { 3001 3002 for (uint32 col = 0; col < cols; col += colPitch) 3003 { 3004 3005 real32 x = dPtr [col]; 3006 3007 real32 y = coefficients [0] + x * coefficients [1]; 3008 3009 dPtr [col] = Pin_real32 (-1.0f, y, 1.0f); 3010 3011 } 3012 3013 break; 3014 3015 } 3016 3017 case 2: 3018 { 3019 3020 for (uint32 col = 0; col < cols; col += colPitch) 3021 { 3022 3023 real32 x = dPtr [col]; 3024 3025 real32 y; 3026 3027 if (x < 0.0f) 3028 { 3029 3030 y = coefficients [0] + x * 3031 (coefficients [1] - x * 3032 (coefficients [2])); 3033 3034 } 3035 3036 else 3037 { 3038 3039 y = coefficients [0] + x * 3040 (coefficients [1] + x * 3041 (coefficients [2])); 3042 3043 } 3044 3045 dPtr [col] = Pin_real32 (-1.0f, y, 1.0f); 3046 3047 } 3048 3049 break; 3050 3051 } 3052 3053 case 3: 3054 { 3055 3056 for (uint32 col = 0; col < cols; col += colPitch) 3057 { 3058 3059 real32 x = dPtr [col]; 3060 3061 real32 y; 3062 3063 if (x < 0.0f) 3064 { 3065 3066 y = coefficients [0] + x * 3067 (coefficients [1] - x * 3068 (coefficients [2] - x * 3069 (coefficients [3]))); 3070 3071 } 3072 3073 else 3074 { 3075 3076 y = coefficients [0] + x * 3077 (coefficients [1] + x * 3078 (coefficients [2] + x * 3079 (coefficients [3]))); 3080 3081 } 3082 3083 dPtr [col] = Pin_real32 (-1.0f, y, 1.0f); 3084 3085 } 3086 3087 break; 3088 3089 } 3090 3091 case 4: 3092 { 3093 3094 for (uint32 col = 0; col < cols; col += colPitch) 3095 { 3096 3097 real32 x = dPtr [col]; 3098 3099 real32 y; 3100 3101 if (x < 0.0f) 3102 { 3103 3104 y = coefficients [0] + x * 3105 (coefficients [1] - x * 3106 (coefficients [2] - x * 3107 (coefficients [3] - x * 3108 (coefficients [4])))); 3109 3110 } 3111 3112 else 3113 { 3114 3115 y = coefficients [0] + x * 3116 (coefficients [1] + x * 3117 (coefficients [2] + x * 3118 (coefficients [3] + x * 3119 (coefficients [4])))); 3120 3121 } 3122 3123 dPtr [col] = Pin_real32 (-1.0f, y, 1.0f); 3124 3125 } 3126 3127 break; 3128 3129 } 3130 3131 default: 3132 { 3133 3134 for (uint32 col = 0; col < cols; col += colPitch) 3135 { 3136 3137 real32 x = dPtr [col]; 3138 3139 real32 y = coefficients [0]; 3140 3141 if (x < 0.0f) 3142 { 3143 3144 x = -x; 3145 3146 real32 xx = x; 3147 3148 for (uint32 j = 1; j <= degree; j++) 3149 { 3150 3151 y -= coefficients [j] * xx; 3152 3153 xx *= x; 3154 3155 } 3156 3157 } 3158 3159 else 3160 { 3161 3162 real32 xx = x; 3163 3164 for (uint32 j = 1; j <= degree; j++) 3165 { 3166 3167 y += coefficients [j] * xx; 3168 3169 xx *= x; 3170 3171 } 3172 3173 } 3174 3175 dPtr [col] = Pin_real32 (-1.0f, y, 1.0f); 3176 3177 } 3178 3179 } 3180 3181 } 3182 3183 if (blackLevel != 0) 3184 { 3185 3186 for (uint32 col = 0; col < cols; col += colPitch) 3187 { 3188 3189 dPtr [col] = dPtr [col] * blackScale2 + blackOffset2; 3190 3191 } 3192 3193 } 3194 3195 // Advance to the next row. Note that rowStep already accounts for the 3196 // row pitch. 3197 3198 dPtr += rowStep; 3199 3200 } 3201 3202 } 3203 3204 /*****************************************************************************/