00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#ifndef LHGeneralIncs_h
00015
#include "General.h"
00016
#endif
00017
00018
#if GENERATING68K
00019
00020
00021
#define CM_Doub extended
00022
extern CM_Doub pow(CM_Doub _x,CM_Doub _y);
00023
#else
00024 #define CM_Doub double
00025
#include <math.h>
00026
#endif
00027
00028
#ifndef LHFragment_h
00029
#include "Fragment.h"
00030
#endif
00031
00032
#ifndef LHStdConversionLuts_h
00033
#include "StdConv.h"
00034
#endif
00035
00036
#if ! realThing
00037
#ifdef DEBUG_OUTPUT
00038
#define kThisFile kLHFragment16ID
00039
#endif
00040
#endif
00041
00042
00043
00044
void
00045
Fill_inverseGamma_ushort_ALUT (
unsigned short *usALUT,
char addrBits,
00046
unsigned short gamma_u8_8);
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
CMError
00070 Fill_inverse_ushort_ALUT_from_CurveTag(
icCurveType *pCurveTag,
00071
unsigned short *usALUT,
00072
char addrBits )
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
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
00098
00099
if(pCurveTag->
curve.
count == 0)
00100 {
00101 ulFactor = ((
unsigned long)65535 << 16) / clipIndex;
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)
00112 {
00113
Fill_inverseGamma_ushort_ALUT(usALUT, addrBits, pCurveTag->
curve.
data[0]);
00114
return(
noErr);
00115 }
00116
00117
00118
00119 inCount = pCurveTag->
curve.
count;
00120 inCurve = pCurveTag->
curve.
data;
00121
00122
00123 flFactor = (
double)clipIndex / 65535.;
00124
00125 halfStep = clipIndex >> 1;
00126
00127
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)
00137 {
00138
for(i=1; i<inCount; i++)
00139
if(inCurve[i-1] > inCurve[i])
00140 inCurve[i] = inCurve[i-1];
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++)
00146 usALUT[i] = 0;
00147
for(i=intpLast+1; i<outCount; i++)
00148 usALUT[i] = 0xFFFF;
00149
00150
00151 usPtr = inCurve;
00152 stopPtr = inCurve + inCount - 2;
00153
00154
for(i=intpFirst; i<=intpLast; i++)
00155 {
00156 target = (0x0FFFF * i + halfStep) / clipIndex;
00157
while(*(usPtr+1) < target && usPtr < stopPtr)
00158 usPtr++;
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)
00167 ulAux = 0xFFFF;
00168 }
00169
00170 usALUT[i] = (
unsigned short)ulAux;
00171 }
00172 }
00173
else
00174 {
00175
for(i=1; i<inCount; i++)
00176
if(inCurve[i-1] < inCurve[i])
00177 inCurve[i] = inCurve[i-1];
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++)
00183 usALUT[i] = 0xFFFF;
00184
for(i=intpLast+1; i<outCount; i++)
00185 usALUT[i] = 0;
00186
00187
00188 usPtr = inCurve + inCount - 1;
00189 stopPtr = inCurve + 1;
00190
00191
for(i=intpFirst; i<=intpLast; i++)
00192 {
00193 target = (0x0FFFF * i + halfStep) / clipIndex;
00194
while(*(usPtr-1) < target && usPtr > stopPtr)
00195 usPtr--;
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 }
00215
00216
00217
00218
void
00219 Fill_inverseGamma_ushort_ALUT(
unsigned short *usALUT,
00220
char addrBits,
00221
unsigned short gamma_u8_8 )
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)
00239 step = 1;
00240
else
00241 step = 0x1 << (addrBits - 6);
00242
00243 usALUT[0] = 0;
00244 usALUT[outCount-1] = 0xFFFF;
00245
00246
for(i=step; i<outCount-1; i+=step)
00247 {
00248 x = (
CM_Doub)i * xFactor;
00249
if(x > 1.)
00250 x = 1.;
00251
00252 usALUT[i] = (
unsigned short)( pow(x,invGamma) * 65535.0 + 0.5);
00253 }
00254
00255
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
00270 i = outCount - step;
00271 leftVal = (
long)usALUT[i];
00272 Diff = 0x0FFFF - leftVal;
00273
00274
for(j=1; j<step-1; j++)
00275 {
00276 lAux = ( (Diff * j << 8) / (step - 1) + 128 ) >> 8;
00277
00278 usALUT[i + j] = (
unsigned short)(leftVal + lAux);
00279 }
00280
00281
00282
if(addrBits > 6 && invGamma < 1.0)
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 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
CMError
00316 Fill_ushort_ALUTs_from_lut8Tag(
CMLutParamPtr theLutData,
00317 Ptr profileALuts,
00318
char addrBits )
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;
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;
00345
00346
for(i=0; i<theLutData->
colorLutOutDim; i++)
00347 {
00348 curOutLut = profAluts + (i << 8);
00349 curALUT = localAlutPtr + i * count;
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;
00359
00360
if(fract)
00361 {
00362 rightVal = (
long)curOutLut[baseInd + 1];
00363 rightVal = (rightVal << 8) + rightVal;
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;
00376 curALUT[j] = (
unsigned short)leftVal;
00377
00378
for(j=clipIndex+1; j<count; j++)
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 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
CMError
00414 Fill_ushort_ALUTs_from_lut16Tag(
CMLutParamPtr theLutData,
00415 Ptr profileALuts,
00416
char addrBits,
00417
long outputTableEntries )
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;
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;
00442
if(outTabLen > 4096)
00443 {
00444 err =
cmparamErr;
00445
goto CleanupAndExit;
00446 }
00447
00448 ulIndFactor = (((
unsigned long)outTabLen - 1) << 20)
00449 / (
unsigned long)clipIndex;
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 );
00462 baseInd = (
unsigned long)lAux >> 15;
00463 fract = lAux & 0x7FFF;
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++)
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 }
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 CMError DoAbsoluteShiftForPCS_Cube16(
unsigned short *theCube,
00519
long count,
00520 CMProfileRef theProfile,
00521 Boolean pcsIsXYZ,
00522 Boolean afterInput )
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)
00545
return(
noErr);
00546
else
00547
return(err);
00548 }
00549
00550
00551 xFactor = ((
double)curMediaWhite.data.data[0].X) / 65536. / 0.9642;
00552
if(xFactor > 100.)
00553 xFactor = 100.;
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;
00573
00574
if(!afterInput)
00575 {
00576 xFactor = 1. / xFactor;
00577 yFactor = 1. / yFactor;
00578 zFactor = 1. / zFactor;
00579 }
00580
00581
00582 intFactorX = (
unsigned long)(xFactor * 65536. * 64.);
00583 intFactorY = (
unsigned long)(yFactor * 65536. * 64.);
00584 intFactorZ = (
unsigned long)(zFactor * 65536. * 64.);
00585
00586 roundX = roundY = roundZ = 0x1FFFFF;
00587 shiftX = shiftY = shiftZ = 22;
00588
00589
while(intFactorX & 0xFFFF0000)
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
00611
if(!pcsIsXYZ)
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;
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)
00635
XYZ2Lab_forCube16(theCube, count);
00636
00637
00638
LH_END_PROC(
"DoAbsoluteShiftForPCS_Cube16")
00639
return(
noErr);
00640 }