test: w98/lh_core/fragment.h File Reference

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

# fragment.h File Reference

`#include "Defines.h"`
`#include "GenLuts.h"`

Go to the source code of this file.

## Functions

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_identical (UINT16 *usELUT, char addrBits, char usedBits, long gridPoints)
CMError | Fill_ushort_ELUT_from_CurveTag (icCurveType *pCurveTag, UINT16 *usELUT, char addrBits, char usedBits, long gridPoints)
CMError | Fill_inverse_byte_ALUT_from_CurveTag (icCurveType *pCurveTag, UINT8 *ucALUT, char addrBits)
CMError | Fill_inverse_ushort_ALUT_from_CurveTag (icCurveType *pCurveTag, unsigned short *usALUT, 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_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 | Fill_ushort_ALUTs_from_lut16Tag (CMLutParamPtr theLutData, Ptr profileALuts, char addrBits, long outputTableEntries)
CMError | MakeGamut16or32ForMonitor (icXYZType *pRedXYZ, icXYZType *pGreenXYZ, icXYZType *pBlueXYZ, CMLutParamPtr theLutData, Boolean cube32Flag)
CMError | DoAbsoluteShiftForPCS_Cube16 (unsigned short *theCube, long count, CMProfileRef theProfile, Boolean pcsIsXYZ, Boolean afterInput)

## Function Documentation

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

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

References CMError, cmparamErr, icXYZArray::data, icXYZType::data, DebugPrint, doubMatrixInvert(), LH_END_PROC, LH_START_PROC, noErr, icXYZNumber::X, icXYZNumber::Y, and icXYZNumber::Z.

    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 }

CMError DoAbsoluteShiftForPCS_Cube16 | ( | unsigned short * | theCube,
|  | long | count,
|  | CMProfileRef | theProfile,
|  | Boolean | pcsIsXYZ,
|  | Boolean | afterInput
| ) |

Definition at line 518 of file lh_core/frgmnt16.c.

References icXYZType::base, cmElementTagNotFound, CMError, CMGetProfileElement(), icXYZArray::data, icXYZType::data, icSigMediaWhitePointTag, Lab2XYZ_forCube16(), LH_END_PROC, LH_START_PROC, noErr, icTagBase::sig, and XYZ2Lab_forCube16().

