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 /*****************************************************************************/