test: lh_core/fragment.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# fragment.c File Reference

`#include "General.h"`
`#include <math.h>`
`#include "Fragment.h"`
`#include "StdConv.h"`

Go to the source code of this file.

## Defines

#define | CM_Doub double

## Functions

void | InvLut1dExceptions (unsigned short *inCurve, unsigned long inCount, unsigned short *outCurve, UINT8 AdressBits)
CMError | Fill_ushort_ELUT_Gamma (unsigned short *usELUT, char addrBits, char usedBits, long gridPoints, unsigned short gamma_u8_8)
void | Fill_inverseGamma_byte_ALUT (unsigned char *ucALUT, char addrBits, unsigned short gamma_u8_8)
icCurveType * | InvertLut1d (icCurveType *LookUpTable, UINT8 AdressBits)
CMError | CombiMatrix (icXYZType srcColorantData[3], icXYZType destColorantData[3], double resMatrix[3][3])
Boolean | doubMatrixInvert (double MatHin[3][3], double MatRueck[3][3])
CMError | Fill_ushort_ELUT_from_CurveTag (icCurveType *pCurveTag, unsigned short *usELUT, char addrBits, char usedBits, long gridPoints)
CMError | Fill_ushort_ELUT_identical (UINT16 *usELUT, char addrBits, char usedBits, long gridPoints)
CMError | Fill_inverse_byte_ALUT_from_CurveTag (icCurveType *pCurveTag, unsigned char *ucALUT, char addrBits)
CMError | Fill_ushort_ELUTs_from_lut8Tag (CMLutParamPtr theLutData, Ptr profileELuts, char addrBits, char usedBits, long gridPoints)
CMError | Fill_byte_ALUTs_from_lut8Tag (CMLutParamPtr theLutData, Ptr profileALuts, char addrBits)
CMError | Fill_ushort_ELUTs_from_lut16Tag (CMLutParamPtr theLutData, Ptr profileELuts, char addrBits, char usedBits, long gridPoints, long inputTableEntries)
CMError | Fill_byte_ALUTs_from_lut16Tag (CMLutParamPtr theLutData, Ptr profileALuts, char addrBits, long outputTableEntries)
CMError | MakeGamut16or32ForMonitor (icXYZType *pRedXYZ, icXYZType *pGreenXYZ, icXYZType *pBlueXYZ, CMLutParamPtr theLutData, Boolean cube32Flag)

## Define Documentation

#define CM_Doub double

| Definition at line 22 of file lh_core/fragment.c. Referenced by Fill_inverseGamma_byte_ALUT(), Fill_inverseGamma_ushort_ALUT(), Fill_ushort_ELUT_Gamma(), and InvLut1dExceptions().

## Function Documentation

CMError CombiMatrix | ( | icXYZType | srcColorantData[3],
|  | icXYZType | destColorantData[3],
|  | double | resMatrix[3][3]
| ) |

Definition at line 317 of file lh_core/fragment.c.

    00320 {
    00321         short           i, j;
    00322         double          straightMat[3][3], invMat[3][3];
    00323         CMError         err = noErr;
    00324
    00325         LH_START_PROC("CombiMatrix")
    00326                 /* RGB -> XYZ for first profile: */
    00327         straightMat[0][0] = (double)srcColorantData[0].data.data[0].X;
    00328         straightMat[1][0] = (double)srcColorantData[0].data.data[0].Y;
    00329         straightMat[2][0] = (double)srcColorantData[0].data.data[0].Z;
    00330
    00331         straightMat[0][1] = (double)srcColorantData[1].data.data[0].X;
    00332         straightMat[1][1] = (double)srcColorantData[1].data.data[0].Y;
    00333         straightMat[2][1] = (double)srcColorantData[1].data.data[0].Z;
    00334
    00335         straightMat[0][2] = (double)srcColorantData[2].data.data[0].X;
    00336         straightMat[1][2] = (double)srcColorantData[2].data.data[0].Y;
    00337         straightMat[2][2] = (double)srcColorantData[2].data.data[0].Z;
    00338
    00339                 /* RGB -> XYZ for 2nd profile, store in resMatrix prelim.: */
    00340         resMatrix[0][0] = (double)destColorantData[0].data.data[0].X;
    00341         resMatrix[1][0] = (double)destColorantData[0].data.data[0].Y;
    00342         resMatrix[2][0] = (double)destColorantData[0].data.data[0].Z;
    00343
    00344         resMatrix[0][1] = (double)destColorantData[1].data.data[0].X;
    00345         resMatrix[1][1] = (double)destColorantData[1].data.data[0].Y;
    00346         resMatrix[2][1] = (double)destColorantData[1].data.data[0].Z;
    00347
    00348         resMatrix[0][2] = (double)destColorantData[2].data.data[0].X;
    00349         resMatrix[1][2] = (double)destColorantData[2].data.data[0].Y;
    00350         resMatrix[2][2] = (double)destColorantData[2].data.data[0].Z;
    00351
    00352         if( !doubMatrixInvert(resMatrix, invMat) )
    00353         {
    00354 #ifdef DEBUG_OUTPUT
    00355         if ( DebugCheck(kThisFile, kDebugErrorInfo) )
    00356             DebugPrint("¥ CombiMatrix-Error: doubMatrixInvert failed \n");
    00357 #endif
    00358                 err = cmparamErr;
    00359                 goto CleanupAndExit;
    00360         }
    00361
    00362         for(i=0; i<3; i++)
    00363                 for(j=0; j<3; j++)
    00364                         resMatrix[i][j] = straightMat[i][0] * invMat[0][j]
    00365                                                         + straightMat[i][1] * invMat[1][j]
    00366                                                         + straightMat[i][2] * invMat[2][j];
    00367 CleanupAndExit:
    00368         LH_END_PROC("CombiMatrix")
    00369         return err;
    00370 }

Boolean doubMatrixInvert | ( | double | MatHin[3][3],
|  | double | MatRueck[3][3]
| ) |

Definition at line 389 of file lh_core/fragment.c.

    00390 {
    00391         double  detm, hilf1, hilf2, hilf3, hilf4, hilf5, hilf6;
    00392         double  *a;
    00393         Boolean success = TRUE;
    00394 #ifdef DEBUG_OUTPUT
    00395         CMError err=noErr;
    00396 #endif
    00397         LH_START_PROC("doubMatrixInvert")
    00398         a = (double *)MatHin;
    00399
    00400         hilf1 = a[0] * a[4];
    00401         hilf2 = a[1] * a[5];
    00402         hilf3 = a[2] * a[3];
    00403         hilf4 = a[2] * a[4];
    00404         hilf5 = a[1] * a[3];
    00405         hilf6 = a[0] * a[5];
    00406
    00407         detm = hilf1 * a[8] + hilf2 * a[6]
    00408                  + hilf3 * a[7] - hilf4 * a[6]
    00409                  - hilf5 * a[8] - hilf6 * a[7];
    00410
    00411         /*      if(fabs(detm) < 1.E-9) */
    00412         if ( (detm < 1.E-9) && (detm > -1.E-9) )
    00413         success = FALSE;
    00414         else
    00415         {
    00416                 detm = 1. / detm;
    00417
    00418                 MatRueck[0][0] = (a[4] * a[8] - a[5] * a[7]) * detm;
    00419                 MatRueck[0][1] = (a[7] * a[2] - a[8] * a[1]) * detm;
    00420                 MatRueck[0][2] = (hilf2       - hilf4      ) * detm;
    00421
    00422                 MatRueck[1][0] = (a[5] * a[6] - a[3] * a[8]) * detm;
    00423                 MatRueck[1][1] = (a[8] * a[0] - a[6] * a[2]) * detm;
    00424                 MatRueck[1][2] = (hilf3       - hilf6      ) * detm;
    00425
    00426                 MatRueck[2][0] = (a[3] * a[7] - a[4] * a[6]) * detm;
    00427                 MatRueck[2][1] = (a[6] * a[1] - a[7] * a[0]) * detm;
    00428                 MatRueck[2][2] = (hilf1       - hilf5      ) * detm;
    00429         }
    00430
    00431         LH_END_PROC("doubMatrixInvert")
    00432     return(success);
    00433 }