Referenced by CreateCombi().

    00523 {
    00524         unsigned long           i, uLong;
    00525         unsigned short          *usPtr;
    00526    CMError                              err = noErr;
    00527         unsigned long           elementSize;
    00528         icXYZType                       curMediaWhite;
    00529         double                          xFactor, yFactor, zFactor;
    00530         unsigned long           intFactorX, intFactorY, intFactorZ;
    00531         unsigned long           roundX, roundY, roundZ;
    00532         unsigned long           shiftX, shiftY, shiftZ;
    00533
    00534         LH_START_PROC("DoAbsoluteShiftForPCS_Cube16")
    00535
    00536         elementSize = sizeof(icXYZType);
    00537         err = CMGetProfileElement(theProfile, icSigMediaWhitePointTag, &elementSize, &curMediaWhite);
    00538 #ifdef IntelMode
    00539    SwapLongOffset( &curMediaWhite.base.sig, 0, 4 );
    00540    SwapLongOffset( &curMediaWhite, (LONG)((char*)&curMediaWhite.data.data[0]-(char*)&curMediaWhite), elementSize );
    00541 #endif
    00542         if(err)
    00543         {
    00544                 if(err == cmElementTagNotFound)         /* take D50 and do nothing */
    00545                         return(noErr);
    00546                 else
    00547                         return(err);
    00548         }
    00549
    00550                 /*--- preliminary matching factors: ---*/
    00551         xFactor = ((double)curMediaWhite.data.data[0].X) / 65536. / 0.9642;
    00552         if(xFactor > 100.)
    00553                 xFactor = 100.;                 /* evil profile */
    00554         else if(xFactor < 0.01)
    00555                 xFactor = 0.01;
    00556
    00557         yFactor = ((double)curMediaWhite.data.data[0].Y) / 65536.;
    00558         if(yFactor > 100.)
    00559                 yFactor = 100.;
    00560         else if(yFactor < 0.01)
    00561                 yFactor = 0.01;
    00562
    00563         zFactor = ((double)curMediaWhite.data.data[0].Z) / 65536. / 0.8249;
    00564         if(zFactor > 100.)
    00565                 zFactor = 100.;
    00566         else if(zFactor < 0.01)
    00567                 zFactor = 0.01;
    00568
    00569         if( ( xFactor < 1.+1.E-3 && xFactor > 1.-1.E-3 ) &&
    00570                 ( yFactor < 1.+1.E-3 && yFactor > 1.-1.E-3 ) &&
    00571                 ( zFactor < 1.+1.E-3 && zFactor > 1.-1.E-3 ) )
    00572                         return noErr; /* do nothing if MediaWhite is D50 */
    00573
    00574         if(!afterInput)         /* back to device space (for example with B2A1 table) */
    00575         {
    00576                 xFactor = 1. / xFactor;
    00577                 yFactor = 1. / yFactor;
    00578                 zFactor = 1. / zFactor;
    00579         }
    00580
    00581                 /*--- integer factors for speed: ---*/
    00582         intFactorX = (unsigned long)(xFactor * 65536. * 64.);   /* probably too long... */
    00583         intFactorY = (unsigned long)(yFactor * 65536. * 64.);   /* ...adding 22 bits    */
    00584         intFactorZ = (unsigned long)(zFactor * 65536. * 64.);
    00585
    00586         roundX = roundY = roundZ = 0x1FFFFF;    /* 2^21 - 1 */
    00587         shiftX = shiftY = shiftZ = 22;
    00588
    00589         while(intFactorX & 0xFFFF0000)  /* stay within 16 bits to prevent product overflow */
    00590         {
    00591                 intFactorX >>= 1;
    00592                 roundX     >>= 1;
    00593                 shiftX      -= 1;
    00594         }
    00595
    00596         while(intFactorY & 0xFFFF0000)
    00597         {
    00598                 intFactorY >>= 1;
    00599                 roundY     >>= 1;
    00600                 shiftY      -= 1;
    00601         }
    00602
    00603         while(intFactorZ & 0xFFFF0000)
    00604         {
    00605                 intFactorZ >>= 1;
    00606                 roundZ     >>= 1;
    00607                 shiftZ      -= 1;
    00608         }
    00609
    00610                 /*--- perform matching: ---*/
    00611         if(!pcsIsXYZ)           /* 16 bit linear Lab  to XYZ before and afterwards */
    00612                 Lab2XYZ_forCube16(theCube, count);
    00613
    00614         usPtr = theCube;
    00615
    00616         for(i=0; i<(unsigned long)count; i++)
    00617         {
    00618                 uLong = ((unsigned long)(*usPtr) * intFactorX + roundX) >> shiftX;
    00619                 if(uLong > 0x0FFFF)
    00620                         uLong = 0xFFFF;                         /* clip to 2.0 */
    00621                 *usPtr++ = (unsigned short)uLong;
    00622
    00623                 uLong = ((unsigned long)(*usPtr) * intFactorY + roundY) >> shiftY;
    00624                 if(uLong > 0x0FFFF)
    00625                         uLong = 0xFFFF;
    00626                 *usPtr++ = (unsigned short)uLong;
    00627
    00628                 uLong = ((unsigned long)(*usPtr) * intFactorZ + roundZ) >> shiftZ;
    00629                 if(uLong > 0x0FFFF)
    00630                         uLong = 0xFFFF;
    00631                 *usPtr++ = (unsigned short)uLong;
    00632         }
    00633
    00634         if(!pcsIsXYZ)           /* back to 16 bit Lab */
    00635                 XYZ2Lab_forCube16(theCube, count);
    00636
    00637
    00638         LH_END_PROC("DoAbsoluteShiftForPCS_Cube16")
    00639         return(noErr);
    00640 }

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.

References ALLOC_DATA, CMLutParam::colorLutOutDim, DATA_2_PTR, DISPOSE_IF_DATA, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, CMLutParam::outputLut, UINT16, UINT8, and UNLOCK_DATA.

