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

frgmnt16.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 Fill_inverseGamma_ushort_ALUT (unsigned short *usALUT, char addrBits, unsigned short gamma_u8_8)
CMError Fill_inverse_ushort_ALUT_from_CurveTag (icCurveType *pCurveTag, unsigned short *usALUT, char addrBits)
CMError Fill_ushort_ALUTs_from_lut8Tag (CMLutParamPtr theLutData, Ptr profileALuts, char addrBits)
CMError Fill_ushort_ALUTs_from_lut16Tag (CMLutParamPtr theLutData, Ptr profileALuts, char addrBits, long outputTableEntries)
CMError DoAbsoluteShiftForPCS_Cube16 (unsigned short *theCube, long count, CMProfileRef theProfile, Boolean pcsIsXYZ, Boolean afterInput)


Define Documentation

#define CM_Doub   double
 

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


Function Documentation

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

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

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 }

CMError Fill_inverse_ushort_ALUT_from_CurveTag icCurveType pCurveTag,
unsigned short *  usALUT,
char  addrBits
 

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

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 }

void Fill_inverseGamma_ushort_ALUT unsigned short *  usALUT,
char  addrBits,
unsigned short  gamma_u8_8
 

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

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

00222 { 00223 unsigned long i, j, outCount, step, stopit; 00224 long leftVal, Diff, lAux; 00225 CM_Doub invGamma, x, xFactor; 00226 long clipIndex; 00227 #ifdef DEBUG_OUTPUT 00228 OSErr err = noErr; 00229 #endif 00230 LH_START_PROC("Fill_inverseGamma_ushort_ALUT") 00231 00232 outCount = 0x1 << addrBits; 00233 00234 invGamma = 256. / (CM_Doub)gamma_u8_8; 00235 clipIndex = outCount - 1; 00236 xFactor = 1. / (CM_Doub)clipIndex; 00237 00238 if(addrBits <= 6) /* up to 64 - 2 float.computations */ 00239 step = 1; 00240 else 00241 step = 0x1 << (addrBits - 6); /* more would take too long */ 00242 00243 usALUT[0] = 0; /* these two... */ 00244 usALUT[outCount-1] = 0xFFFF; /* ...are fixed */ 00245 00246 for(i=step; i<outCount-1; i+=step) 00247 { 00248 x = (CM_Doub)i * xFactor; 00249 if(x > 1.) 00250 x = 1.; /* clipping in the end of ALUT */ 00251 00252 usALUT[i] = (unsigned short)( pow(x,invGamma) * 65535.0 + 0.5); 00253 } 00254 00255 /*---fill intervals - except for last, which is odd:---*/ 00256 for(i=0; i<outCount-step; i+=step) 00257 { 00258 leftVal = (long)usALUT[i]; 00259 Diff = (long)usALUT[i + step] - leftVal; 00260 00261 for(j=1; j<step; j++) 00262 { 00263 lAux = ( (Diff * j << 8) / step + 128 ) >> 8; 00264 00265 usALUT[i + j] = (unsigned short)(leftVal + lAux); 00266 } 00267 } 00268 00269 /*---fill last interval:---*/ 00270 i = outCount - step; 00271 leftVal = (long)usALUT[i]; 00272 Diff = 0x0FFFF - leftVal; /* 0xFFFF for 1.0 */ 00273 00274 for(j=1; j<step-1; j++) /* stops here if step <= 2 */ 00275 { 00276 lAux = ( (Diff * j << 8) / (step - 1) + 128 ) >> 8; 00277 00278 usALUT[i + j] = (unsigned short)(leftVal + lAux); 00279 } 00280 00281 /*--overwrite sensitive values depending on Gamma:--*/ 00282 if(addrBits > 6 && invGamma < 1.0) /* ...if lower part is difficult */ 00283 { 00284 stopit = 0x1 << (addrBits - 6); 00285 00286 for(i=1; i<stopit; i++) 00287 { 00288 x = (CM_Doub)i * xFactor; 00289 usALUT[i] = (unsigned short)( pow(x,invGamma) * 65535.0); 00290 } 00291 } 00292 00293 LH_END_PROC("Fill_inverseGamma_ushort_ALUT") 00294 }

CMError Fill_ushort_ALUTs_from_lut16Tag CMLutParamPtr  theLutData,
Ptr  profileALuts,
char  addrBits,
long  outputTableEntries
 

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

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.

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 }


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