test: pi_cmm.c Source File

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