CMError Fill_byte_ALUTs_from_lut16Tag | ( | CMLutParamPtr | theLutData,
|  | Ptr | profileALuts,
|  | char | addrBits,
|  | long | outputTableEntries
| ) |

Definition at line 1237 of file lh_core/fragment.c.

    01241 {
    01242         long                    i, j;
    01243         UINT16                  *curOutLut;
    01244         UINT8                   *curALUT;
    01245         long                    count, clipIndex, outTabLen;
    01246         long                    indFactor, fract, baseInd, lAux;
    01247         UINT16                  *profALUTs = (UINT16*)profileALuts;
    01248         OSErr                   err = noErr;
    01249         LUT_DATA_TYPE   localAlut = nil;
    01250         UINT8                   *localAlutPtr;
    01251         long                    theAlutSize;
    01252
    01253         LH_START_PROC("Fill_byte_ALUTs_from_lut16Tag")
    01254
    01255         count     = 1 << addrBits;                                                              /* addrBits is always >= 8 */
    01256         clipIndex = (1 << addrBits) - (1 << (addrBits - 8));    /* max XLUT output with 10 bit is at 1020, not at1023 */
    01257
    01258         theAlutSize = theLutData->colorLutOutDim * count;
    01259         localAlut   = ALLOC_DATA(theAlutSize + 1, &err);
    01260         if (err)
    01261                 goto CleanupAndExit;
    01262
    01263         outTabLen = outputTableEntries;                                 /* <= 4096 */
    01264         indFactor = ((outTabLen - 1) << 18) / clipIndex;        /* for adjusting the indices */
    01265
    01266         LOCK_DATA(localAlut);
    01267         localAlutPtr = (UINT8*)DATA_2_PTR(localAlut);
    01268
    01269         for(i=0; i<theLutData->colorLutOutDim; i++)
    01270         {
    01271                 curOutLut = profALUTs + i * outTabLen;
    01272                 curALUT   = localAlutPtr + i * count;
    01273
    01274                 for(j=0; j<=clipIndex; j++)
    01275                 {
    01276                         lAux    = (j * indFactor+32) >> 6;
    01277                         baseInd = lAux >> 12;
    01278                         fract   = lAux & 0x0FFF;
    01279
    01280                         if(fract)
    01281                         {
    01282                                 lAux = (long)curOutLut[baseInd + 1] - (long)curOutLut[baseInd];
    01283                                 lAux = (lAux * fract + 0x0800) >> 12;
    01284
    01285                                 curALUT[j] = (UINT8)(((long)curOutLut[baseInd] + lAux) >> 8);
    01286                         }
    01287                         else
    01288                                 curALUT[j] = curOutLut[baseInd] >> 8;
    01289                 }
    01290
    01291                 for(j=clipIndex+1; j<count; j++)                /* unused indices, clip these */
    01292                         curALUT[j] = curALUT[clipIndex];
    01293         }
    01294
    01295         UNLOCK_DATA(localAlut);
    01296         theLutData->outputLut = localAlut;
    01297         localAlut = nil;
    01298 CleanupAndExit:
    01299         localAlut = DISPOSE_IF_DATA(localAlut);
    01300
    01301         LH_END_PROC("Fill_byte_ALUTs_from_lut16Tag")
    01302         return err;
    01303 }

CMError Fill_byte_ALUTs_from_lut8Tag | ( | CMLutParamPtr | theLutData,
|  | Ptr | profileALuts,
|  | char | addrBits
| ) |

Definition at line 1028 of file lh_core/fragment.c.

    01031 {
    01032         long                    i, j;
    01033         UINT8                   *curOutLut;
    01034         UINT8                   *profAluts = (UINT8*)profileALuts;
    01035         UINT8                   *curALUT;
    01036         long                    count, clipIndex;
    01037         long                    factor, fract, baseInd, lAux;
    01038         OSErr                   err = noErr;
    01039         LUT_DATA_TYPE   localAlut = nil;
    01040         UINT8                   *localAlutPtr;
    01041         long                    theAlutSize;
    01042
    01043         LH_START_PROC("Fill_byte_ALUTs_from_lut8Tag")
    01044
    01045         count     = 1 << addrBits;                                                              /* addrBits is always >= 8 */
    01046         clipIndex = (1 << addrBits) - (1 << (addrBits - 8));    /* max XLUT output with 10 bit is at 1020, not at1023 */
    01047
    01048         theAlutSize = theLutData->colorLutOutDim * count;
    01049         localAlut   = ALLOC_DATA(theAlutSize + 1, &err);
    01050         if (err)
    01051                 goto CleanupAndExit;
    01052
    01053         LOCK_DATA(localAlut);
    01054         localAlutPtr = (UINT8*)DATA_2_PTR(localAlut);
    01055
    01056         factor = (255 << 12) / clipIndex;               /* for adjusting the indices */
    01057
    01058         for(i=0; i<theLutData->colorLutOutDim; i++)
    01059         {
    01060                 curOutLut = profAluts + (i << 8);
    01061                 curALUT   = localAlutPtr + i * count;
    01062
    01063                 for(j=0; j<=clipIndex; j++)
    01064                 {
    01065                         lAux    = j * factor;
    01066                         baseInd = lAux >> 12;
    01067                         fract   = lAux & 0x0FFF;
    01068
    01069                         if(fract)
    01070                         {
    01071                                 lAux = (long)curOutLut[baseInd + 1] - (long)curOutLut[baseInd];
    01072                                 lAux = (lAux * fract + 0x0800) >> 12;
    01073
    01074                                 curALUT[j] = (UINT8)((long)curOutLut[baseInd] + lAux);
    01075                         }
    01076                         else
    01077                                 curALUT[j] = curOutLut[baseInd];
    01078                 }
    01079
    01080                 for(j=clipIndex+1; j<count; j++)                /* unused indices, clip these */
    01081                         curALUT[j] = curALUT[clipIndex];
    01082         }
    01083
    01084         UNLOCK_DATA(localAlut);
    01085         theLutData->outputLut = localAlut;
    01086         localAlut = nil;
    01087 CleanupAndExit:
    01088         localAlut = DISPOSE_IF_DATA(localAlut);
    01089         LH_END_PROC("Fill_byte_ALUTs_from_lut8Tag")
    01090         return err;
    01091 }

CMError Fill_inverse_byte_ALUT_from_CurveTag | ( | icCurveType * | pCurveTag,
|  | unsigned char * | ucALUT,
|  | char | addrBits
| ) |

Definition at line 692 of file lh_core/fragment.c.

