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