Referenced by Extract_MFT_Alut().

    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.

References ALLOC_DATA, CMLutParam::colorLutOutDim, DATA_2_PTR, DISPOSE_IF_DATA, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, CMLutParam::outputLut, UINT8, and UNLOCK_DATA.

Referenced by Extract_MFT_Alut().

    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,
|  | UINT8 * | ucALUT,
|  | char | addrBits
| ) |

| Referenced by Extract_Gray_Luts(), and Extract_TRC_Alut().

CMError Fill_inverse_ushort_ALUT_from_CurveTag | ( | icCurveType * | pCurveTag,
|  | unsigned short * | usALUT,
|  | char | addrBits
| ) |

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

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

Referenced by Extract_Gray_Luts(), and Extract_TRC_Alut().

    00073 {
    00074         unsigned long   i, inCount, outCount, clipIndex, ulFactor;
    00075         unsigned long   intpFirst, intpLast, halfStep, ulAux, target;
    00076         short                   monot;
    00077         unsigned short  *inCurve, *usPtr, *stopPtr;
    00078         double                  flFactor;
    00079 #ifdef DEBUG_OUTPUT
    00080         OSErr err=noErr;
    00081 #endif
    00082         LH_START_PROC("Fill_inverse_ushort_ALUT_from_CurveTag")
    00083
    00084     if( pCurveTag->base.sig != icSigCurveType   /* 'curv' */
    00085          || addrBits > 15 )
    00086          {
    00087 #ifdef DEBUG_OUTPUT
    00088                 if ( DebugCheck(kThisFile, kDebugErrorInfo) )
    00089                         DebugPrint("¥ Fill_inverse_ushort_ALUT_from_CurveTag ERROR:   addrBits= %d\n",addrBits);
    00090 #endif
    00091                 return(cmparamErr);
    00092          }
    00093
    00094         outCount  = 1 << addrBits;
    00095         clipIndex = outCount - 1;
    00096
    00097                 /*---special cases:---*/
    00098
    00099         if(pCurveTag->curve.count == 0)         /*---identity---*/
    00100         {
    00101                 ulFactor = ((unsigned long)65535 << 16) / clipIndex;            /* use all 32 bits */
    00102
    00103                 for(i=0; i<clipIndex; i++)
    00104                         usALUT[i] = (unsigned short)((i * ulFactor + 32767) >> 16);
    00105
    00106                 for(i=clipIndex; i<outCount; i++)
    00107                         usALUT[i] = 0xFFFF;
    00108
    00109                 return(noErr);
    00110         }
    00111         else if(pCurveTag->curve.count == 1)    /*---gamma curve---*/
    00112         {
    00113                 Fill_inverseGamma_ushort_ALUT(usALUT, addrBits, pCurveTag->curve.data[0]);
    00114                 return(noErr);
    00115         }
    00116
    00117                 /*---ordinary case:---*/
    00118
    00119         inCount = pCurveTag->curve.count;
    00120         inCurve = pCurveTag->curve.data;
    00121
    00122                  /* exact matching factor needed for special values: */
    00123         flFactor = (double)clipIndex / 65535.;
    00124
    00125         halfStep = clipIndex >> 1;              /* lessen computation incorrectness */
    00126
    00127                                 /* ascending or descending ? */
    00128         for(monot=0, i=1; i<inCount; i++)
    00129         {
    00130                 if(inCurve[i-1] < inCurve[i])
    00131                         monot++;
    00132                 else if(inCurve[i-1] > inCurve[i])
    00133                         monot--;
    00134         }
    00135
    00136         if(monot >= 0)  /* curve seems to be ascending */
    00137         {
    00138                 for(i=1; i<inCount; i++)
    00139                         if(inCurve[i-1] > inCurve[i])
    00140                                 inCurve[i] = inCurve[i-1];      /* correct not-invertible parts */
    00141
    00142                 intpFirst = (unsigned long)(inCurve[0] * flFactor + 0.9999);
    00143                 intpLast  = (unsigned long)(inCurve[inCount-1] * flFactor);
    00144
    00145                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00146                         usALUT[i] = 0;
    00147                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00148                         usALUT[i] = 0xFFFF;
    00149
    00150                         /* interpolate remaining values: */
    00151                 usPtr   = inCurve;
    00152                 stopPtr = inCurve + inCount - 2; /* stops incrementation */
    00153
    00154                 for(i=intpFirst; i<=intpLast; i++)
    00155                 {
    00156                         target = (0x0FFFF * i + halfStep)  / clipIndex;
    00157                         while(*(usPtr+1) < target && usPtr < stopPtr)
    00158                                 usPtr++;                                        /* find interval */
    00159
    00160                         ulAux = ((unsigned long)(usPtr - inCurve) << 16) / (inCount - 1);
    00161                         if(*(usPtr+1) != *usPtr)
    00162                         {
    00163                                 ulAux += ((target - (unsigned long)*usPtr) << 16)
    00164                                           / ( (*(usPtr+1) - *usPtr) * (inCount - 1) );
    00165
    00166                                 if(ulAux & 0x10000)   /* *(usPtr+1) was required */
    00167                                         ulAux = 0xFFFF;
    00168                         }
    00169
    00170                         usALUT[i] = (unsigned short)ulAux;
    00171                 }
    00172         }
    00173         else                    /* curve seems to be descending */
    00174         {
    00175                 for(i=1; i<inCount; i++)
    00176                         if(inCurve[i-1] < inCurve[i])
    00177                                 inCurve[i] = inCurve[i-1];      /* correct not-invertible parts */
    00178
    00179                 intpFirst = (unsigned long)(inCurve[inCount-1] * flFactor + 0.9999);
    00180                 intpLast  = (unsigned long)(inCurve[0] * flFactor);
    00181
    00182                 for(i=0; i<intpFirst; i++)                      /* fill lacking area low */
    00183                         usALUT[i] = 0xFFFF;
    00184                 for(i=intpLast+1; i<outCount; i++)      /* fill lacking area high */
    00185                         usALUT[i] = 0;
    00186
    00187                         /* interpolate remaining values: */
    00188                 usPtr   = inCurve + inCount - 1;
    00189                 stopPtr = inCurve + 1;          /* stops decrementation */
    00190
    00191                 for(i=intpFirst; i<=intpLast; i++)
    00192                 {
    00193                         target = (0x0FFFF * i + halfStep)  / clipIndex;
    00194                         while(*(usPtr-1) < target && usPtr > stopPtr)
    00195                                 usPtr--;                                        /* find interval */
    00196
    00197                         ulAux = ((unsigned long)(usPtr-1 - inCurve) << 16) / (inCount - 1);
    00198                         if(*(usPtr-1) != *usPtr)
    00199                         {
    00200                                 ulAux += (((unsigned long)*(usPtr-1) - target) << 16)
    00201                                           / ( (*(usPtr-1) - *usPtr) * (inCount - 1) );
    00202
    00203                                 if(ulAux & 0x10000)
    00204                                         ulAux = 0xFFFF;
    00205                         }
    00206
    00207                         usALUT[i] = (unsigned short)ulAux;
    00208                 }
    00209         }
    00210
    00211
    00212         LH_END_PROC("Fill_inverse_ushort_ALUT_from_CurveTag")
    00213         return(noErr);
    00214 }

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