References icCurveType::base, CMError, cmparamErr, icCurve::count, icCurveType::curve, icCurve::data, DebugPrint, Fill_inverseGamma_byte_ALUT(), icSigCurveType, LH_END_PROC, LH_START_PROC, noErr, and icTagBase::sig.

    00695 {
    00696         unsigned long   i, inCount, outCount;
    00697         unsigned long   intpFirst, intpLast, halfStep, ulAux, target;
    00698         short                   monot;
    00699         unsigned short  *inCurve, *usPtr, *stopPtr;
    00700         double                  flFactor;
    00701         char                    baseShift;
    00702         unsigned long   clipIndex;
    00703         CMError                 err = noErr;
    00704
    00705         LH_START_PROC("Fill_inverse_byte_ALUT_from_CurveTag")
    00706
    00707     if( pCurveTag->base.sig != icSigCurveType   /* 'curv' */
    00708      || addrBits > 15 )
    00709     {
    00710 #ifdef DEBUG_OUTPUT
    00711         if ( DebugCheck(kThisFile, kDebugErrorInfo) )
    00712             DebugPrint("¥ Fill_inverse_byte_ALUT_from_CurveTag ERROR:  addrBits = %d\n",addrBits);
    00713 #endif
    00714                 err = cmparamErr;
    00715                 goto CleanupAndExit;
    00716         }
    00717
    00718         outCount = 0x1 << addrBits;
    00719
    00720                 /*---special cases:---*/
    00721
    00722         if(pCurveTag->curve.count == 0)         /*---identity---*/
    00723         {
    00724                 baseShift = addrBits - 8;               /* >= 0, we need at least 256 values */
    00725
    00726                 for(i=0; i<outCount; i++)
    00727                         ucALUT[i] = (unsigned char)(i >> baseShift);
    00728
    00729                 goto CleanupAndExit;
    00730         }
    00731         else if(pCurveTag->curve.count == 1)    /*---gamma curve---*/
    00732         {
    00733                 Fill_inverseGamma_byte_ALUT(ucALUT, addrBits, pCurveTag->curve.data[0]);
    00734                 goto CleanupAndExit;
    00735         }
    00736
    00737                 /*---ordinary case:---*/
    00738
    00739         inCount = pCurveTag->curve.count;
    00740         inCurve = pCurveTag->curve.data;
    00741
    00742                  /* exact matching factor needed for special values: */
    00743         clipIndex = (1 << addrBits) - (1 << (addrBits - 8)); /* max XLUT output with 10 bit is at 1020, not at1023 */
    00744         flFactor  = (double)clipIndex / 65535.;
    00745
    00746         halfStep = outCount >> 1;               /* lessen computation incorrectness */
    00747
    00748                                 /* ascending or descending ? */
    00749         for(monot=0, i=1; i<inCount; i++)
    00750         {
    00751                 if(inCurve[i-1] < inCurve[i])
    00752                         monot++;
    00753                 else if(inCurve[i-1] > inCurve[i])
    00754                         monot--;
    00755         }
    00756
    00757         if(monot >= 0)  /* curve seems to be ascending */
    00758         {
    00759                 for(i=1; i<inCount; i++)
    00760                         if(inCurve[i-1] > inCurve[i])
    00761                                 inCurve[i] = inCurve[i-1];
    00762
    00763                 intpFirst = (unsigned long)(inCurve[0] * flFactor + 0.9999);
    00764                 intpLast  = (unsigned long)(inCurve[inCount-1] * flFactor);
    00765
    00766                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00767                         ucALUT[i] = 0;
    00768                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00769                         ucALUT[i] = 0xFF;
    00770
    00771                         /* interpolate remaining values: */
    00772                 usPtr   = inCurve;
    00773                 stopPtr = inCurve + inCount - 2; /* stops incrementation */
    00774
    00775                 for(i=intpFirst; i<=intpLast; i++)
    00776                 {
    00777                         target = (0x0FFFF * i + halfStep)  / (outCount - 1);
    00778                         while(*(usPtr+1) < target && usPtr < stopPtr)
    00779                                 usPtr++;                                        /* find interval */
    00780
    00781                         ulAux = ((unsigned long)(usPtr - inCurve) << 16) / (inCount - 1);
    00782                         if(*(usPtr+1) != *usPtr)
    00783                         {
    00784                                 ulAux += ((target - (unsigned long)*usPtr) << 16)
    00785                                           / ( (*(usPtr+1) - *usPtr) * (inCount - 1) );
    00786
    00787                                 if(ulAux & 0x10000)   /* *(usPtr+1) was required */
    00788                                         ulAux = 0x0FFFF;
    00789                         }
    00790
    00791                         ucALUT[i] = (unsigned char)(ulAux >> 8);
    00792                 }
    00793         }
    00794         else                    /* curve seems to be descending */
    00795         {
    00796                 for(i=1; i<inCount; i++)
    00797                         if(inCurve[i-1] < inCurve[i])
    00798                                 inCurve[i] = inCurve[i-1];
    00799
    00800                 intpFirst = (unsigned long)(inCurve[inCount-1] * flFactor + 0.9999);
    00801                 intpLast  = (unsigned long)(inCurve[0] * flFactor);
    00802
    00803                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00804                         ucALUT[i] = 0xFF;
    00805                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00806                         ucALUT[i] = 0;
    00807
    00808                         /* interpolate remaining values: */
    00809                 usPtr   = inCurve + inCount - 1;
    00810                 stopPtr = inCurve + 1;          /* stops decrementation */
    00811
    00812                 for(i=intpFirst; i<=intpLast; i++)
    00813                 {
    00814                         target = (0x0FFFF * i + halfStep)  / (outCount - 1);
    00815                         while(*(usPtr-1) < target && usPtr > stopPtr)
    00816                                 usPtr--;                                        /* find interval */
    00817
    00818                         ulAux = ((unsigned long)(usPtr-1 - inCurve) << 16) / (inCount - 1);
    00819                         if(*(usPtr-1) != *usPtr)
    00820                         {
    00821                                 ulAux += (((unsigned long)*(usPtr-1) - target) << 16)
    00822                                           / ( (*(usPtr-1) - *usPtr) * (inCount - 1) );
    00823
    00824                                 if(ulAux & 0x10000)
    00825                                         ulAux = 0x0FFFF;
    00826                         }
    00827
    00828             ucALUT[i] = (unsigned char)(ulAux >> 8);
    00829                 }
    00830         }
    00831
    00832 CleanupAndExit:
    00833         LH_END_PROC("Fill_inverse_byte_ALUT_from_CurveTag")
    00834         return(noErr);
    00835 }

void Fill_inverseGamma_byte_ALUT | ( | unsigned char * | ucALUT,
|  | char | addrBits,
|  | unsigned short | gamma_u8_8
| ) |

Definition at line 839 of file lh_core/fragment.c.

References CM_Doub, CMError, LH_END_PROC, LH_START_PROC, and noErr.

    00842 {
    00843         unsigned long   i, j, outCount, step, stopit;
    00844         long                    leftVal, Diff, lAux;
    00845         CM_Doub                 invGamma, x, xFactor;
    00846     unsigned long       clipIndex;
    00847 #ifdef DEBUG_OUTPUT
    00848         CMError                 err=noErr;
    00849 #endif
    00850
    00851         LH_START_PROC("Fill_inverseGamma_byte_ALUT")
    00852
    00853         outCount = 0x1 << addrBits;
    00854
    00855         invGamma  = 256. / (CM_Doub)gamma_u8_8;
    00856         clipIndex = (1 << addrBits) - (1 << (addrBits - 8)); /* max XLUT output with 10 bit is at 1020, not at1023 */
    00857         xFactor   = 1. / (CM_Doub)clipIndex;
    00858
    00859         if(addrBits <= 6)               /* up to 64 - 2 float.computations */
    00860                 step = 1;
    00861         else
    00862                 step = 0x1 << (addrBits - 6);           /* more would take too long */
    00863
    00864         ucALUT[0]          = 0;                 /* these two... */
    00865         ucALUT[outCount-1] = 0xFF;              /* ...are fixed */
    00866
    00867         for(i=step; i<outCount-1; i+=step)
    00868         {
    00869                 x = (CM_Doub)i * xFactor;
    00870                 if(x > 1.)
    00871                         x = 1.;         /* clipping in the end of ALUT */
    00872
    00873                 ucALUT[i] = (unsigned char)( pow(x,invGamma) * 255.0 + 0.5);
    00874         }
    00875
    00876                 /*---fill intervals - except for last, which is odd:---*/
    00877         for(i=0; i<outCount-step; i+=step)
    00878         {
    00879                 leftVal = (long)ucALUT[i];
    00880                 Diff    = (long)ucALUT[i + step] - leftVal;
    00881
    00882                 for(j=1; j<step; j++)
    00883                 {
    00884                         lAux = ( (Diff * j << 8) / step + 128 ) >> 8;
    00885
    00886                         ucALUT[i + j] = (unsigned char)(leftVal + lAux);
    00887                 }
    00888         }
    00889
    00890                 /*---fill last interval:---*/
    00891         i       = outCount - step;
    00892         leftVal = (long)ucALUT[i];
    00893         Diff    = 0x0FF - leftVal;      /* 0xFF for 1.0 */
    00894
    00895         for(j=1; j<step-1; j++)         /* stops here if step <= 2 */
    00896         {
    00897                 lAux = ( (Diff * j << 8) / (step - 1) + 128 ) >> 8;
    00898
    00899                 ucALUT[i + j] = (unsigned char)(leftVal + lAux);
    00900         }
    00901
    00902                 /*--overwrite sensitive values depending on Gamma:--*/
    00903         if(addrBits > 6 && invGamma < 1.0)              /* ...if lower part is difficult */
    00904         {
    00905                 stopit = 0x1 << (addrBits - 6);
    00906
    00907                 for(i=1; i<stopit; i++)
    00908                 {
    00909                         x         = (CM_Doub)i * xFactor;
    00910                         ucALUT[i] = (unsigned char)( pow(x,invGamma) * 255.0);
    00911                 }
    00912         }
    00913         LH_END_PROC("Fill_inverseGamma_byte_ALUT")
    00914 }

