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)
icCurveTypeInvertLut1d (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 }


Generated on Sat May 15 19:43:45 2004 for test by doxygen 1.3.7