Definition at line 414 of file lh_core/frgmnt16.c.

References ALLOC_DATA, cmparamErr, CMLutParam::colorLutOutDim, DATA_2_PTR, DISPOSE_IF_DATA, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, CMLutParam::outputLut, and UNLOCK_DATA.

Referenced by Extract_MFT_Alut().

    00418 {
    00419         long                    i;
    00420         unsigned short  *curOutLut;
    00421         unsigned short  *curALUT;
    00422         unsigned long   ulIndFactor, j;
    00423         long                    count, clipIndex, outTabLen;
    00424         long                    fract, baseInd, lAux, leftVal, rightVal;
    00425         unsigned short  *profALUTs = (unsigned short *)profileALuts;
    00426         OSErr                   err = noErr;
    00427         LUT_DATA_TYPE   localAlut = nil;
    00428         unsigned short  *localAlutPtr;
    00429         long                    theAlutSize;
    00430
    00431         LH_START_PROC("Fill_ushort_ALUTs_from_lut16Tag")
    00432
    00433         count     = 1 << addrBits;                                              /* addrBits is always >= 8 */
    00434         clipIndex = count - 1;
    00435
    00436         theAlutSize = theLutData->colorLutOutDim * count * sizeof(unsigned short);
    00437         localAlut   = ALLOC_DATA(theAlutSize + 2, &err);
    00438         if (err)
    00439                 goto CleanupAndExit;
    00440
    00441         outTabLen = outputTableEntries;                 /* <= 4096 acc. to the spec */
    00442         if(outTabLen > 4096)
    00443         {
    00444                 err = cmparamErr;
    00445                 goto CleanupAndExit;
    00446         }
    00447
    00448         ulIndFactor = (((unsigned long)outTabLen - 1) << 20)
    00449                                 / (unsigned long)clipIndex;                             /* for adjusting the indices */
    00450
    00451         LOCK_DATA(localAlut);
    00452         localAlutPtr = (unsigned short *)DATA_2_PTR(localAlut);
    00453
    00454         for(i=0; i<theLutData->colorLutOutDim; i++)
    00455         {
    00456                 curOutLut = profALUTs + i * outTabLen;
    00457                 curALUT   = localAlutPtr + i * count;
    00458
    00459                 for(j=0; j<=(unsigned long)clipIndex; j++)
    00460                 {
    00461                         lAux    = (long)( (j * ulIndFactor + 16) >> 5 );                /* n.b: j is unsigned long ! */
    00462                         baseInd = (unsigned long)lAux >> 15;
    00463                         fract   = lAux & 0x7FFF;        /* 15 bits for interpolation */
    00464
    00465                         if(fract)
    00466                         {
    00467                                 leftVal  = (long)curOutLut[baseInd];
    00468                                 rightVal = (long)curOutLut[baseInd + 1];
    00469
    00470                                 lAux = rightVal - leftVal;
    00471                                 lAux = (lAux * fract + 16383) >> 15;
    00472
    00473                                 curALUT[j] = (unsigned short)(leftVal + lAux);
    00474                         }
    00475                         else
    00476                                 curALUT[j] = curOutLut[baseInd];
    00477                 }
    00478
    00479                 for(j=clipIndex+1; j<(unsigned long)count; j++)         /* unused indices, clip these */
    00480                         curALUT[j] = curALUT[clipIndex];
    00481         }
    00482
    00483         UNLOCK_DATA(localAlut);
    00484         theLutData->outputLut = localAlut;
    00485         localAlut = nil;
    00486 CleanupAndExit:
    00487         localAlut = DISPOSE_IF_DATA(localAlut);
    00488
    00489         LH_END_PROC("Fill_ushort_ALUTs_from_lut16Tag")
    00490         return err;
    00491 }

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