CMError Fill_ushort_ELUT_from_CurveTag | ( | icCurveType * | pCurveTag,
|  | unsigned short * | usELUT,
|  | char | addrBits,
|  | char | usedBits,
|  | long | gridPoints
| ) |

Definition at line 460 of file lh_core/fragment.c.

References CMError, cmparamErr, icCurve::count, icCurveType::curve, icCurve::data, Fill_ushort_ELUT_Gamma(), Fill_ushort_ELUT_identical(), L, LH_END_PROC, LH_START_PROC, and noErr.

    00465 {
    00466         long                    i, count, indFactor, outFactor, baseInd, maxOut;
    00467         long                    fract, lAux, diff, outRound, outShift, interpRound, interpShift;
    00468         unsigned short  *usCurv;
    00469         double                  dFactor;
    00470         CMError                 err = noErr;
    00471
    00472         LH_START_PROC("Fill_ushort_ELUT_from_CurveTag")
    00473                 /*---special cases:---*/
    00474
    00475         if(pCurveTag->curve.count == 0)         /* identity curve */
    00476         {
    00477                 err = Fill_ushort_ELUT_identical(usELUT, addrBits, usedBits, gridPoints);
    00478                 goto CleanupAndExit;
    00479         }
    00480
    00481         if(pCurveTag->curve.count == 1)         /* Gamma  curve */
    00482         {
    00483                 err = Fill_ushort_ELUT_Gamma(usELUT, addrBits, usedBits, gridPoints, pCurveTag->curve.data[0]);
    00484                 goto CleanupAndExit;
    00485         }
    00486                 /*---ordinary case:---*/
    00487
    00488         if(addrBits > 15)
    00489         {
    00490                 err = cmparamErr;       /* would lead to overflow */
    00491                 goto CleanupAndExit;
    00492         }
    00493
    00494         count     = 1 << addrBits;
    00495         indFactor = ((pCurveTag->curve.count - 1) << 18) / (count - 1); /* for adjusting indices */
    00496
    00497         if(usedBits < 8)
    00498         {
    00499                 err = cmparamErr;
    00500                 goto CleanupAndExit;
    00501         }
    00502
    00503         if(gridPoints == 0)
    00504                 maxOut = 65535;
    00505         else
    00506                 maxOut = ((1L << (usedBits - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    00507
    00508                 /*-----find factor for the values that fits in 15 bits------*/
    00509                 /* (product with 16 bit number must fit in 31 bit uns.long)     */
    00510                 /* n.b: 512 <= maxOut <= 65535  in all possible cases           */
    00511
    00512         dFactor  = (double)maxOut / 65535.;             /* 65535 is max. curve value */
    00513         dFactor *= 4194304.;                                    /* same as << 22, certainly too much */
    00514
    00515         outFactor = (long)dFactor;
    00516         outRound  = (1L << 21) - 1;
    00517         outShift  = 22;
    00518         while(outFactor & 0xFFF8000)    /* stay within 15 bits to prevent product overflow */
    00519         {
    00520                 outFactor >>= 1;
    00521                 outRound  >>= 1;
    00522                 outShift   -= 1;
    00523         }
    00524
    00525         interpRound = outRound >> 1;    /* with interpolation we have an additional...  */
    00526         interpShift = outShift  - 1;    /* ... >> 1 because we must add two nunmbers    */
    00527
    00528         usCurv = pCurveTag->curve.data;
    00529
    00530         for(i=0; i<count; i++)
    00531         {
    00532                 lAux    = (i * indFactor+4) >> 3;
    00533                 baseInd = (unsigned long)lAux >> 15;
    00534                 fract   = lAux & 0x7FFF;                /* 15 bits for interpolation */
    00535
    00536                 if(fract)               /* interpolation necessary ? */
    00537                 {
    00538                         lAux = (long)usCurv[baseInd] * outFactor >> 1;
    00539
    00540                         diff = (long)usCurv[baseInd+1] - (long)usCurv[baseInd];
    00541                         diff = (diff * outFactor >> 15) * fract >> 1;
    00542
    00543                         usELUT[i] = (unsigned short)( (lAux + diff + interpRound) >> interpShift );
    00544                 }
    00545                 else
    00546                         usELUT[i] = (unsigned short)( ((long)usCurv[baseInd]
    00547                                                                                                 * outFactor + outRound) >> outShift );
    00548         }
    00549
    00550 CleanupAndExit:
    00551         LH_END_PROC("Fill_ushort_ELUT_from_CurveTag")
    00552         return(noErr);
    00553 }

CMError Fill_ushort_ELUT_Gamma | ( | unsigned short * | usELUT,
|  | char | addrBits,
|  | char | usedBits,
|  | long | gridPoints,
|  | unsigned short | gamma_u8_8
| ) |

Definition at line 590 of file lh_core/fragment.c.

References CM_Doub, CMError, L, LH_END_PROC, LH_START_PROC, noErr, and UINT16.

    00595 {
    00596         unsigned long   i, j, outCount, step, stopit;
    00597         CM_Doub                 gamma, x, xFactor;
    00598         long                    leftVal, Diff, lAux, maxOut;
    00599 #ifdef DEBUG_OUTPUT
    00600         CMError                 err=noErr;
    00601 #endif
    00602
    00603         LH_START_PROC("Fill_ushort_ELUT_Gamma")
    00604         outCount = 0x1 << addrBits;
    00605         if(gridPoints == 0)
    00606                 maxOut = 65535;
    00607         else
    00608                 maxOut = ((1L << (usedBits - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    00609
    00610         gamma   = ((CM_Doub)gamma_u8_8 * 3.90625E-3);   /* / 256.0 */
    00611         xFactor = 1. / (CM_Doub)(outCount - 1);
    00612
    00613         if(addrBits <= 6)               /* up to 64 - 2 float.computations */
    00614                 step = 1;
    00615         else
    00616                 step = 0x1 << (addrBits - 6);           /* would take too long */
    00617
    00618         usELUT[0]          = 0;
    00619     usELUT[outCount-1] = (UINT16)maxOut;
    00620
    00621         for(i=step; i<outCount-1; i+=step)
    00622         {
    00623                 x         = (CM_Doub)i * xFactor;
    00624                 usELUT[i] = (unsigned short)( pow(x,gamma) * maxOut);
    00625         }
    00626
    00627                 /*---fill intervals - except for last, which is odd:---*/
    00628         for(i=0; i<outCount-step; i+=step)
    00629         {
    00630                 leftVal = (long)usELUT[i];
    00631                 Diff    = (long)usELUT[i + step] - leftVal;
    00632
    00633                 for(j=1; j<step; j++)
    00634                 {
    00635                         lAux = ( (Diff * j << 8) / step + 128 ) >> 8;
    00636
    00637                         usELUT[i + j] = (unsigned short)(leftVal + lAux);
    00638                 }
    00639         }
    00640
    00641                 /*---fill last interval:---*/
    00642         i       = outCount - step;
    00643         leftVal = (long)usELUT[i];
    00644         Diff    = maxOut - leftVal;             /* maxOut for 1.0 */
    00645
    00646         for(j=1; j<step-1; j++)         /* stops here if step <= 2 */
    00647         {
    00648                 lAux = ( (Diff * j << 8) / (step - 1) + 128 ) >> 8;
    00649
    00650                 usELUT[i + j] = (unsigned short)(leftVal + lAux);
    00651         }
    00652
    00653                 /* overwrite sensitive values depending on Gamma */
    00654         if(addrBits > 6 && gamma < 1.0) /* lower part is difficult */
    00655         {
    00656                 stopit = 0x1 << (addrBits - 6);
    00657
    00658                 for(i=1; i<stopit; i++)
    00659                 {
    00660                         x = (CM_Doub)i * xFactor;
    00661                         usELUT[i] = (unsigned short)( pow(x,gamma) * maxOut);
    00662                 }
    00663         }
    00664
    00665         LH_END_PROC("Fill_ushort_ELUT_Gamma")
    00666         return(noErr);
    00667 }

CMError Fill_ushort_ELUT_identical | ( | UINT16 * | usELUT,
|  | char | addrBits,
|  | char | usedBits,
|  | long | gridPoints
| ) |

Definition at line 558 of file lh_core/fragment.c.

    00562 {
    00563         long            i, count, factor, maxOut;
    00564         UINT16          *myWPtr;
    00565 #ifdef DEBUG_OUTPUT
    00566         CMError err = noErr;
    00567 #endif
    00568         LH_START_PROC("Fill_ushort_ELUT_identical")
    00569
    00570         count  = 1 << addrBits;
    00571
    00572         if(gridPoints == 0)
    00573                 maxOut = 65535;
    00574         else
    00575                 maxOut = ((1L << (usedBits - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    00576
    00577         factor = (maxOut << 14) / (count - 1);
    00578
    00579         myWPtr = usELUT;
    00580         for(i=0; i<count; i++)
    00581                 *myWPtr++ = (UINT16)((i * factor + 0x2000) >> 14);
    00582
    00583         LH_END_PROC("Fill_ushort_ELUT_identical")
    00584         return(noErr);
    00585 }

CMError Fill_ushort_ELUTs_from_lut16Tag | ( | CMLutParamPtr | theLutData,
|  | Ptr | profileELuts,
|  | char | addrBits,
|  | char | usedBits,
|  | long | gridPoints,
|  | long | inputTableEntries
| ) |

Definition at line 1121 of file lh_core/fragment.c.

    01127 {
    01128         long                    i, j, inTabLen, maxOut;
    01129         UINT16                  *curInLut;
    01130         UINT16                  *curELUT;
    01131         UINT16                  *profELUT = (UINT16*)profileELuts;
    01132         long                    count, outFactor, fract, lAux, diff;
    01133         long                    baseInd, indFactor;
    01134         long                    outRound, outShift, interpRound, interpShift;
    01135         double                  dFactor;
    01136         long                    theElutSize;
    01137         LUT_DATA_TYPE   localElut = nil;
    01138         UINT16                  *localElutPtr;
    01139         OSErr                   err = noErr;
    01140
    01141         LH_START_PROC("Fill_ushort_ELUTs_from_lut16Tag")
    01142
    01143         count     = 1 << addrBits;
    01144         inTabLen  = inputTableEntries;
    01145
    01146         theElutSize = theLutData->colorLutInDim * count * sizeof (UINT16);
    01147         localElut   = ALLOC_DATA(theElutSize + 2, &err);
    01148         if(err)
    01149                 goto CleanupAndExit;
    01150
    01151         indFactor = ((inTabLen - 1) << 18) / (count - 1);       /* for adjusting indices */
    01152
    01153         if(gridPoints == 0)
    01154                 maxOut = 65535;
    01155         else
    01156                 maxOut = ((1L << (usedBits - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    01157
    01158                 /*-----find factor for the values that fits in 15 bits------*/
    01159                 /* (product with 16 bit number must fit in 31 bit uns.long)     */
    01160                 /* n.b: 512 <= maxOut <= 65535  in all possible cases           */
    01161
    01162         dFactor  = (double)maxOut / 65535.;             /* 65535 is max. curve value */
    01163         dFactor *= 4194304.;                                    /* same as << 22, certainly too much */
    01164
    01165         outFactor = (long)dFactor;
    01166         outRound  = (1L << 21) - 1;
    01167         outShift  = 22;
    01168         while(outFactor & 0xFFF8000)    /* stay within 15 bits to prevent product overflow */
    01169         {
    01170                 outFactor >>= 1;
    01171                 outRound  >>= 1;
    01172                 outShift   -= 1;
    01173         }
    01174
    01175         interpRound = outRound >> 1;    /* with interpolation we have an additional...  */
    01176         interpShift = outShift  - 1;    /* ... >> 1 because we must add two nunmbers    */
    01177
    01178         LOCK_DATA(localElut);
    01179         localElutPtr = (UINT16*)DATA_2_PTR(localElut);
    01180
    01181         for(i=0; i<theLutData->colorLutInDim; i++)
    01182         {
    01183                 curInLut = profELUT + (i * inTabLen);
    01184                 curELUT  = localElutPtr + (i * count);
    01185
    01186                 for(j=0; j<count; j++)
    01187                 {
    01188                         lAux    = (j * indFactor+4) >> 3;
    01189                         baseInd = (unsigned long)lAux >> 15;
    01190                         fract   = lAux & 0x7FFF;        /* 15 bits for interpolation */
    01191
    01192                         if(fract)               /* interpolation necessary ? */
    01193                         {
    01194                                 lAux = (long)curInLut[baseInd] * outFactor >> 1;
    01195
    01196                                 diff = (long)curInLut[baseInd+1] - (long)curInLut[baseInd];
    01197                                 diff = ((diff * outFactor >> 15) * fract) >> 1;
    01198
    01199                                 curELUT[j] = (UINT16)( (lAux + diff + interpRound) >> interpShift );
    01200                         }
    01201                         else
    01202                                 curELUT[j] = (UINT16)( ((long)curInLut[baseInd] * outFactor
    01203                                                                                                         + outRound) >> outShift );
    01204                 }
    01205         }
    01206         UNLOCK_DATA(localElut);
    01207         theLutData->inputLut = localElut;
    01208         localElut = nil;
    01209 CleanupAndExit:
    01210         localElut = DISPOSE_IF_DATA(localElut);
    01211         LH_END_PROC("Fill_ushort_ELUTs_from_lut16Tag")
    01212         return err;
    01213 }

CMError Fill_ushort_ELUTs_from_lut8Tag | ( | CMLutParamPtr | theLutData,
|  | Ptr | profileELuts,
|  | char | addrBits,
|  | char | usedBits,
|  | long | gridPoints
| ) |

Definition at line 941 of file lh_core/fragment.c.

    00946 {
    00947         long                    i, j, maxOut;
    00948         UINT8                   *curInLut;
    00949         UINT16                  *curELUT;
    00950         long                    count, indFactor, outFactor, baseInd, fract, lAux, diff;
    00951         LUT_DATA_TYPE   localElut = nil;
    00952         UINT16                  *localElutPtr;
    00953         OSErr                   err = noErr;
    00954         long                    theElutSize;
    00955
    00956         LH_START_PROC("Fill_ushort_ELUTs_from_lut8Tag")
    00957
    00958         count       = 1 << addrBits;
    00959         theElutSize = theLutData->colorLutInDim * count * sizeof (UINT16);
    00960         localElut   = ALLOC_DATA(theElutSize + 2, &err);
    00961         if (err)
    00962                 goto CleanupAndExit;
    00963
    00964         indFactor = (255 << 12) / (count - 1);  /* for adjusting indices */
    00965
    00966         if(gridPoints == 0)
    00967                 maxOut = 65535;
    00968         else
    00969                 maxOut = ((1L << (usedBits - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    00970         outFactor = (maxOut << 12) / 255;                       /* 255 is max. value from mft1 output lut */
    00971
    00972         LOCK_DATA(localElut);
    00973         localElutPtr = (UINT16*)DATA_2_PTR(localElut);
    00974         for(i=0; i<theLutData->colorLutInDim; i++)
    00975         {
    00976                 curInLut = (UINT8*)profileELuts + (i << 8);
    00977                 curELUT  = localElutPtr + i * count;
    00978
    00979                 for(j=0; j<count; j++)
    00980                 {
    00981                         lAux    = j * indFactor;
    00982                         baseInd = lAux >> 12;
    00983                         fract   = (lAux & 0x0FFF) >> 4; /* leaves 8 bits for interpolation as with distortion */
    00984
    00985                         if(fract && baseInd != 255)             /* interpolation necessary ? */
    00986                         {
    00987                                 lAux = (long)curInLut[baseInd] * outFactor >> 6;
    00988
    00989                                 diff = (long)curInLut[baseInd+1] - (long)curInLut[baseInd];
    00990                                 diff = (diff * outFactor >> 6) * fract >> 8;
    00991
    00992                                 curELUT[j] = (UINT16)( (lAux + diff + 32) >> 6 );
    00993                         }
    00994                         else
    00995                                 curELUT[j] = (UINT16)( ((long)curInLut[baseInd]
    00996                                                                                                         * outFactor + 0x0800) >> 12 );
    00997                 }
    00998         }
    00999         UNLOCK_DATA(localElut);
    01000         theLutData->inputLut = localElut;
    01001         localElut = nil;
    01002 CleanupAndExit:
    01003         localElut = DISPOSE_IF_DATA(localElut);
    01004         LH_END_PROC("Fill_ushort_ELUTs_from_lut8Tag")
    01005         return err;
    01006 }

icCurveType* InvertLut1d | ( | icCurveType * | LookUpTable,
|  | UINT8 | AdressBits
| ) |

Definition at line 70 of file lh_core/fragment.c.

    00072 {
    00073         unsigned long   i, inCount, outCount;
    00074         unsigned long   intpFirst, intpLast, halfStep, ulAux, target;
    00075         short                   monot;
    00076         unsigned short  *inCurve, *outCurve, *usPtr, *stopPtr;
    00077         icCurveType             *outCMcurve = nil;
    00078         double                  flFactor;
    00079         OSErr                   err = noErr;
    00080
    00081         LH_START_PROC("InvertLut1d")
    00082
    00083         if( LookUpTable->base.sig != icSigCurveType     /* 'curv' */ || AdressBits > 15 )
    00084                 goto CleanupAndExit;
    00085
    00086         inCount  = LookUpTable->curve.count;
    00087         inCurve  = LookUpTable->curve.data;
    00088         outCount = 0x1 << AdressBits;
    00089
    00090         outCMcurve = (icCurveType *)SmartNewPtr( sizeof(OSType)
    00091                                                                           + 2 * sizeof(unsigned long)
    00092                                                                           + outCount * sizeof(unsigned short), &err );
    00093         if(err)
    00094                 goto CleanupAndExit;
    00095
    00096         outCurve = (unsigned short *)outCMcurve->curve.data;
    00097
    00098         outCMcurve->base.sig    = icSigCurveType;       /* 'curv' */
    00099         outCMcurve->base.reserved[0] = 0x00;
    00100         outCMcurve->base.reserved[1] = 0x00;
    00101         outCMcurve->base.reserved[2] = 0x00;
    00102         outCMcurve->base.reserved[3] = 0x00;
    00103         outCMcurve->curve.count = outCount;
    00104
    00105         if(inCount < 2)         /* 0 or 1 point in LUT */
    00106         {
    00107                 InvLut1dExceptions(inCurve, inCount, outCurve, AdressBits);
    00108                 goto CleanupAndExit;
    00109         }
    00110
    00111                  /* exact matching factor for special values: */
    00112         flFactor = (double)(outCount - 1) / 65535.;
    00113         halfStep = outCount >> 1;               /* lessen computation incorrectness */
    00114
    00115                                 /* ascending or descending ? */
    00116         for(monot=0, i=1; i<inCount; i++)
    00117         {
    00118                 if(inCurve[i-1] < inCurve[i])
    00119                         monot++;
    00120                 else if(inCurve[i-1] > inCurve[i])
    00121                         monot--;
    00122         }
    00123
    00124         if(monot >= 0)  /* curve seems to be ascending */
    00125         {
    00126                 for(i=1; i<inCount; i++)
    00127                         if(inCurve[i-1] > inCurve[i])
    00128                                 inCurve[i] = inCurve[i-1];
    00129
    00130                 intpFirst = (unsigned long)(inCurve[0] * flFactor + 0.9999);
    00131                 intpLast  = (unsigned long)(inCurve[inCount-1] * flFactor);
    00132
    00133                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00134                         outCurve[i] = 0;
    00135                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00136                         outCurve[i] = 0xFFFF;
    00137
    00138                         /* interpolate remaining values: */
    00139                 usPtr   = inCurve;
    00140                 stopPtr = inCurve + inCount - 2; /* stops incrementation */
    00141
    00142                 for(i=intpFirst; i<=intpLast; i++)
    00143                 {
    00144                         target = (0x0FFFF * i + halfStep)  / (outCount - 1);
    00145                         while(*(usPtr+1) < target && usPtr < stopPtr)
    00146                                 usPtr++;                                        /* find interval */
    00147
    00148                         ulAux = ((unsigned long)(usPtr - inCurve) << 16) / (inCount - 1);
    00149                         if(*(usPtr+1) != *usPtr)
    00150                         {
    00151                                 ulAux += ((target - (unsigned long)*usPtr) << 16)
    00152                                           / ( (*(usPtr+1) - *usPtr) * (inCount - 1) );
    00153
    00154                                 if(ulAux & 0x10000)   /* *(usPtr+1) was required */
    00155                                         ulAux = 0xFFFF;
    00156                         }
    00157
    00158                         outCurve[i] = (unsigned short)ulAux;
    00159                 }
    00160         }
    00161         else                    /* curve seems to be descending */
    00162         {
    00163                 for(i=1; i<inCount; i++)
    00164                         if(inCurve[i-1] < inCurve[i])
    00165                                 inCurve[i] = inCurve[i-1];
    00166
    00167                 intpFirst = (unsigned long)(inCurve[inCount-1] * flFactor + 0.9999);
    00168                 intpLast  = (unsigned long)(inCurve[0] * flFactor);
    00169
    00170                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00171                         outCurve[i] = 0xFFFF;
    00172                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00173                         outCurve[i] = 0;
    00174
    00175                         /* interpolate remaining values: */
    00176                 usPtr   = inCurve + inCount - 1;
    00177                 stopPtr = inCurve + 1;          /* stops decrementation */
    00178
    00179                 for(i=intpFirst; i<=intpLast; i++)
    00180                 {
    00181                         target = (0x0FFFF * i + halfStep)  / (outCount - 1);
    00182                         while(*(usPtr-1) < target && usPtr > stopPtr)
    00183                                 usPtr--;                                        /* find interval */
    00184
    00185                         ulAux = ((unsigned long)(usPtr-1 - inCurve) << 16) / (inCount - 1);
    00186                         if(*(usPtr-1) != *usPtr)
    00187                         {
    00188                                 ulAux += (((unsigned long)*(usPtr-1) - target) << 16)
    00189                                           / ( (*(usPtr-1) - *usPtr) * (inCount - 1) );
    00190
    00191                                 if(ulAux & 0x10000)
    00192                                         ulAux = 0x0FFFF;
    00193                         }
    00194
    00195                         outCurve[i] = (unsigned short)ulAux;
    00196                 }
    00197         }
    00198 CleanupAndExit:
    00199         LH_END_PROC("InvertLut1d")
    00200         return(outCMcurve);
    00201 }

void InvLut1dExceptions | ( | unsigned short * | inCurve,
|  | unsigned long | inCount,
|  | unsigned short * | outCurve,
|  | UINT8 | AdressBits
| ) |

Definition at line 224 of file lh_core/fragment.c.

References CM_Doub, CMError, LH_END_PROC, LH_START_PROC, noErr, and UINT8.

    00228 {
    00229         unsigned long   i, outCount, step, oldstep, stopit;
    00230         UINT8                   shiftBits;
    00231         CM_Doub                 invGamma, x, xFactor;
    00232 #ifdef DEBUG_OUTPUT
    00233         CMError                 err = noErr;
    00234 #endif
    00235
    00236         LH_START_PROC("InvLut1dExceptions")
    00237         outCount = 0x1 << AdressBits;
    00238
    00239         if(inCount == 0)        /* identity */
    00240         {
    00241                 shiftBits = 16 - AdressBits;
    00242
    00243                 for(i=0; i<outCount; i++)
    00244                         outCurve[i] = (unsigned short)( (i << shiftBits)
    00245                                                                                   + (i >> AdressBits) );
    00246         }
    00247         else            /* inCount == 1 , gamma */
    00248         {
    00249                 invGamma = 256. / (CM_Doub)inCurve[0];
    00250                 xFactor  = 1. / (CM_Doub)(outCount - 1);
    00251
    00252                 if(AdressBits <= 6)             /* up to 64 - 2 float.computations */
    00253                         step = 1;
    00254                 else
    00255                         step = 0x1 << (AdressBits - 6);         /* would take too long */
    00256
    00257                 outCurve[0]          = 0;
    00258                 outCurve[outCount-1] = 0xFFFF;
    00259
    00260                 for(i=step; i<outCount-1; i+=step)
    00261                 {
    00262                         x = (CM_Doub)i * xFactor;
    00263                         outCurve[i] = (unsigned short)( pow(x,invGamma) * 65535.0);
    00264                 }
    00265
    00266                 while(step > 1)         /* fill remaining values successively */
    00267                 {
    00268                         oldstep = step;
    00269                         step  >>= 1;
    00270
    00271                         stopit = outCount - step;       /* last value afterwards */
    00272
    00273                         for(i=step; i<stopit; i+=oldstep)
    00274                                 outCurve[i] = (unsigned short)( ((long)outCurve[i - step]
    00275                                                                                 + (long)outCurve[i + step]) >> 1 );
    00276
    00277                         if(step != 1)
    00278                                 outCurve[stopit] = (unsigned short)
    00279                                                         ( ((long)outCurve[stopit - step] + 0x0FFFF) >> 1 );
    00280                 }
    00281
    00282                         /* overwrite sensitive values depending on Gamma */
    00283                 if(AdressBits > 6 && invGamma < 1.0)    /* lower part is difficult */
    00284                 {
    00285                         stopit = 0x1 << (AdressBits - 6);
    00286
    00287                         for(i=1; i<stopit; i++)
    00288                         {
    00289                                 x = (CM_Doub)i * xFactor;
    00290                                 outCurve[i] = (unsigned short)( pow(x,invGamma) * 65535.0);
    00291                         }
    00292                 }
    00293         }
    00294         LH_END_PROC("InvLut1dExceptions")
    00295 }

CMError MakeGamut16or32ForMonitor | ( | icXYZType * | pRedXYZ,
|  | icXYZType * | pGreenXYZ,
|  | icXYZType * | pBlueXYZ,
|  | CMLutParamPtr | theLutData,
|  | Boolean | cube32Flag
| ) |

Definition at line 1334 of file lh_core/fragment.c.

    01340 {
    01341         double                  XYZmatrix[3][3], RGBmatrix[3][3];
    01342         double                  sum, dFactor;
    01343         long                    i, j, k, gridPoints, planeCount, totalCount, longMat[9];
    01344         long                    longX, longY, longZ, longR, longG, longB;
    01345         long                    *lPtr, lFactor, maxOut;
    01346         unsigned short  *usPtr;
    01347         unsigned char   *XPtr;
    01348         LUT_DATA_TYPE   tempXLutHdl     = nil;
    01349         LUT_DATA_TYPE   tempELutHdl     = nil;
    01350         LUT_DATA_TYPE   tempALutHdl     = nil;
    01351         unsigned char   *tempXLut       = nil;
    01352         unsigned char   *tempALut       = nil;
    01353         unsigned short  *tempELut       = nil;
    01354         unsigned short  Levels[32];
    01355         OSErr                   err = noErr;
    01356
    01357         LH_START_PROC("MakeGamut16or32ForMonitor")
    01358
    01359         if(theLutData->inputLut != nil || theLutData->colorLut != nil || theLutData->outputLut != nil)
    01360         {
    01361                 err = cmparamErr;
    01362                 goto CleanupAndExit;
    01363         }
    01364
    01365
    01366         /*----------------------------------------------------------------------------------------- E */
    01367         tempELutHdl = ALLOC_DATA(adr_bereich_elut * 3 * sizeof(unsigned short) + 2, &err);  /* +2 extra space for Interpolation */
    01368         if(err)
    01369                 goto CleanupAndExit;
    01370         LOCK_DATA(tempELutHdl);
    01371         tempELut = (unsigned short *)DATA_2_PTR(tempELutHdl);
    01372
    01373
    01374   /*----------------------------------------------------------------------------------------- X */
    01375         if(cube32Flag)
    01376                 gridPoints = 32;                        /* for cube grid */
    01377         else
    01378                 gridPoints = 16;
    01379         totalCount = gridPoints * gridPoints * gridPoints;
    01380   totalCount += 1 + gridPoints + gridPoints * gridPoints; /* extra space for Interpolation */
    01381
    01382 #ifdef ALLOW_MMX
    01383                         totalCount+=3;  /* +1 for MMX 4 Byte access */
    01384 #endif
    01385
    01386         tempXLutHdl = ALLOC_DATA(totalCount, &err);
    01387         if(err)
    01388                 goto CleanupAndExit;
    01389         LOCK_DATA(tempXLutHdl);
    01390         tempXLut = (unsigned char *)DATA_2_PTR(tempXLutHdl);
    01391
    01392
    01393   /*----------------------------------------------------------------------------------------- A */
    01394         tempALutHdl = ALLOC_DATA(adr_bereich_alut + 1, &err);   /* +1 extra space for Interpolation */
    01395         if(err)
    01396                 goto CleanupAndExit;
    01397         LOCK_DATA(tempALutHdl);
    01398         tempALut = (unsigned char *)DATA_2_PTR(tempALutHdl);
    01399
    01400                 /*---------fill 3 ELUTs for X, Y, Z (256 u.shorts each):--------------------*/
    01401                 /* linear curve with clipping, slope makes white value  become                          */
    01402                 /* max * 30.5/31 or max * 14.5/15, that is half of the last XLUT interval       */
    01403         if(cube32Flag)
    01404                 dFactor = 30.5 / 31.;
    01405         else
    01406                 dFactor = 14.5 / 15.;
    01407
    01408         maxOut = ((1L << (16 /*usedBits*/ - 8) ) * 256 * (gridPoints - 1)) / gridPoints;
    01409
    01410         for(i=0; i<3; i++)              /* X, Y, Z ELUTs */
    01411         {
    01412                 if(i == 0)
    01413                         lFactor = (long)( dFactor * 2. * maxOut * 256. / 255. / 0.9642 );/* X, adjust D50 */
    01414                 else if(i == 1)
    01415                         lFactor = (long)( dFactor * 2. * maxOut * 256. / 255.);                 /* Y */
    01416                 else
    01417                         lFactor = (long)( dFactor * 2. * maxOut * 256. / 255. / 0.8249);/* Z, adjust D50 */
    01418
    01419                 usPtr = tempELut + 256 * i;
    01420                 for(j=0; j<256; j++)
    01421                 {
    01422                         k = (j * lFactor + 127) >> 8;
    01423                         if(k > maxOut)
    01424                                 k = maxOut;             /* max. ELUT value */
    01425
    01426                         *usPtr++ = (unsigned short)k;
    01427                 }
    01428         }
    01429
    01430                 /*------ RGB to XYZ matrix in the range 0.0 to 1.0 -----*/
    01431                 /* floating point for accurate inversion                                */
    01432         XYZmatrix[0][0] = (double)pRedXYZ->data.data[0].X;
    01433         XYZmatrix[1][0] = (double)pRedXYZ->data.data[0].Y;
    01434         XYZmatrix[2][0] = (double)pRedXYZ->data.data[0].Z;
    01435
    01436         XYZmatrix[0][1] = (double)pGreenXYZ->data.data[0].X;
    01437         XYZmatrix[1][1] = (double)pGreenXYZ->data.data[0].Y;
    01438         XYZmatrix[2][1] = (double)pGreenXYZ->data.data[0].Z;
    01439
    01440         XYZmatrix[0][2] = (double)pBlueXYZ->data.data[0].X;
    01441         XYZmatrix[1][2] = (double)pBlueXYZ->data.data[0].Y;
    01442         XYZmatrix[2][2] = (double)pBlueXYZ->data.data[0].Z;
    01443
    01444                 /*--- grey with R = G = B (D50 adjustment is done by the ELUTs) ----*/
    01445         for(i=0; i<3; i++)
    01446         {
    01447                 sum = XYZmatrix[i][0] + XYZmatrix[i][1] + XYZmatrix[i][2];
    01448                 if(sum < 0.1)
    01449                         sum = 0.1;      /* prevent from div. by 0 (bad profiles) */
    01450
    01451                 for(j=0; j<3; j++)
    01452                         XYZmatrix[i][j] /= sum;
    01453         }
    01454
    01455                 /*---XYZ to RGB matrix:---*/
    01456         if(!doubMatrixInvert(XYZmatrix, RGBmatrix))
    01457         {
    01458                 err = cmparamErr;
    01459                 goto CleanupAndExit;
    01460         }
    01461
    01462         for(i=0; i<3; i++)                              /* create integer format for speed, */
    01463                 for(j=0; j<3; j++)                      /* 1.0 becomes 2^13, works for coeff. up to 8. */
    01464                         longMat[3*i + j] = (long)(RGBmatrix[i][j] * 8192.);
    01465
    01466                 /*-----grid levels for cube grid in XYZ (16 bit) so ----*/
    01467                 /* that white is at half of last interval, so the last  */
    01468                 /* value is white * 15/14.5 or white * 31/30.5                  */
    01469         if(cube32Flag)
    01470                 dFactor = 32768. / 30.5 * 31. / (gridPoints - 1);
    01471         else
    01472                 dFactor = 32768. / 14.5 * 15. / (gridPoints - 1);
    01473
    01474         for(i=0; i<gridPoints; i++)                     /* n.b: 32 is max. possible gridPoints */
    01475                 Levels[i] = (unsigned short)(i * dFactor + 0.5);
    01476
    01477                 /*----special treatment of first and last plane for speed:----*/
    01478         planeCount = gridPoints * gridPoints;
    01479         XPtr       = tempXLut;
    01480         for(i=0; i<planeCount; i++)
    01481                 *XPtr++ = 255;          /* out of gamut */
    01482
    01483         XPtr = tempXLut + (gridPoints - 1) * planeCount;
    01484         for(i=0; i<planeCount; i++)
    01485                 *XPtr++ = 255;          /* out of gamut */
    01486
    01487         *tempXLut = 0;  /* set black (white is between last 2 planes) */
    01488
    01489                 /*----second to second last plane must be computed:-----*/
    01490                 /*  transform points to RGB and judge in/out                    */
    01491         XPtr = tempXLut + planeCount;
    01492
    01493         for(i=1; i<gridPoints-1; i++)
    01494                 for(j=0; j<gridPoints; j++)
    01495                         for(k=0; k<gridPoints; k++)
    01496                         {
    01497                                 longX = (long)Levels[i];                /* X */
    01498                                 longY = (long)Levels[j];                /* Y */
    01499                                 longZ = (long)Levels[k];                /* Z */
    01500
    01501                                         /* matrix coeff: 2^13 is 1.0 , XYZ values: 1.0 or 100. is 2^15 ;        */
    01502                                         /* -> mask for products < 0 and >= 2^28 is used for in/out checking     */
    01503
    01504                                 longR = longX * longMat[0] + longY * longMat[1] + longZ * longMat[2];
    01505                                 if(longR & 0xF0000000)
    01506                                         *XPtr++ = 255;          /* out of gamut */
    01507                                 else
    01508                                 {
    01509                                         longG = longX * longMat[3] + longY * longMat[4] + longZ * longMat[5];
    01510                                         if(longG & 0xF0000000)
    01511                                                 *XPtr++ = 255;          /* out of gamut */
    01512                                         else
    01513                                         {
    01514                                                 longB = longX * longMat[6] + longY * longMat[7] + longZ * longMat[8];
    01515                                                 if(longB & 0xF0000000)
    01516                                                         *XPtr++ = 255;          /* out of gamut */
    01517                                                 else
    01518                                                         *XPtr++ = 0;            /* in gamut */
    01519                                         }
    01520                                 }
    01521                         }
    01522
    01523                 /*---fill Boolean output LUT, adr_bereich_alut Bytes, 4 at one time with long:---*/
    01524         lPtr = (long *)(tempALut);
    01525         j = adr_bereich_alut/4/2 + 8;   /* slightly more than 50 % */
    01526         for(i=0; i<j; i++)                              /* slightly more than 50 % */
    01527                 *(lPtr + i) = 0;                        /* in gamut */
    01528         k = adr_bereich_alut/4;
    01529         for(i=j; i<k; i++)
    01530                 *(lPtr + i) = 0xFFFFFFFF;       /* out of gamut */
    01531
    01532         UNLOCK_DATA(tempELutHdl);
    01533         UNLOCK_DATA(tempXLutHdl);
    01534         UNLOCK_DATA(tempALutHdl);
    01535         theLutData->colorLut    = tempXLutHdl;  tempXLutHdl = nil;
    01536         theLutData->inputLut    = tempELutHdl;  tempELutHdl = nil;
    01537         theLutData->outputLut   = tempALutHdl;  tempALutHdl = nil;
    01538
    01539 CleanupAndExit:
    01540         tempELutHdl = DISPOSE_IF_DATA(tempELutHdl);
    01541         tempXLutHdl = DISPOSE_IF_DATA(tempXLutHdl);
    01542         tempALutHdl = DISPOSE_IF_DATA(tempALutHdl);
    01543         LH_END_PROC("MakeGamut16or32ForMonitor")
    01544         return (err);
    01545 }