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
#ifndef LHGenLuts_h
00019
#include "GenLuts.h"
00020
#endif
00021
00022
#ifndef PI_CMMInitialization_h
00023
#include "PI_CMM.h"
00024
#endif
00025
00026
#ifndef LHStdConversionLuts_h
00027
#include "StdConv.h"
00028
#endif
00029
00030
#if ! realThing
00031
#ifdef DEBUG_OUTPUT
00032
#define kThisFile kCMMInitializationID
00033
#define __TYPES__
00034
00035
00036
#endif
00037
#endif
00038
00039 #define ALLOW_DEVICE_LINK
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 CMError CMMInitPrivate( CMMModelPtr storage,
00061 CMProfileRef srcProfile,
00062 CMProfileRef dstProfile )
00063 {
00064
CMError err =
noErr;
00065
OSErr aOSerr =
noErr;
00066
CMConcatProfileSet *profileSet =
nil;
00067
CMCoreProfileHeader sourceHeader;
00068
CMCoreProfileHeader destHeader;
00069
Boolean valid;
00070
short mode = 0;
00071
#ifdef DEBUG_OUTPUT
00072
long timer =
TickCount();
00073
#endif
00074
00075
#ifdef DEBUG_OUTPUT
00076
if ( DebugCheck(kThisFile, kDebugMiscInfo) )
00077
DebugPrint(
"� ->CMMInitPrivate\n");
00078
#endif
00079
00080
00081 err =
CMValidateProfile( srcProfile, &valid );
00082
if (err)
00083
goto CleanupAndExit;
00084
if (!valid)
00085 {
00086
#ifdef DEBUG_OUTPUT
00087
if ( DebugCheck(kThisFile, kDebugErrorInfo) )
00088
DebugPrint(
"� CMMInitPrivate ERROR: srcProfile is NOT valid!\n");
00089
#endif
00090
00091
#ifdef realThing
00092
err =
cmProfileError;
00093
goto CleanupAndExit;
00094
#endif
00095
}
00096
00097 err =
CMValidateProfile(dstProfile, &valid );
00098
if (err)
00099
goto CleanupAndExit;
00100
if (!valid)
00101 {
00102
#ifdef DEBUG_OUTPUT
00103
if ( DebugCheck(kThisFile, kDebugErrorInfo) )
00104
DebugPrint(
"� CMMInitPrivate ERROR: dstProfile is NOT valid!\n");
00105
#endif
00106
#ifdef realThing
00107
err =
cmProfileError;
00108
goto CleanupAndExit;
00109
#endif
00110
}
00111
00112
00113 (storage)->lutParam.inputLut =
DISPOSE_IF_DATA((storage)->lutParam.inputLut);
00114 (storage)->lutParam.colorLut =
DISPOSE_IF_DATA((storage)->lutParam.colorLut);
00115 (storage)->lutParam.outputLut =
DISPOSE_IF_DATA((storage)->lutParam.outputLut);
00116
00117 (storage)->gamutLutParam.inputLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.inputLut);
00118 (storage)->gamutLutParam.colorLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.colorLut);
00119 (storage)->gamutLutParam.outputLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.outputLut);
00120
00121 (storage)->theNamedColorTagData =
DISPOSE_IF_DATA((storage)->theNamedColorTagData);
00122
00123 (storage)->srcProfileVersion =
icVersionNumber;
00124 (storage)->dstProfileVersion =
icVersionNumber;
00125
00126
00127 err =
CMGetProfileHeader( srcProfile, &sourceHeader);
00128
if (err)
00129
goto CleanupAndExit;
00130
00131
if ( !((sourceHeader.
version & 0xff000000) >=
icVersionNumber) ){
00132 err =
cmProfileError;
00133
goto CleanupAndExit;
00134 }
00135
if (sourceHeader.
deviceClass ==
icSigLinkClass)
00136 {
00137 err =
cmCantConcatenateError;
00138
goto CleanupAndExit;
00139 }
00140
00141
00142 err =
CMGetProfileHeader( dstProfile, &destHeader);
00143
if (err)
00144
goto CleanupAndExit;
00145
00146
if ( !((destHeader.
version & 0xff000000) >=
icVersionNumber) ){
00147 err =
cmProfileError;
00148
goto CleanupAndExit;
00149 }
00150
if (destHeader.
deviceClass ==
icSigLinkClass)
00151 {
00152 err =
cmCantConcatenateError;
00153
goto CleanupAndExit;
00154 }
00155 storage->lookup = (
Boolean)((sourceHeader.
flags &
kLookupOnlyMask)>>16);
00156
00157
#ifdef RenderInt
00158
if( storage->
dwFlags != 0xffffffff ){
00159 storage->lookup = (
Boolean)((storage->
dwFlags &
kLookupOnlyMask)>>16);
00160 }
00161
#endif
00162
00163 profileSet = (
CMConcatProfileSet *)
SmartNewPtr(
sizeof (
CMConcatProfileSet) +
sizeof(
CMProfileRef), &aOSerr);
00164
if (aOSerr)
00165
goto CleanupAndExit;
00166
00167 profileSet->
count = 2;
00168 profileSet->
keyIndex = 1;
00169
00170 profileSet->
profileSet[0] = srcProfile;
00171
00172 profileSet->
profileSet[1] = dstProfile;
00173
00174
00175 err =
PrepareCombiLUTs( storage, profileSet );
00176
if (err)
00177
goto CleanupAndExit;
00178
00179 CleanupAndExit:
00180 profileSet = (
CMConcatProfileSet*)
DisposeIfPtr( (
Ptr)profileSet );
00181
00182
#ifdef DEBUG_OUTPUT
00183
if ( err && DebugCheck(kThisFile, kDebugErrorInfo) )
00184
DebugPrint(
"� CMMInitPrivate: err = %d\n", err);
00185
if ( DebugCheck(kThisFile, kDebugTimingInfo) )
00186
DebugPrint(
" time in CMMInitPrivate: %f second(s)\n",(
TickCount()-timer)/60.0);
00187
if ( DebugCheck(kThisFile, kDebugMiscInfo) )
00188
DebugPrint(
"� <-CMMInitPrivate\n");
00189
#endif
00190
return err;
00191 }
00192
00193
CMError MakeSessionFromLink( CMMModelPtr storage,
00194
CMConcatProfileSet *profileSet );
00195
00196
#ifndef HD_NEW_CONCATE_INIT
00197 CMError CMMConcatInitPrivate ( CMMModelPtr storage,
00198
CMConcatProfileSet *profileSet)
00199 {
00200
CMCoreProfileHeader firstHeader;
00201
CMCoreProfileHeader lastHeader;
00202
CMCoreProfileHeader tempHeader;
00203
CMError err =
noErr;
00204
unsigned short count;
00205
unsigned short loop;
00206
Boolean valid;
00207
CMProfileRef theProfile;
00208
#ifdef DEBUG_OUTPUT
00209
long timer =
TickCount();
00210
#endif
00211
00212
00213
#ifdef DEBUG_OUTPUT
00214
if ( DebugCheck(kThisFile, kDebugMiscInfo) )
00215 {
00216
DebugPrint(
"� ->CMMConcatInitPrivate\n");
00217
DebugPrint(
" got %d profiles keyindex is %d \n", profileSet->
count, profileSet->
keyIndex);
00218 }
00219
#endif
00220
00221 count = profileSet->
count;
00222
if (count == 0)
00223 {
00224 err =
cmparamErr;
00225
goto CleanupAndExit;
00226 }
00227
00228 err =
CMGetProfileHeader( profileSet->
profileSet[0], &firstHeader);
00229
if (err)
00230
goto CleanupAndExit;
00231
00232 storage->lookup = (
Boolean)((firstHeader.
flags &
kLookupOnlyMask)>>16);
00233
00234
#ifdef RenderInt
00235
if( storage->
dwFlags != 0xffffffff ){
00236 storage->lookup = (
Boolean)((storage->
dwFlags &
kLookupOnlyMask)>>16);
00237 }
00238
#endif
00239
if (count == 1 && firstHeader.
deviceClass !=
icSigNamedColorClass )
00240 {
00241
if (firstHeader.
deviceClass !=
icSigLinkClass && firstHeader.
deviceClass !=
icSigAbstractClass )
00242 {
00243 err =
cmCantConcatenateError;
00244
goto CleanupAndExit;
00245 }
00246
else{
00247 err =
MakeSessionFromLink( storage, profileSet );
00248
if( err == 0 )
return noErr;
00249 }
00250 lastHeader = firstHeader;
00251 }
else
00252 {
00253
00254 err =
CMGetProfileHeader( profileSet->
profileSet[count-1], &lastHeader);
00255
if (err)
00256
goto CleanupAndExit;
00257
#ifndef ALLOW_DEVICE_LINK
00258
if (lastHeader.
deviceClass ==
icSigLinkClass)
00259 {
00260 err =
cmCantConcatenateError;
00261
goto CleanupAndExit;
00262 }
00263
#endif
00264
}
00265
00266
00267
for ( loop = 0; loop < count; loop++)
00268 {
00269 theProfile = profileSet->
profileSet[loop];
00270 err =
CMValidateProfile( theProfile, &valid );
00271
if (err)
00272
goto CleanupAndExit;
00273
if (!valid)
00274 {
00275
#ifdef DEBUG_OUTPUT
00276
if ( DebugCheck(kThisFile, kDebugErrorInfo) )
00277
DebugPrint(
"� CMMConcatInitPrivate ERROR: profile #%d is NOT valid!\n", loop);
00278
#endif
00279
#ifdef realThing
00280
err =
cmProfileError;
00281
goto CleanupAndExit;
00282
#endif
00283
}
00284
00285
if ( (loop > 0) && (loop < count-1))
00286 {
00287 err =
CMGetProfileHeader( profileSet->
profileSet[loop], &tempHeader);
00288
if (err)
00289
goto CleanupAndExit;
00290
if (tempHeader.
deviceClass ==
icSigLinkClass)
00291 {
00292 err =
cmCantConcatenateError;
00293
goto CleanupAndExit;
00294 }
00295 }
00296 }
00297
00298
00299
if ( (count >1) && ( (firstHeader.
deviceClass ==
icSigAbstractClass) || (lastHeader.
deviceClass ==
icSigAbstractClass) ) )
00300 {
00301 err =
cmCantConcatenateError;
00302
goto CleanupAndExit;
00303 }
00304
00305
00306 (storage)->lutParam.inputLut =
DISPOSE_IF_DATA((storage)->lutParam.inputLut);
00307 (storage)->lutParam.colorLut =
DISPOSE_IF_DATA((storage)->lutParam.colorLut);
00308 (storage)->lutParam.outputLut =
DISPOSE_IF_DATA((storage)->lutParam.outputLut);
00309
00310 (storage)->gamutLutParam.inputLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.inputLut);
00311 (storage)->gamutLutParam.colorLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.colorLut);
00312 (storage)->gamutLutParam.outputLut =
DISPOSE_IF_DATA((storage)->gamutLutParam.outputLut);
00313
00314 (storage)->theNamedColorTagData =
DISPOSE_IF_DATA((storage)->theNamedColorTagData);
00315
00316 {
00317 err =
PrepareCombiLUTs( storage, profileSet );
00318 }
00319
00320 CleanupAndExit:
00321
00322
#ifdef DEBUG_OUTPUT
00323
if ( err && DebugCheck(kThisFile, kDebugErrorInfo) )
00324
DebugPrint(
" CMMConcatInitPrivate: err = %d\n", err);
00325
DebugPrint(
" time in CMMConcatInitPrivate: %f second(s)\n",(
TickCount()-timer)/60.0);
00326
DebugPrint(
"� <-CMMConcatInitPrivate\n");
00327
#endif
00328
return( err );
00329 }
00330
00331
Boolean IsPowerOf2(
unsigned long l );
00332
Boolean IsPowerOf2(
unsigned long l )
00333 {
00334
unsigned long i;
00335
for( i=1; i<32; i++){
00336
if( (1U<<i) == l )
return 1;
00337 }
00338
return 0;
00339 }
00340
00341
#endif
00342
CMError MakeSessionFromLink( CMMModelPtr storage,
00343
CMConcatProfileSet *profileSet )
00344 {
00345
CMLutParam theLut={0};
00346
CMLutParam *theLutData;
00347
LHCombiData theCombi={0};
00348
LHCombiData *theCombiData;
00349
double *aDoublePtr;
00350
double aDouble;
00351
OSType theTag =
icSigAToB0Tag;
00352
00353
CMError err =
noErr;
00354
OSErr aOSerr =
noErr;
00355
Ptr profileLutPtr =
nil;
00356
UINT32 elementSize;
00357
double factor;
00358
UINT32 byteCount;
00359
CMCoreProfileHeader aHeader;
00360
00361
LH_START_PROC(
"MakeSessionFromLink")
00362
00363
00364 theLutData = &theLut;
00365 theCombiData = &theCombi;
00366 theCombiData->theProfile = profileSet->profileSet[0];
00367
00368
00369 err = CMGetProfileElement(theCombiData->theProfile, theTag, &elementSize, nil);
00370 if (err)
00371 goto CleanupAndExit;
00372
00373 byteCount = 52;
00374 profileLutPtr = SmartNewPtr(byteCount, &aOSerr);
00375 err = aOSerr;
00376 if (err)
00377 goto CleanupAndExit;
00378
00379 err = CMGetProfileElement( theCombiData->theProfile, theTag, &byteCount, profileLutPtr );
00380 if (err)
00381 goto CleanupAndExit;
00382 #ifdef IntelMode
00383 SwapLongOffset( &((
icLut16Type*)profileLutPtr)->base.sig, 0, 4 );
00384 SwapShortOffset( &((
icLut16Type*)profileLutPtr)->lut.inputEnt, 0, 2 );
00385 SwapShortOffset( &((
icLut16Type*)profileLutPtr)->lut.outputEnt, 0, 2 );
00386 #endif
00387
00388 theLutData->colorLutInDim = ((
icLut8Type*)profileLutPtr)->lut.inputChan;
00389 theLutData->colorLutOutDim = ((
icLut8Type*)profileLutPtr)->lut.outputChan;
00390 theLutData->colorLutGridPoints = ((
icLut8Type*)profileLutPtr)->lut.clutPoints;
00391
00392 switch( theLutData->colorLutInDim ){
00393
case 3:
00394
if( theLutData->
colorLutGridPoints != 16 && theLutData->
colorLutGridPoints != 32 ){
00395 err = 1;
00396
goto CleanupAndExit;
00397 }
00398
break;
00399
case 4:
00400
if( theLutData->
colorLutGridPoints != 8 && theLutData->
colorLutGridPoints != 16 ){
00401 err = 1;
00402
goto CleanupAndExit;
00403 }
00404
break;
00405 }
00406
00407 err =
CMGetProfileHeader( profileSet->
profileSet[0], &aHeader);
00408
if (err)
00409
goto CleanupAndExit;
00410 storage->firstColorSpace = aHeader.
colorSpace;
00411 storage->lastColorSpace = aHeader.
pcs;
00412 storage->srcProfileVersion =
icVersionNumber;
00413 storage->dstProfileVersion =
icVersionNumber;
00414
00415
if ( ( theLutData->
colorLutInDim == 3) &&
00416 ( aHeader.
pcs ==
icSigXYZData ) )
00417 {
00418 factor = 1.;
00419 err =
GetMatrixFromProfile(theLutData, theCombiData, theTag, factor);
00420
if( err )
goto CleanupAndExit;
00421 aDoublePtr = (
double *)theLutData->
matrixMFT;
00422
if( aDoublePtr != 0 ){
00423 aDouble = aDoublePtr[0] + aDoublePtr[4] + aDoublePtr[8];
00424
if( aDouble > 3.0 + 1E-6 || aDouble < 3.0 - 1E-6 ){
00425 err = 1;
00426
goto CleanupAndExit;
00427 }
00428 }
00429 }
00430 theCombiData->
maxProfileCount = 0;
00431
if( ((
icLut16Type*)profileLutPtr)->base.sig ==
icSigLut16Type ){
00432 theCombiData->
doCreate_16bit_Combi = 1;
00433 theCombiData->
doCreate_16bit_ELut = 0;
00434 theCombiData->
doCreate_16bit_XLut = 1;
00435 theCombiData->
doCreate_16bit_ALut = 0;
00436 }
00437
else{
00438 theCombiData->
doCreate_16bit_Combi = 0;
00439 theCombiData->
doCreate_16bit_ELut = 0;
00440 theCombiData->
doCreate_16bit_XLut = 0;
00441 theCombiData->
doCreate_16bit_ALut = 0;
00442 }
00443
00444
00445 err =
Extract_MFT_Alut( theLutData, theCombiData, profileLutPtr, theTag );
00446
if (err)
00447
goto CleanupAndExit;
00448
00449
00450 err =
Extract_MFT_Xlut ( theLutData, theCombiData, profileLutPtr, theTag );
00451
if (err)
00452
goto CleanupAndExit;
00453
00454
00455 err =
Extract_MFT_Elut( theLutData, theCombiData, profileLutPtr, theTag );
00456
if (err)
00457
goto CleanupAndExit;
00458
00459 storage->lutParam = *theLutData;
00460
00461
00462
00463
00464 CleanupAndExit:
00465 profileLutPtr =
DisposeIfPtr(profileLutPtr);
00466
LH_END_PROC(
"MakeSessionFromLink")
00467 return err;
00468 }
00469 #if 0
00470 #define POS(x) ((x) > (0) ? (x) : -(x))
00471 CMError QuantizeNamedValues( CMMModelPtr storage,
00472 Ptr imgIn,
00473
long size )
00474 {
00475
long j,k;
00476
UINT16 *imgInPtr;
00477
UINT16 *tagTbl =
NULL,*colorPtr =
NULL;
00478
Handle tagH =
NULL;
00479
CMError err =
noErr;
00480
long elemSz,deviceChannelCount,count;
00481
UINT16 LL,aa,bb;
00482
UINT32 dE,dEnow,index;
00483
00484
LH_START_PROC(
"QuantizeNamedValues")
00485 tagH = storage->theNamedColorTagData;
00486 if (tagH==NULL)
00487 {
00488 err =
cmparamErr;
00489
goto CleanUp;
00490 }
00491
LOCK_DATA(tagH);
00492
00493
00494
00495 tagTbl = (
UINT16 *)
DATA_2_PTR(tagH) + 61;
00496
00497
00498 count = ((
icNamedColor2Type *)
DATA_2_PTR(tagH))->ncolor.count;
00499 deviceChannelCount = ((
icNamedColor2Type *)
DATA_2_PTR(tagH))->ncolor.nDeviceCoords;
00500
if (deviceChannelCount==3)
00501 {
00502 elemSz = 32+(3+3)*
sizeof(
SINT16);
00503 }
else if (deviceChannelCount == 4)
00504 {
00505 elemSz = 32+(3+4)*
sizeof(
SINT16);
00506 }
else if (deviceChannelCount == 0)
00507 {
00508 elemSz = 32+(3+0)*
sizeof(
SINT16);
00509 }
else
00510 {
00511 err =
cmparamErr;
00512
goto CleanUp;
00513 }
00514 elemSz/=2;
00515
00516 imgInPtr = (
UINT16 *) imgIn;
00517
for (j = 0; j < size; j++)
00518 {
00519 LL = (*imgInPtr+0);
00520 aa = (*imgInPtr+1);
00521 bb = (*imgInPtr+2);
00522
00523 dEnow = 0x40000;
00524 index =(
UINT32)-1;
00525 colorPtr = tagTbl;
00526
for (k = 0; k < count; k++)
00527 {
00528 dE =
POS(LL - *(colorPtr+0));
00529 dE = dE +
POS(aa - *(colorPtr+1));
00530 dE = dE +
POS(bb - *(colorPtr+2));
00531
if (dE < dEnow)
00532 {
00533 index = k;
00534 dEnow = dE;
00535 }
00536 colorPtr += elemSz;
00537 }
00538 colorPtr = tagTbl + index * elemSz;
00539 *(imgInPtr+0)= *(colorPtr+0);
00540 *(imgInPtr+1)= *(colorPtr+1);
00541 *(imgInPtr+2)= *(colorPtr+2);
00542 imgInPtr += 3;
00543 }
00544
UNLOCK_DATA(tagH);
00545 CleanUp:
00546
LH_END_PROC(
"QuantizeNamedValues")
00547 return err;
00548 }
00549 #endif