Definition at line 316 of file lh_core/frgmnt16.c.

References ALLOC_DATA, CMLutParam::colorLutOutDim, DATA_2_PTR, DISPOSE_IF_DATA, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, CMLutParam::outputLut, and UNLOCK_DATA.

Referenced by Extract_MFT_Alut().

    00319 {
    00320         long                    i, j;
    00321         unsigned char   *curOutLut;
    00322         unsigned char   *profAluts = (unsigned char *)profileALuts;
    00323         unsigned short  *curALUT;
    00324         long                    count, clipIndex;
    00325         long                    factor, fract, baseInd, lAux, leftVal, rightVal;
    00326         OSErr                   err = noErr;
    00327         LUT_DATA_TYPE   localAlut = nil;
    00328         unsigned short  *localAlutPtr;
    00329         long                    theAlutSize;
    00330
    00331         LH_START_PROC("Fill_ushort_ALUTs_from_lut8Tag")
    00332
    00333         count     = 1 << addrBits;                                              /* addrBits is always >= 8 */
    00334         clipIndex = count - 1;
    00335
    00336         theAlutSize = theLutData->colorLutOutDim * count * sizeof(unsigned short);
    00337         localAlut   = ALLOC_DATA(theAlutSize + 2, &err);
    00338         if (err)
    00339                 goto CleanupAndExit;
    00340
    00341         LOCK_DATA(localAlut);
    00342         localAlutPtr = (unsigned short *)DATA_2_PTR(localAlut);
    00343
    00344         factor = ((255 << 12) + clipIndex/2) / clipIndex;               /* for adjusting the indices */
    00345
    00346         for(i=0; i<theLutData->colorLutOutDim; i++)
    00347         {
    00348                 curOutLut = profAluts + (i << 8);               /* these are unsigned char's */
    00349                 curALUT   = localAlutPtr + i * count;   /* these are unsigned short's */
    00350
    00351                 for(j=0; j<=clipIndex-1; j++)
    00352                 {
    00353                         lAux    = j * factor;
    00354                         baseInd = (unsigned long)lAux >> 12;
    00355                         fract   = lAux & 0x0FFF;
    00356
    00357                         leftVal = (long)curOutLut[baseInd];
    00358                         leftVal = (leftVal << 8) + leftVal;             /* 0xFF -> 0xFFFF */
    00359
    00360                         if(fract)
    00361                         {
    00362                                 rightVal = (long)curOutLut[baseInd + 1];
    00363                                 rightVal = (rightVal << 8) + rightVal;          /* 0xFF -> 0xFFFF */
    00364
    00365                                 lAux = rightVal - leftVal;
    00366                                 lAux = (lAux * fract + 0x0800) >> 12;
    00367
    00368                                 curALUT[j] = (unsigned short)(leftVal + lAux);
    00369                         }
    00370                         else
    00371                                 curALUT[j] = (unsigned short)leftVal;
    00372                 }
    00373
    00374                 leftVal = (long)curOutLut[255];
    00375                 leftVal = (leftVal << 8) + leftVal;             /* 0xFF -> 0xFFFF */
    00376                 curALUT[j] = (unsigned short)leftVal;
    00377
    00378                 for(j=clipIndex+1; j<count; j++)                /* unused indices, clip these */
    00379                         curALUT[j] = curALUT[clipIndex];
    00380         }
    00381
    00382         UNLOCK_DATA(localAlut);
    00383         theLutData->outputLut = localAlut;
    00384         localAlut = nil;
    00385 CleanupAndExit:
    00386         localAlut = DISPOSE_IF_DATA(localAlut);
    00387
    00388         LH_END_PROC("Fill_ushort_ALUTs_from_lut8Tag")
    00389         return err;
    00390 }

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

