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

pi_cmm.c

Go to the documentation of this file.
00001 /* 00002 File: PI_CMMInitialization.c 00003 00004 Contains: 00005 00006 Written by: U. J. Krabbenhoeft 00007 00008 Version: 00009 00010 Copyright: � 1993-1997 by Heidelberger Druckmaschinen AG, all rights reserved. 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 /*#include "DebugSpecial.h"*/ 00035 /*#include "LH_Util.h"*/ 00036 #endif 00037 #endif 00038 00039 #define ALLOW_DEVICE_LINK /* allows link as the last profile in a chain, change in genluts.c too */ 00040 /* ______________________________________________________________________ 00041 00042 CMError CMMInitPrivate( CMMModelPtr storage, 00043 CMProfileRef srcProfile, 00044 CMProfileRef dstProfile ); 00045 00046 Abstract: 00047 ColorWorld function called to initialize a matching session. 00048 00049 Params: 00050 Storage (in) Reference to CMMModel. 00051 srcProfile (in) Reference to source CMProfileRef. 00052 dstProfile (in) Reference to destination CMProfileRef. 00053 00054 Return: 00055 noErr successful 00056 System or result code if an error occurs. 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 /* --------------------------------------------------------------------------------------- valid profiles ???*/ 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 /* --------------------------------------------------------------------------------------- initialization*/ 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 /* --------------------------------------------------------------------------------------- check version of source profile*/ 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 /* --------------------------------------------------------------------------------------- check version of destination profile*/ 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); /* lookup vs. interpolation */ 00156 00157 #ifdef RenderInt 00158 if( storage-> dwFlags != 0xffffffff ){ 00159 storage->lookup = (Boolean)((storage-> dwFlags & kLookupOnlyMask)>>16); 00160 } 00161 #endif 00162 /* --------------------------------------------------------------------------------------- 'normal' cases*/ 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 /* profileSet->flags = sourceHeader.flags; */ 00170 profileSet->profileSet[0] = srcProfile; 00171 /* profileSet->profileSet[0]->renderingIntent = sourceHeader.renderingIntent; */ 00172 profileSet->profileSet[1] = dstProfile; 00173 /* profileSet->profileSet[1]->renderingIntent = destHeader.renderingIntent; */ 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 /* ------------------------------------------------------------------------------------------ get first header */ 00228 err = CMGetProfileHeader( profileSet->profileSet[0], &firstHeader); 00229 if (err) 00230 goto CleanupAndExit; 00231 /* ------------------------------------------------------------------------------------------ only one profile? -> has to be a link profile */ 00232 storage->lookup = (Boolean)((firstHeader.flags & kLookupOnlyMask)>>16); /* lookup vs. interpolation */ 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 /* -------------------------------------------------------------------------------------- get last header */ 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 /* ------------------------------------------------------------------------------------------ valid profiles ??? */ 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 /* -------------------------------------------------------------------------------------- link profiles may not be used inbetween */ 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 /* ------------------------------------------------------------------------------------------ no abstract profile as first or last */ 00299 if ( (count >1) && ( (firstHeader.deviceClass == icSigAbstractClass) || (lastHeader.deviceClass == icSigAbstractClass) ) ) 00300 { 00301 err = cmCantConcatenateError; 00302 goto CleanupAndExit; 00303 } 00304 00305 /* ------------------------------------------------------------------------------------------ initialization */ 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 /* ------------------------------------------------------------------------------------------ check 'special' cases */ 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 /* -------------------------------------------------------- get partial tag data from profile */ 00369 err = CMGetProfileElement(theCombiData->theProfile, theTag, &elementSize, nil); 00370 if (err) 00371 goto CleanupAndExit; 00372 00373 byteCount = 52; /* get the first 52 bytes out of the profile */ 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 /* ---------------------------------------------------------------------- process A Lut */ 00445 err = Extract_MFT_Alut( theLutData, theCombiData, profileLutPtr, theTag ); 00446 if (err) 00447 goto CleanupAndExit; 00448 00449 /* ---------------------------------------------------------------------- process X Lut */ 00450 err = Extract_MFT_Xlut ( theLutData, theCombiData, profileLutPtr, theTag ); 00451 if (err) 00452 goto CleanupAndExit; 00453 00454 /* ---------------------------------------------------------------------- process E Lut */ 00455 err = Extract_MFT_Elut( theLutData, theCombiData, profileLutPtr, theTag ); 00456 if (err) 00457 goto CleanupAndExit; 00458 00459 storage->lutParam = *theLutData; 00460 00461 /* --------------------------------------------------------------------------------- 00462 clean up 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 /* tagTbl should now point to beginning of first device data */ 00494 /* = CMNamedColor2Type_header(84) + firstName(32) + PCSSize(3*2) */ 00495 tagTbl = (UINT16 *)DATA_2_PTR(tagH) + 61; 00496 00497 /* find out how many bytes to skip per element. div'ed 2 for indexing purpose */ 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 /* go through the whole table to find the closest one*/ 00523 dEnow = 0x40000; /* just arbitrarily high = 256*256*4 */ 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

Generated on Sat May 15 19:41:10 2004 for test by doxygen 1.3.7