| Referenced by Extract_Gray_Luts(), and Extract_TRC_Elut().

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

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

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

Referenced by Fill_ushort_ELUT_from_CurveTag().

    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.

References ALLOC_DATA, CMLutParam::colorLutInDim, DATA_2_PTR, DISPOSE_IF_DATA, CMLutParam::inputLut, L, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, UINT16, and UNLOCK_DATA.

Referenced by Extract_MFT_Elut().

    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.

References ALLOC_DATA, CMLutParam::colorLutInDim, DATA_2_PTR, DISPOSE_IF_DATA, CMLutParam::inputLut, L, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, UINT16, UINT8, and UNLOCK_DATA.

Referenced by Extract_MFT_Elut().

    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.

References icCurveType::base, icCurve::count, icCurveType::curve, icCurve::data, icSigCurveType, InvLut1dExceptions(), LH_END_PROC, LH_START_PROC, nil, noErr, OSErr, OSType, icTagBase::reserved, icTagBase::sig, and SmartNewPtr().

    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 }

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

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

References adr_bereich_alut, adr_bereich_elut, ALLOC_DATA, CMError, cmparamErr, CMLutParam::colorLut, icXYZArray::data, icXYZType::data, DATA_2_PTR, DISPOSE_IF_DATA, doubMatrixInvert(), CMLutParam::inputLut, L, LH_END_PROC, LH_START_PROC, LOCK_DATA, LUT_DATA_TYPE, nil, noErr, OSErr, CMLutParam::outputLut, UNLOCK_DATA, icXYZNumber::X, icXYZNumber::Y, and icXYZNumber::Z.

Referenced by DoMakeGamutForMonitor().

    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 }