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

profcrd.c

Go to the documentation of this file.
00001 #include "generic.h" 00002 #include "icmstr.h" 00003 00004 #pragma code_seg(_ICM3SEG) 00005 00006 #define MAXCOLOR8 255 00007 00008 #pragma optimize("", off) 00009 00010 static SINT 00011 CreateHostInputOutputArray (MEMPTR lpMem, PMEMPTR ppArray, 00012 SINT numChan, SINT tableSize, SINT Offset, CSIG Tag, MEMPTR Buff); 00013 static BOOL 00014 CheckInputOutputTable(LPHOSTCLUT lpHostClut, float far *fTemp, BOOL, BOOL); 00015 BOOL 00016 GetHostCSA_Intent (CHANDLE cp, MEMPTR lpBuffer, LPDWORD lpcbSize, 00017 CSIG Intent, int Type); 00018 static BOOL 00019 CheckColorLookupTable(LPHOSTCLUT lpHostClut, float far *fTemp); 00020 static BOOL 00021 DoHostConversionCRD (LPHOSTCLUT lpHostCRD, LPHOSTCLUT lpHostCSA, 00022 float far *Input, float far *Output, 00023 CSIG ColorSpace, BOOL bCheckOutputTable); 00024 static BOOL 00025 DoHostConversionCSA (LPHOSTCLUT lpHostClut, float far *Input, float far *Output); 00026 static BOOL 00027 GetCRDInputOutputArraySize(CHANDLE cp, DWORD Intent, 00028 LPSINT lpInTbSize, LPSINT lpOutTbSize, 00029 LPCSIG lpIntentTag, LPSINT lpGrids); 00030 static void 00031 LabToXYZ(float far *Input, float far *Output, float far *whitePoint); 00032 00033 /*************************************************************************** 00034 * CreateHostInputOutputArray 00035 * function: 00036 * this is the function which creates the output array from the data 00037 * supplied in the ColorProfile's LUT8 or LUT16 tag. 00038 * parameters: 00039 * MEMPTR lpMem : The buffer to save output array. 00040 * LPHOSTCLUT lpHostClut : 00041 * SINT nOutputCh : Number of input channel. 00042 * SINT nOutputTable : The size of each input table. 00043 * SINT Offset : The position of source output data(in icc profile). 00044 * CSIG Tag : To determin the Output table is 8 or 16 bits. 00045 * MEMPTR Buff : The buffer that contains source data(copyed from icc profile) 00046 * 00047 * returns: 00048 * SINT Returns number of bytes of Output Array 00049 * 00050 ***************************************************************************/ 00051 00052 static SINT 00053 CreateHostInputOutputArray (MEMPTR lpMem, PMEMPTR ppArray, 00054 SINT numChan, SINT tableSize, 00055 SINT Offset, CSIG Tag, MEMPTR Buff) 00056 { 00057 SINT i, j; 00058 PUSHORT lpMemPtr16; 00059 MEMPTR lpMemPtr8; 00060 MEMPTR lpTable; 00061 00062 if (Tag == icSigLut8Type) 00063 lpMemPtr8 = lpMem; 00064 else 00065 lpMemPtr16 = (PUSHORT)lpMem; 00066 00067 for (i = 0; i < numChan; i++) 00068 { 00069 if (Tag == icSigLut8Type) 00070 { 00071 ppArray[i] = lpMemPtr8; 00072 lpTable = (MEMPTR) (((lpcpLut8Type) Buff)->lut.data) + 00073 Offset + 00074 tableSize * i; 00075 MemCopy(lpMemPtr8, lpTable, tableSize); 00076 lpMemPtr8 += tableSize; 00077 } 00078 else 00079 { 00080 ppArray[i] = (MEMPTR)lpMemPtr16; 00081 lpTable = (MEMPTR) (((lpcpLut16Type) Buff)->lut.data) + 00082 2 * Offset + 00083 2 * tableSize * i; 00084 for (j = 0; j < tableSize; j++) 00085 { 00086 *lpMemPtr16++ = (USHORT) ui16toSINT (lpTable); 00087 lpTable += sizeof (icUInt16Number); 00088 } 00089 } 00090 } 00091 if (Tag == icSigLut8Type) 00092 return ((SINT) ((MEMPTR)lpMemPtr8 - lpMem)); 00093 else 00094 return ((SINT) ((MEMPTR)lpMemPtr16 - lpMem)); 00095 00096 } 00097 00098 VOID 00099 GetCLUTinfo(CSIG LutTag, MEMPTR lpLut, LPSINT nInputCh, LPSINT nOutputCh, 00100 LPSINT nGrids, LPSINT nInputTable, LPSINT nOutputTable, LPSINT size) 00101 { 00102 if (LutTag == icSigLut8Type) 00103 { 00104 *nInputCh = ui8toSINT (((lpcpLut8Type) lpLut)->lut.inputChan); 00105 *nOutputCh = ui8toSINT (((lpcpLut8Type) lpLut)->lut.outputChan); 00106 *nGrids = ui8toSINT (((lpcpLut8Type) lpLut)->lut.clutPoints); 00107 *nInputTable = 256L; 00108 *nOutputTable = 256L; 00109 *size = 1; // one byte for each input\output table entry 00110 } else 00111 { 00112 *nInputCh = ui8toSINT (((lpcpLut16Type) lpLut)->lut.inputChan); 00113 *nOutputCh = ui8toSINT (((lpcpLut16Type) lpLut)->lut.outputChan); 00114 *nGrids = ui8toSINT (((lpcpLut16Type) lpLut)->lut.clutPoints); 00115 *nInputTable = ui16toSINT (((lpcpLut16Type) lpLut)->lut.inputEnt); 00116 *nOutputTable = ui16toSINT (((lpcpLut16Type) lpLut)->lut.outputEnt); 00117 *size = 2; // two bytes for each input\output table entry 00118 } 00119 } 00120 00121 /*************************************************************************** 00122 * GetHostCSA 00123 * function: 00124 * this is the function which creates a Host CSA 00125 * parameters: 00126 * CHANDLE cp -- Color Profile handle 00127 * MEMPTR lpMem -- Pointer to the memory block. If this point is NULL, 00128 * require buffer size. 00129 * LPDWORD lpcbSize -- Size of the memory block 00130 * CSIG InputIntent -- 00131 * SINT Index -- to the icc profile tag that contains the data of Intent 00132 * int Type -- DEF or DEFG 00133 * returns: 00134 * BOOL -- TRUE if the function was successful, 00135 * FALSE otherwise. 00136 ***************************************************************************/ 00137 static BOOL 00138 GetHostCSA (CHANDLE cp, MEMPTR lpMem, LPDWORD lpcbSize, 00139 CSIG InputIntent, SINT Index, int Type) 00140 { 00141 CSIG PCS, LutTag; 00142 CSIG IntentSig; 00143 SINT nInputCh, nOutputCh, nGrids, SecondGrids; 00144 SINT nInputTable, nOutputTable, nNumbers; 00145 SINT i, j, k; 00146 MEMPTR lpTable; 00147 MEMPTR lpOldMem = lpMem; 00148 MEMPTR lpLut = NULL; 00149 HGLOBAL hLut = 0; 00150 SINT LutSize; 00151 LPHOSTCLUT lpHostClut; 00152 00153 // Check if we can generate the CS. 00154 // If we cannot find the required tag - we will return false 00155 if (!GetCPConnSpace (cp, (LPCSIG) & PCS) || 00156 (PCS != icSigLabData) && (PCS != icSigXYZData) || 00157 !GetCPTagSig (cp, Index, (LPCSIG) & IntentSig)) 00158 { 00159 return (FALSE); 00160 } 00161 if (!GetCPElementType (cp, Index, (LPCSIG) & LutTag) || 00162 ((LutTag != icSigLut8Type) && (LutTag != icSigLut16Type)) || 00163 !GetCPElementSize (cp, Index, (LPSINT) & LutSize) || 00164 !MemAlloc (LutSize, (HGLOBAL FAR *) &hLut, (LPMEMPTR) & lpLut) || 00165 !GetCPElement (cp, Index, lpLut, LutSize)) 00166 { 00167 if (0 != hLut) 00168 { 00169 MemFree (hLut); 00170 } 00171 return (FALSE); 00172 } 00173 00174 // Estimate the memory size required to hold CS 00175 GetCLUTinfo(LutTag, lpLut, &nInputCh, &nOutputCh, 00176 &nGrids, &nInputTable, &nOutputTable, &i); 00177 00178 if (!(nOutputCh == 3) || 00179 !((nInputCh == 3) && (Type == TYPE_CIEBASEDDEF)) && 00180 !((nInputCh == 4) && (Type == TYPE_CIEBASEDDEFG))) 00181 { 00182 SetCPLastError (CP_POSTSCRIPT_ERR); 00183 MemFree (hLut); 00184 return (FALSE); 00185 } 00186 00187 // First Pass. This is a size request 00188 if (lpMem == NULL) 00189 { 00190 if (Type == TYPE_CIEBASEDDEFG) 00191 *lpcbSize = nOutputCh * nGrids * nGrids * nGrids * nGrids; 00192 else 00193 *lpcbSize = nOutputCh * nGrids * nGrids * nGrids; 00194 *lpcbSize = *lpcbSize + // size of RenderTable 8-bits only 00195 nInputCh * nInputTable * i + // size of input table 8/16-bits 00196 nOutputCh * nOutputTable * i + // size of output table 8/16-bits 00197 sizeof(HOSTCLUT) + 1024; // data structure + extra safe space 00198 MemFree (hLut); 00199 return (TRUE); 00200 } 00201 00202 // Second pass. constructure real HostCSA 00203 lpHostClut = (LPHOSTCLUT)lpMem; 00204 lpMem += sizeof(HOSTCLUT); 00205 lpHostClut->size = sizeof(HOSTCLUT); 00206 lpHostClut->pcs = PCS; 00207 lpHostClut->intent = InputIntent; 00208 lpHostClut->lutBits = (LutTag == icSigLut8Type)? 8:16; 00209 00210 // Get info about Illuminant White Point from the header 00211 GetCPWhitePoint (cp, (LPSFLOAT)lpHostClut->whitePoint); // .. Illuminant 00212 00213 lpHostClut->inputChan = (unsigned char)nInputCh; 00214 lpHostClut->outputChan = (unsigned char)nOutputCh; 00215 lpHostClut->clutPoints = (unsigned char)nGrids; 00216 lpHostClut->inputEnt = (USHORT)nInputTable; 00217 lpHostClut->outputEnt = (USHORT)nOutputTable; 00218 // Input Array 00219 lpMem += CreateHostInputOutputArray (lpMem, lpHostClut->inputArray, 00220 nInputCh, nInputTable, 0, LutTag, lpLut); 00221 00222 if (Type == TYPE_CIEBASEDDEFG) 00223 { 00224 i = nInputTable * nInputCh + 00225 nGrids * nGrids * nGrids * nGrids * nOutputCh; 00226 } else 00227 { 00228 i = nInputTable * nInputCh + 00229 nGrids * nGrids * nGrids * nOutputCh; 00230 } 00231 // ourput array 00232 lpMem += CreateHostInputOutputArray (lpMem, lpHostClut->outputArray, 00233 nOutputCh, nOutputTable, i, LutTag, lpLut); 00234 //********** /Table 00235 00236 lpHostClut->clut = lpMem; 00237 nNumbers = nGrids * nGrids * nOutputCh; 00238 SecondGrids = 1; 00239 if (Type == TYPE_CIEBASEDDEFG) 00240 { 00241 SecondGrids = nGrids; 00242 } 00243 for (i = 0; i < nGrids; i++) // Nh strings should be sent 00244 { 00245 for (k = 0; k < SecondGrids; k++) 00246 { 00247 if (LutTag == icSigLut8Type) 00248 { 00249 lpTable = (MEMPTR) (((lpcpLut8Type) lpLut)->lut.data) + 00250 nInputTable * nInputCh + 00251 nNumbers * (i * SecondGrids + k); 00252 } else 00253 { 00254 lpTable = (MEMPTR) (((lpcpLut16Type) lpLut)->lut.data) + 00255 2 * nInputTable * nInputCh + 00256 2 * nNumbers * (i * SecondGrids + k); 00257 } 00258 00259 if (LutTag == icSigLut8Type) 00260 { 00261 // Copy 8-bit data. 00262 MemCopy(lpMem, lpTable, nNumbers); 00263 lpMem += nNumbers; 00264 } 00265 else 00266 { 00267 // convert 16 bit integer to right format. then copy only 8 bits. 00268 for (j = 0; j < nNumbers; j++) 00269 { 00270 *lpMem++ = (BYTE)(ui16toSINT (lpTable) / 256); 00271 lpTable += sizeof (icUInt16Number); 00272 } 00273 } 00274 } 00275 } 00276 00277 *lpcbSize = (DWORD) (lpMem - lpOldMem); 00278 00279 MemFree (hLut); 00280 return (TRUE); 00281 } 00282 00283 // BUGBUG -- MOVE to CSPROF.C 00284 HGLOBAL GetTRCData(CHANDLE cp, 00285 LPMEMPTR lpRed, LPMEMPTR lpGreen, LPMEMPTR lpBlue, 00286 LPSINT lpnRed, LPSINT lpnGreen, LPSINT lpnBlue) 00287 { 00288 SINT RedTRCIndex, GreenTRCIndex, BlueTRCIndex; 00289 SINT RedTRCSize = 0, GreenTRCSize = 0, BlueTRCSize = 0; 00290 SINT MemSize; 00291 HGLOBAL hMem; 00292 00293 // Check if we can generate the CRD 00294 if (!GetTRCElementSize(cp, icSigRedTRCTag, &RedTRCIndex, &RedTRCSize) || 00295 !GetTRCElementSize(cp, icSigGreenTRCTag, &GreenTRCIndex, &GreenTRCSize) || 00296 !GetTRCElementSize(cp, icSigBlueTRCTag, &BlueTRCIndex, &BlueTRCSize)) 00297 { 00298 return 0; 00299 } 00300 MemSize = RedTRCSize + GreenTRCSize + BlueTRCSize; 00301 if (!MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) lpRed)) 00302 return 0; 00303 00304 *lpGreen = *lpRed + RedTRCSize; 00305 *lpBlue = *lpGreen + GreenTRCSize; 00306 if (!GetCPElement (cp, RedTRCIndex, *lpRed, RedTRCSize) || 00307 !GetCPElement (cp, GreenTRCIndex, *lpGreen, GreenTRCSize ) || 00308 !GetCPElement (cp, BlueTRCIndex, *lpBlue, BlueTRCSize )) 00309 { 00310 MemFree (hMem); 00311 return (NULL); 00312 } 00313 *lpnRed = ui32toSINT (((lpcpCurveType) *lpRed)->curve.count); 00314 *lpnGreen = ui32toSINT (((lpcpCurveType) *lpGreen)->curve.count); 00315 *lpnBlue = ui32toSINT (((lpcpCurveType) *lpBlue)->curve.count); 00316 00317 return (hMem); 00318 } 00319 00320 00321 static SINT 00322 CreateHostTRCInputTable(MEMPTR lpMem, LPHOSTCLUT lpHostClut, 00323 MEMPTR lpRed, MEMPTR lpGreen, MEMPTR lpBlue) 00324 { 00325 SINT i; 00326 PUSHORT lpPtr16; 00327 MEMPTR lpTable; 00328 00329 lpPtr16 = (PUSHORT)lpMem; 00330 00331 lpHostClut->inputArray[0] = (MEMPTR)lpPtr16; 00332 lpTable = (MEMPTR)(((lpcpCurveType) lpRed)->curve.data); 00333 for (i = 0; i < (SINT)(lpHostClut->inputEnt); i++) 00334 { 00335 *lpPtr16++ = (USHORT) ui16toSINT(lpTable); 00336 lpTable += sizeof(icUInt16Number); 00337 } 00338 00339 lpHostClut->inputArray[1] = (MEMPTR)lpPtr16; 00340 lpTable = (MEMPTR)(((lpcpCurveType) lpGreen)->curve.data); 00341 for (i = 0; i < (SINT)(lpHostClut->inputEnt); i++) 00342 { 00343 *lpPtr16++ = (USHORT) ui16toSINT(lpTable); 00344 lpTable += sizeof(icUInt16Number); 00345 } 00346 00347 lpHostClut->inputArray[2] = (MEMPTR)lpPtr16; 00348 lpTable = (MEMPTR)(((lpcpCurveType) lpBlue)->curve.data); 00349 for (i = 0; i < (SINT)(lpHostClut->inputEnt); i++) 00350 { 00351 *lpPtr16++ = (USHORT) ui16toSINT(lpTable); 00352 lpTable += sizeof(icUInt16Number); 00353 } 00354 return ((MEMPTR)lpPtr16 - lpMem); 00355 } 00356 00357 static SINT 00358 CreateHostRevTRCInputTable(MEMPTR lpMem, LPHOSTCLUT lpHostClut, 00359 MEMPTR lpRed, MEMPTR lpGreen, MEMPTR lpBlue) 00360 { 00361 HGLOBAL hTemp; 00362 MEMPTR lpTemp; 00363 00364 if (!MemAlloc (lpHostClut->outputEnt * (REVCURVE_RATIO + 1) * 2 , 00365 (HGLOBAL FAR *) &hTemp, (LPMEMPTR) &lpTemp)) 00366 { 00367 return (0); 00368 } 00369 00370 lpHostClut->outputArray[0] = lpMem; 00371 GetRevCurve (lpRed, lpTemp, lpHostClut->outputArray[0]); 00372 lpHostClut->outputArray[1] = lpHostClut->outputArray[0] + 00373 2 * REVCURVE_RATIO * lpHostClut->outputEnt; 00374 GetRevCurve (lpGreen, lpTemp, lpHostClut->outputArray[1]); 00375 lpHostClut->outputArray[2] = lpHostClut->outputArray[1] + 00376 2 * REVCURVE_RATIO * lpHostClut->outputEnt; 00377 GetRevCurve (lpBlue, lpTemp, lpHostClut->outputArray[2]); 00378 00379 MemFree (hTemp); 00380 return ( 2 * REVCURVE_RATIO * lpHostClut->outputEnt * 3); 00381 } 00382 00383 static BOOL 00384 GetHostMatrixCSAorCRD(CHANDLE cp, MEMPTR lpMem, LPDWORD lpcbSize, BOOL bCSA) 00385 { 00386 SINT nRedCount, nGreenCount, nBlueCount; 00387 MEMPTR lpRed = NULL,lpGreen, lpBlue; 00388 HGLOBAL hMem; 00389 LPHOSTCLUT lpHostClut; 00390 MEMPTR lpOldMem = lpMem; 00391 double pArray[9], pRevArray[9], pTemp[9]; 00392 SINT i; 00393 00394 hMem = GetTRCData(cp, 00395 (LPMEMPTR)&lpRed, (LPMEMPTR)&lpGreen, (LPMEMPTR)&lpBlue, 00396 (LPSINT)&nRedCount,(LPSINT)&nGreenCount, (LPSINT)&nBlueCount); 00397 00398 // Estimate the memory size required to hold CRD 00399 *lpcbSize = (nRedCount + nGreenCount + nBlueCount) * 2 + 00400 sizeof(HOSTCLUT) + 1024; // data structure + extra safe space 00401 00402 if (lpMem == NULL) // This is a size request 00403 { 00404 MemFree (hMem); 00405 return TRUE; 00406 } 00407 00408 lpHostClut = (LPHOSTCLUT)lpMem; 00409 lpMem += sizeof(HOSTCLUT); 00410 lpHostClut->size = sizeof(HOSTCLUT); 00411 lpHostClut->dataType = DATA_matrix; 00412 lpHostClut->clutPoints = 2; 00413 lpHostClut->pcs = icSigXYZData; 00414 GetCPWhitePoint(cp, (LPSFLOAT)lpHostClut->whitePoint); 00415 00416 if (bCSA) 00417 { 00418 lpHostClut->inputEnt = (USHORT)nRedCount; 00419 lpHostClut->inputChan = 3; 00420 lpMem += CreateHostTRCInputTable(lpMem, lpHostClut, 00421 lpRed, lpGreen, lpBlue); 00422 } 00423 else 00424 { 00425 lpHostClut->outputEnt = (USHORT)nRedCount; 00426 lpHostClut->outputChan = 3; 00427 lpMem += CreateHostRevTRCInputTable(lpMem, lpHostClut, 00428 lpRed, lpGreen, lpBlue); 00429 } 00430 00431 MemFree (hMem); 00432 *lpcbSize = (DWORD) (lpMem - lpOldMem); 00433 00434 if (!CreateColorantArray(cp, &pTemp[0], icSigRedColorantTag) || 00435 !CreateColorantArray(cp, &pTemp[3], icSigGreenColorantTag) || 00436 !CreateColorantArray(cp, &pTemp[6], icSigBlueColorantTag)) 00437 { 00438 return (FALSE); 00439 } 00440 00441 for (i = 0; i < 9; i++) 00442 { 00443 pArray[i] = pTemp[i/8*8 + i*3%8]; 00444 } 00445 00446 if (bCSA) 00447 { 00448 for (i = 0; i < 9; i++) 00449 lpHostClut->e[i] = (float)pArray[i]; 00450 } 00451 else 00452 { 00453 InvertMatrix(pArray, pRevArray); 00454 for (i = 0; i < 9; i++) 00455 lpHostClut->e[i] = (float)pRevArray[i]; 00456 } 00457 00458 return TRUE; 00459 } 00460 00461 /*************************************************************************** 00462 * GetHostCSA_Intent 00463 * function: 00464 * This is the function which creates the Host DEF or DEFGColorSpace array 00465 * based on Intent. 00466 * parameters: 00467 * cp -- Color Profile handle 00468 * lpBuffer -- Pointer to the memory block. If this point is NULL, 00469 * require buffer size. 00470 * lpcbSize -- Size of the memory block 00471 * Intent -- Intent. 00472 * Type -- CieBasedDEF or CieBasedDEF. 00473 * returns: 00474 * BOOL -- TRUE if the function was successful, 00475 * FALSE otherwise. 00476 ***************************************************************************/ 00477 00478 BOOL 00479 GetHostCSA_Intent (CHANDLE cp, MEMPTR lpBuffer, LPDWORD lpcbSize, 00480 CSIG Intent, int Type) 00481 { 00482 SINT Index; 00483 BOOL Success = FALSE; 00484 CSIG AToBxTag; 00485 00486 switch (Intent) 00487 { 00488 case icPerceptual: 00489 AToBxTag = icSigAToB0Tag; 00490 break; 00491 case icRelativeColorimetric: 00492 case icAbsoluteColorimetric: 00493 // use RelativeColorimetric data to build it. 00494 AToBxTag = icSigAToB1Tag; 00495 break; 00496 case icSaturation: 00497 AToBxTag = icSigAToB2Tag; 00498 break; 00499 default: 00500 return FALSE; 00501 break; 00502 } 00503 if (DoesCPTagExist (cp, AToBxTag) && 00504 GetCPTagIndex (cp, AToBxTag, (LPSINT) & Index)) 00505 { 00506 Success = GetHostCSA(cp, lpBuffer, lpcbSize, Intent, Index, Type); 00507 } 00508 else if ((DoesTRCAndColorantTagExist(cp)) && 00509 (Type == TYPE_CIEBASEDDEF)) 00510 { 00511 Success = GetHostMatrixCSAorCRD(cp, lpBuffer, lpcbSize, TRUE); 00512 } 00513 00514 return Success; 00515 } 00516 /*************************************************************************** 00517 * GetHostColorSpaceArray 00518 * function: 00519 * This is the main function which creates the Host CSA 00520 * from the data supplied in the Profile. 00521 * parameters: 00522 * cp -- Color Profile handle 00523 * InputIntent -- Intent. 00524 * lpBuffer -- Pointer to the memory block. If this point is NULL, 00525 * require buffer size. 00526 * lpcbSize -- Size of the memory block 00527 * returns: 00528 * BOOL -- TRUE if the function was successful, 00529 * FALSE otherwise. 00530 ***************************************************************************/ 00531 static BOOL 00532 GetHostColorSpaceArray (CHANDLE cp, DWORD InputIntent, 00533 MEMPTR lpBuffer, LPDWORD lpcbSize) 00534 { 00535 CSIG ColorSpace, Intent; 00536 BOOL Success = FALSE; 00537 00538 if (!cp) 00539 return Success; 00540 00541 if (!GetCPDevSpace (cp, (LPCSIG) & ColorSpace) || 00542 !GetCPRenderIntent (cp, (LPCSIG) & Intent)) 00543 { 00544 return Success; 00545 } 00546 if (InputIntent == icUseRenderingIntent) 00547 InputIntent = (DWORD)Intent; 00548 00549 if (!Success) 00550 { 00551 switch (ColorSpace) 00552 { 00553 case icSigRgbData: 00554 Success = GetHostCSA_Intent (cp, lpBuffer, lpcbSize, 00555 (CSIG) InputIntent, TYPE_CIEBASEDDEF); 00556 break; 00557 case icSigCmykData: 00558 Success = GetHostCSA_Intent (cp, lpBuffer, lpcbSize, 00559 (CSIG) InputIntent, TYPE_CIEBASEDDEFG); 00560 break; 00561 default: 00562 break; 00563 } 00564 } 00565 return Success; 00566 } 00567 00568 //=========================================================================== 00569 00570 /*************************************************************************** 00571 * CreateHostLutCRD 00572 * function: 00573 * this is the function which creates the Host CRD 00574 * from the data supplied in the ColorProfile's LUT8 or LUT16 tag. 00575 * parameters: 00576 * cp -- Color Profile handle 00577 * Index -- Index of the tag 00578 * lpMem -- Pointer to the memory block.If this point is NULL, 00579 * require buffer size. 00580 * InputIntent -- Intent. 00581 * 00582 * returns: 00583 * SINT -- Size of Host CRD. 00584 ***************************************************************************/ 00585 00586 static SINT 00587 CreateHostLutCRD (CHANDLE cp, SINT Index, MEMPTR lpMem, DWORD InputIntent) 00588 { 00589 SINT nInputCh, nOutputCh, nGrids; 00590 SINT nInputTable, nOutputTable, nNumbers; 00591 CSIG Tag, PCS; 00592 CSIG IntentSig; 00593 00594 SINT Ret; 00595 SINT i, j; 00596 MEMPTR lpTable; 00597 00598 MEMPTR Buff = NULL; 00599 SINT MemSize = 0; 00600 MEMPTR lpOldMem = lpMem; 00601 HGLOBAL hMem; 00602 LPHOSTCLUT lpHostClut; 00603 00604 // Check if we can generate the CRD 00605 if (!GetCPTagSig (cp, Index, (LPCSIG) & IntentSig) || 00606 !GetCPElementType (cp, Index, (LPCSIG) & Tag) || 00607 ((Tag != icSigLut8Type) && (Tag != icSigLut16Type)) || 00608 !GetCPConnSpace (cp, (LPCSIG) & PCS) || 00609 !GetCPElementSize (cp, Index, (LPSINT) & MemSize) || 00610 !MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) & Buff) || 00611 !GetCPElement (cp, Index, Buff, MemSize)) 00612 { 00613 if (NULL != Buff) 00614 { 00615 MemFree (hMem); 00616 } 00617 return (0); 00618 } 00619 00620 GetCLUTinfo(Tag, Buff, &nInputCh, &nOutputCh, 00621 &nGrids, &nInputTable, &nOutputTable, &i); 00622 00623 if (((nOutputCh != 3) && (nOutputCh != 4)) || 00624 (nInputCh != 3)) 00625 { 00626 SetCPLastError (CP_POSTSCRIPT_ERR); 00627 MemFree (hMem); 00628 return (0); 00629 } 00630 00631 // First Pass. This is a size request 00632 if (lpMem == NULL) 00633 { 00634 Ret = nInputCh * nInputTable * i + // Input table 8/16-bits 00635 nOutputCh * nOutputTable * i + // Output table 8/16-bits 00636 nOutputCh * nGrids * nGrids * nGrids + // CLUT 8-bits only 00637 sizeof(HOSTCLUT) + // Data structure 00638 1024; // safe 00639 00640 MemFree (hMem); 00641 return (Ret); 00642 } 00643 00644 // Second Pass. Get a HostCRD 00645 lpHostClut = (LPHOSTCLUT)lpMem; 00646 lpMem += sizeof(HOSTCLUT); 00647 lpHostClut->size = sizeof(HOSTCLUT); 00648 lpHostClut->pcs = PCS; 00649 lpHostClut->intent = InputIntent; 00650 lpHostClut->lutBits = (Tag == icSigLut8Type)? 8:16; 00651 00652 GetCPWhitePoint (cp, (LPSFLOAT)lpHostClut->whitePoint); // .. Illuminant 00653 00654 // Support absolute whitePoint 00655 if (!GetCPMediaWhitePoint (cp, (LPSFLOAT)lpHostClut->mediaWP)) // .. Media WhitePoint 00656 { 00657 lpHostClut->mediaWP[0] = lpHostClut->whitePoint[0]; 00658 lpHostClut->mediaWP[1] = lpHostClut->whitePoint[1]; 00659 lpHostClut->mediaWP[2] = lpHostClut->whitePoint[2]; 00660 } 00661 lpHostClut->inputChan = (unsigned char)nInputCh; 00662 lpHostClut->outputChan = (unsigned char)nOutputCh; 00663 lpHostClut->clutPoints = (unsigned char)nGrids; 00664 lpHostClut->inputEnt = (USHORT)nInputTable; 00665 lpHostClut->outputEnt = (USHORT)nOutputTable; 00666 00667 //******** Input array 00668 lpMem += CreateHostInputOutputArray (lpMem, lpHostClut->inputArray, 00669 nInputCh, nInputTable, 0, Tag, Buff); 00670 //******** the offset to the position of output array. 00671 i = nInputTable * nInputCh + 00672 nGrids * nGrids * nGrids * nOutputCh; 00673 //******** Output array 00674 lpMem += CreateHostInputOutputArray (lpMem, lpHostClut->outputArray, 00675 nOutputCh, nOutputTable, i, Tag, Buff); 00676 //******** Matrix. 00677 if (PCS == icSigXYZData) 00678 { 00679 if (Tag == icSigLut8Type) 00680 { 00681 lpTable = (MEMPTR) & ((lpcpLut8Type) Buff)->lut.e00; 00682 } else 00683 { 00684 lpTable = (MEMPTR) & ((lpcpLut16Type) Buff)->lut.e00; 00685 } 00686 for (i = 0; i < 9; i++) 00687 { 00688 lpHostClut->e[i] = (float)((si16f16toSFLOAT (lpTable)) / CIEXYZRange); 00689 lpTable += sizeof (icS15Fixed16Number); 00690 } 00691 } 00692 //********** RenderTable 00693 nNumbers = nGrids * nGrids * nOutputCh; 00694 lpHostClut->clut = lpMem; 00695 for (i = 0; i < nGrids; i++) // Na strings should be sent 00696 { 00697 if (Tag == icSigLut8Type) 00698 { 00699 lpTable = (MEMPTR) (((lpcpLut8Type) Buff)->lut.data) + 00700 nInputTable * nInputCh + 00701 nNumbers * i; 00702 } else 00703 { 00704 lpTable = (MEMPTR) (((lpcpLut16Type) Buff)->lut.data) + 00705 2 * nInputTable * nInputCh + 00706 2 * nNumbers * i; 00707 } 00708 if (Tag == icSigLut8Type) 00709 { 00710 MemCopy(lpMem, lpTable, nNumbers); 00711 lpMem += nNumbers; 00712 } 00713 else 00714 { 00715 for (j = 0; j < nNumbers; j++) 00716 { 00717 *lpMem++ = (BYTE)(ui16toSINT (lpTable) / 256); 00718 lpTable += sizeof (icUInt16Number); 00719 } 00720 } 00721 } 00722 00723 MemFree (hMem); 00724 return ((SINT) ((unsigned long) (lpMem - lpOldMem))); 00725 } 00726 00727 00728 /*************************************************************************** 00729 * GetHostColorRenderingDictionary 00730 * function: 00731 * this is the main function which creates the Host CRD 00732 * parameters: 00733 * cp -- Color Profile handle 00734 * Intent -- Intent. 00735 * lpMem -- Pointer to the memory block.If this point is NULL, 00736 * require buffer size. 00737 * lpcbSize -- size of memory block. 00738 * 00739 * returns: 00740 * SINT -- !=0 if the function was successful, 00741 * 0 otherwise. 00742 * Returns number of bytes required/transferred 00743 ***************************************************************************/ 00744 static BOOL 00745 GetHostColorRenderingDictionary (CHANDLE cp, DWORD Intent, 00746 MEMPTR lpMem, LPDWORD lpcbSize) 00747 { 00748 SINT Index; 00749 CSIG BToAxTag; 00750 00751 if (!cp) 00752 return FALSE; 00753 00754 if ((lpMem == NULL) || (*lpcbSize == 0)) 00755 { 00756 lpMem = NULL; 00757 *lpcbSize = 0; 00758 } 00759 00760 switch (Intent) 00761 { 00762 case icPerceptual: 00763 BToAxTag = icSigBToA0Tag; 00764 break; 00765 00766 case icRelativeColorimetric: 00767 case icAbsoluteColorimetric: 00768 // Use RelativeColorimetric to calculate this CRD. 00769 BToAxTag = icSigBToA1Tag; 00770 break; 00771 00772 case icSaturation: 00773 BToAxTag = icSigBToA2Tag; 00774 break; 00775 00776 default: 00777 *lpcbSize = (DWORD) 0; 00778 return FALSE; 00779 } 00780 00781 if (DoesCPTagExist (cp, BToAxTag) && 00782 GetCPTagIndex (cp, BToAxTag, (LPSINT) & Index)) 00783 { 00784 *lpcbSize = CreateHostLutCRD (cp, Index, lpMem, Intent); 00785 } 00786 else if(DoesTRCAndColorantTagExist(cp)) 00787 { 00788 GetHostMatrixCSAorCRD(cp, lpMem, lpcbSize, FALSE); 00789 } 00790 return (*lpcbSize > 0); 00791 } 00792 00793 //======================================================================== 00794 /*************************************************************************** 00795 * g 00796 * function: 00797 * Calculate function y = g(x). used in Lab->XYZ conversion 00798 * y = g(x): g(x) = x*x*x if x >= 6/29 00799 * g(x) = 108/841*(x-4/29) otherwise 00800 * parameters: 00801 * f -- x 00802 * returns: 00803 * SINT -- y 00804 ***************************************************************************/ 00805 00806 static float g(float f) 00807 { 00808 float frc; 00809 if (f >= (6/29)) 00810 { 00811 frc = f * f * f; 00812 } 00813 else 00814 { 00815 frc = f - (4.0f / 29.0f) * (108.0f / 841.0f); 00816 } 00817 return frc; 00818 } 00819 00820 /*************************************************************************** 00821 * inverse_g 00822 * function: 00823 * Calculate inverse function y = g(x). used in XYZ->Lab conversion 00824 * parameters: 00825 * f -- y 00826 * returns: 00827 * SINT -- x 00828 ***************************************************************************/ 00829 static float inverse_g(float f) 00830 { 00831 double frc; 00832 if (f >= (6.0*6.0*6.0)/(29.0*29.0*29.0)) 00833 { 00834 frc = pow(f, 1.0 / 3.0); 00835 } 00836 else 00837 { 00838 frc = f * (841.0 / 108.0) + (4.0 / 29.0); 00839 } 00840 return (float)frc; 00841 } 00842 00843 //======================================================================== 00844 00845 static BOOL 00846 TableInterp3(LPHOSTCLUT lpHostClut, float far *fTemp) 00847 { 00848 int tmpA, tmpBC; 00849 int cellA, cellB, cellC; 00850 float a, b, c; 00851 short Grids; 00852 short outputChan; 00853 MEMPTR v000, v001, v010, v011; 00854 MEMPTR v100, v101, v110, v111; 00855 float vx0x, vx1x; 00856 float v0xx, v1xx; 00857 int idx; 00858 00859 cellA = (int)(fTemp[0]); 00860 a = fTemp[0] - cellA; 00861 00862 cellB = (int)(fTemp[1]); 00863 b = fTemp[1] - cellB; 00864 00865 cellC = (int)(fTemp[2]); 00866 c = fTemp[2] - cellC; 00867 00868 Grids = lpHostClut->clutPoints; 00869 outputChan = lpHostClut->outputChan; 00870 tmpA = outputChan * Grids * Grids; 00871 tmpBC = outputChan * (Grids * cellB + cellC); 00872 00873 // Calculate 8 surrounding cells. 00874 v000 = lpHostClut->clut + tmpA * cellA + tmpBC; 00875 v001 = (cellC < (Grids - 1))? v000 + outputChan : v000; 00876 v010 = (cellB < (Grids - 1))? v000 + outputChan * Grids : v000; 00877 v011 = (cellC < (Grids - 1))? v010 + outputChan : v010 ; 00878 00879 v100 = (cellA < (Grids - 1))? v000 + tmpA : v000; 00880 v101 = (cellC < (Grids - 1))? v100 + outputChan : v100; 00881 v110 = (cellB < (Grids - 1))? v100 + outputChan * Grids : v100; 00882 v111 = (cellC < (Grids - 1))? v110 + outputChan : v110; 00883 00884 for (idx = 0; idx < outputChan; idx++) 00885 { 00886 // Calculate the average of 4 bottom cells. 00887 vx0x = *v000 + c * (int)((int)*v001 - (int)*v000); 00888 vx1x = *v010 + c * (int)((int)*v011 - (int)*v010); 00889 v0xx = vx0x + b * (vx1x - vx0x); 00890 00891 // Calculate the average of 4 upper cells. 00892 vx0x = *v100 + c * (int)((int)*v101 - (int)*v100); 00893 vx1x = *v110 + c * (int)((int)*v111 - (int)*v110); 00894 v1xx = vx0x + b * (vx1x - vx0x); 00895 00896 // Calculate the bottom and upper average. 00897 fTemp[idx] = (v0xx + a * (v1xx - v0xx)) / MAXCOLOR8; 00898 00899 if ( idx < (outputChan - 1)) 00900 { 00901 v000++; 00902 v001++; 00903 v010++; 00904 v011++; 00905 v100++; 00906 v101++; 00907 v110++; 00908 v111++; 00909 } 00910 } 00911 00912 return TRUE; 00913 } 00914 00915 static BOOL 00916 TableInterp4(LPHOSTCLUT lpHostClut, float far *fTemp) 00917 { 00918 int tmpH, tmpI, tmpJK; 00919 int cellH, cellI, cellJ, cellK; 00920 float h, i, j, k; 00921 short Grids; 00922 short outputChan; 00923 MEMPTR v0000, v0001, v0010, v0011; 00924 MEMPTR v0100, v0101, v0110, v0111; 00925 MEMPTR v1000, v1001, v1010, v1011; 00926 MEMPTR v1100, v1101, v1110, v1111; 00927 float vxx0x, vxx1x; 00928 float vx0xx, vx1xx; 00929 float v0xxx, v1xxx; 00930 int idx; 00931 00932 cellH = (int)(fTemp[0]); 00933 h = fTemp[0] - cellH; 00934 00935 cellI = (int)(fTemp[1]); 00936 i = fTemp[1] - cellI; 00937 00938 cellJ = (int)(fTemp[2]); 00939 j = fTemp[2] - cellJ; 00940 00941 cellK = (int)(fTemp[3]); 00942 k = fTemp[3] - cellK; 00943 00944 Grids = lpHostClut->clutPoints; 00945 outputChan = lpHostClut->outputChan; 00946 tmpI = outputChan * Grids * Grids; 00947 tmpH = tmpI * Grids; 00948 tmpJK = outputChan * (Grids * cellJ + cellK); 00949 00950 // Calculate 16 surrounding cells. 00951 v0000 = lpHostClut->clut + tmpH * cellH + tmpI * cellI + tmpJK; 00952 v0001 = (cellK < (Grids - 1))? v0000 + outputChan : v0000; 00953 v0010 = (cellJ < (Grids - 1))? v0000 + outputChan * Grids : v0000; 00954 v0011 = (cellK < (Grids - 1))? v0010 + outputChan : v0010; 00955 00956 v0100 = (cellI < (Grids - 1))? v0000 + tmpI : v0000; 00957 v0101 = (cellK < (Grids - 1))? v0100 + outputChan : v0100; 00958 v0110 = (cellJ < (Grids - 1))? v0100 + outputChan * Grids : v0100; 00959 v0111 = (cellK < (Grids - 1))? v0110 + outputChan : v0110; 00960 00961 v1000 = (cellH < (Grids - 1))? v0000 + tmpH : v0000; 00962 v1001 = (cellK < (Grids - 1))? v1000 + outputChan : v1000; 00963 v1010 = (cellJ < (Grids - 1))? v1000 + outputChan * Grids : v1000; 00964 v1011 = (cellK < (Grids - 1))? v1010 + outputChan : v1010; 00965 00966 v1100 = (cellI < (Grids - 1))? v1000 + tmpI : v1000; 00967 v1101 = (cellK < (Grids - 1))? v1100 + outputChan : v1100; 00968 v1110 = (cellJ < (Grids - 1))? v1100 + outputChan * Grids : v1100; 00969 v1111 = (cellK < (Grids - 1))? v1110 + outputChan : v1110; 00970 00971 for (idx = 0; idx < outputChan; idx++) 00972 { 00973 // Calculate the average of 8 bottom cells. 00974 vxx0x = *v0000 + k * (int)((int)*v0001 - (int)*v0000); 00975 vxx1x = *v0010 + k * (int)((int)*v0011 - (int)*v0010); 00976 vx0xx = vxx0x + j * (vxx1x - vxx0x); 00977 vxx0x = *v0100 + k * (int)((int)*v0101 - (int)*v0100); 00978 vxx1x = *v0110 + k * (int)((int)*v0111 - (int)*v0110); 00979 vx1xx = vxx0x + j * (vxx1x - vxx0x); 00980 v0xxx = vx0xx + i * (vx1xx - vx0xx); 00981 00982 // Calculate the average of 8 upper cells. 00983 vxx0x = *v1000 + k * (int)((int)*v1001 - (int)*v1000); 00984 vxx1x = *v1010 + k * (int)((int)*v1011 - (int)*v1010); 00985 vx0xx = vxx0x + j * (vxx1x - vxx0x); 00986 vxx0x = *v1100 + k * (int)((int)*v1101 - (int)*v1100); 00987 vxx1x = *v1110 + k * (int)((int)*v1111 - (int)*v1110); 00988 vx1xx = vxx0x + j * (vxx1x - vxx0x); 00989 v1xxx = vx0xx + i * (vx1xx - vx0xx); 00990 00991 // Calculate the bottom and upper average. 00992 fTemp[idx] = (v0xxx + h * (v1xxx - v0xxx)) / MAXCOLOR8; 00993 00994 if ( idx < (outputChan - 1)) 00995 { 00996 v0000++; 00997 v0001++; 00998 v0010++; 00999 v0011++; 01000 v0100++; 01001 v0101++; 01002 v0110++; 01003 v0111++; 01004 v1000++; 01005 v1001++; 01006 v1010++; 01007 v1011++; 01008 v1100++; 01009 v1101++; 01010 v1110++; 01011 v1111++; 01012 } 01013 } 01014 01015 return TRUE; 01016 } 01017 01018 01019 /*************************************************************************** 01020 * CheckColorLookupTable 01021 * function: 01022 * This function check RenderTable. 01023 * parameters: 01024 * LPHOSTCLUT lpHostClut -- 01025 * float far *fTemp -- Input (in range [0 gred-1]) / 01026 * output(in range [0 1) 01027 * returns: 01028 * BOOL -- TRUE 01029 ***************************************************************************/ 01030 01031 static BOOL 01032 CheckColorLookupTable(LPHOSTCLUT lpHostClut, float far *fTemp) 01033 { 01034 if (lpHostClut->inputChan == 3) 01035 { 01036 TableInterp3(lpHostClut, fTemp); 01037 } 01038 else if(lpHostClut->inputChan == 4) 01039 { 01040 TableInterp4(lpHostClut, fTemp); 01041 } 01042 return TRUE; 01043 } 01044 01045 /*************************************************************************** 01046 * CheckInputOutputTable 01047 * function: 01048 * This function check inputTable. 01049 * parameters: 01050 * LPHOSTCLUT lpHostClut -- 01051 * float far *fTemp -- Input / output data 01052 * returns: 01053 * BOOL -- TRUE 01054 ***************************************************************************/ 01055 static BOOL 01056 CheckInputOutputTable(LPHOSTCLUT lpHostClut, float far *fTemp, 01057 BOOL bCSA, BOOL bInputTable) 01058 { 01059 int i; 01060 short Grids; 01061 USHORT floor1, ceiling1; 01062 float fIndex; 01063 int numChan; 01064 int numEnt; 01065 PMEMPTR ppArray; 01066 01067 if (bInputTable) 01068 { 01069 numChan = lpHostClut->inputChan; 01070 numEnt = lpHostClut->inputEnt - 1; 01071 ppArray = lpHostClut->inputArray; 01072 } 01073 else 01074 { 01075 numChan = lpHostClut->outputChan; 01076 numEnt = lpHostClut->outputEnt - 1; 01077 ppArray = lpHostClut->outputArray; 01078 } 01079 01080 Grids = lpHostClut->clutPoints; 01081 for (i = 0; (i <= MAXCHANNELS) && (i < numChan); i++) 01082 { 01083 fTemp[i] = (fTemp[i] < 0)? 0: ((fTemp[i] > 1)? 1: fTemp[i]); 01084 fIndex = fTemp[i] * numEnt; 01085 if (lpHostClut->lutBits == 8) 01086 { 01087 floor1 = ppArray[i][(int)fIndex]; 01088 ceiling1 = ppArray[i][((int)fIndex) + 1]; 01089 fTemp[i] = (float)(floor1 + (ceiling1 - floor1) * (fIndex - floor(fIndex))); 01090 if (bCSA && !bInputTable) 01091 fTemp[i] = (float)(fTemp[i] / 127.0); 01092 else 01093 fTemp[i] = (float)(fTemp[i] / 255.0); 01094 } 01095 else 01096 { 01097 floor1 = ((PUSHORT)(ppArray[i]))[(int)fIndex]; 01098 ceiling1 = ((PUSHORT)(ppArray[i]))[((int)fIndex) + 1]; 01099 fTemp[i] = (float)(floor1 + (ceiling1 - floor1) * (fIndex - floor(fIndex))); 01100 if (bCSA && !bInputTable) 01101 fTemp[i] = (float)(fTemp[i] / 32767.0); 01102 else 01103 fTemp[i] = (float)(fTemp[i] / 65535.0); 01104 01105 } 01106 if (bInputTable) 01107 { 01108 fTemp[i] *= (Grids - 1); 01109 if (fTemp[i] > (Grids - 1)) 01110 fTemp[i] = (float)(Grids - 1); 01111 } 01112 } 01113 return TRUE; 01114 } 01115 01116 static void 01117 LabToXYZ(float far *Input, float far *Output, float far *whitePoint) 01118 { 01119 float fL, fa, fb; 01120 01121 fL = (Input[0] * 50 + 16) / 116; 01122 fa = (Input[1] * 128 - 128) / 500; 01123 fb = (Input[2] * 128 - 128) / 200; 01124 Output[0] = whitePoint[0] * g(fL + fa); 01125 Output[1] = whitePoint[1] * g(fL); 01126 Output[2] = whitePoint[2] * g(fL - fb); 01127 } 01128 01129 static void 01130 XYZToLab(float far *Input, float far *Output, float far *whitePoint) 01131 { 01132 float fL, fa, fb; 01133 01134 fL = inverse_g(Input[0] / whitePoint[0]); 01135 fa = inverse_g(Input[1] / whitePoint[1]); 01136 fb = inverse_g(Input[2] / whitePoint[2]); 01137 Output[0] = (fa * 116 - 16) / 100; 01138 Output[1] = (fL * 500 - fa * 500 + 128) / 255; 01139 Output[2] = (fa * 200 - fb * 200 + 128) / 255; 01140 } 01141 01142 static void 01143 ApplyMatrix(PFLOAT e, float far *Input, float far *Output) 01144 { 01145 SINT i, j; 01146 01147 for (i = 0; i < 3; i++) 01148 { 01149 j = i*3; 01150 Output[i] = e[j ] * Input[0] + 01151 e[j + 1] * Input[1] + 01152 e[j + 2] * Input[2]; 01153 } 01154 } 01155 01156 /*************************************************************************** 01157 * DoHostConversionCRD 01158 * function: 01159 * This function converts XYZ/Lab to RGB/CMYK by using HostCRD 01160 * parameters: 01161 * LPHOSTCLUT lpHostCRD -- pointer to a HostCRD 01162 * LPHOSTCLUT lpHostCSA -- pointer to a HostCSA 01163 * float far *Input -- Input XYZ/Lab 01164 * float far *Output -- Output RGB/CMYK 01165 * returns: 01166 * BOOL -- TRUE 01167 ***************************************************************************/ 01168 static BOOL 01169 DoHostConversionCRD (LPHOSTCLUT lpHostCRD, LPHOSTCLUT lpHostCSA, 01170 float far *Input, float far *Output, 01171 CSIG ColorSpace, BOOL bCheckOutputTable) 01172 { 01173 float fTemp[MAXCHANNELS]; 01174 float fTemp1[MAXCHANNELS]; 01175 int i; 01176 01180 // When sampling the deviceCRD, skip the input table. 01181 // If lpHostCSA is not NULL, the current CRD is targetCRD, we 01182 // need to do input table conversion 01183 if (lpHostCSA) 01184 { 01185 // Convert Lab to XYZ in range [ 0 whitePoint ] 01186 if ((lpHostCRD->pcs == icSigXYZData) && 01187 (lpHostCSA->pcs == icSigLabData)) 01188 { 01189 LabToXYZ(Input, fTemp1, lpHostCRD->whitePoint); 01190 } 01191 // Convert XYZ to Lab in range [ 0 1] 01192 else if ((lpHostCRD->pcs == icSigLabData) && 01193 (lpHostCSA->pcs == icSigXYZData)) 01194 { 01195 XYZToLab(Input, fTemp, lpHostCSA->whitePoint); 01196 } 01197 // Convert Lab to range [ 0 1] 01198 else if ((lpHostCRD->pcs == icSigLabData) && 01199 (lpHostCSA->pcs == icSigLabData)) 01200 { 01201 for (i = 0; i < 3; i++) 01202 fTemp[i] = Input[i] / 2; 01203 } 01204 // Convert XYZ to XYZ (based on white point) to range [0 1] 01205 else 01206 { // TODO: different intents using different conversion. 01207 // icRelativeColorimetric: using Bradford transform. 01208 // icAbsoluteColorimetric: using scaling. 01209 for (i = 0; i < 3; i++) 01210 fTemp1[i] = Input[i] * lpHostCRD->whitePoint[i] / lpHostCSA->whitePoint[i]; 01211 } 01212 01213 // Matrix, used for XYZ data only or Matrix icc profile only 01214 if (lpHostCRD->pcs == icSigXYZData) 01215 { 01216 ApplyMatrix(lpHostCRD->e, fTemp1, fTemp); 01217 } 01218 01219 if (lpHostCRD->dataType != DATA_matrix) 01220 { 01221 //Search input Table 01222 CheckInputOutputTable(lpHostCRD, fTemp, 0, 1); 01223 } 01224 } 01225 // If the current CRD is device CRD, we do not need to do input 01226 // table conversion. 01227 else 01228 { 01229 short Grids; 01230 Grids = lpHostCRD->clutPoints; 01231 // Sample data may be XYZ or Lab. It depends on Target icc profile. 01232 // If the PCS of the target icc profile is XYZ, input data will be XYZ. 01233 // If the PCS of the target icc profile is Lab, input data will be Lab. 01234 01235 if (lpHostCRD->dataType == DATA_matrix) 01236 { 01237 for (i = 0; i < 3; i++) 01238 { 01239 fTemp[i] = Input[i]; 01240 } 01241 } 01242 else 01243 { 01244 for (i = 0; i < 3; i++) 01245 { 01246 fTemp[i] = Input[i]* (Grids - 1); 01247 if (fTemp[i] > (Grids - 1)) 01248 fTemp[i] = (float)(Grids - 1); 01249 } 01250 } 01251 } // bCheckInputTable 01252 01253 if (lpHostCRD->dataType != DATA_matrix) 01254 { 01255 // Rendering table 01256 CheckColorLookupTable(lpHostCRD, fTemp); 01257 01261 } 01262 if (bCheckOutputTable) 01263 { 01264 //Output Table 01265 CheckInputOutputTable(lpHostCRD, fTemp, 0, 0); 01266 } 01267 for (i = 0; (i <= MAXCHANNELS) && (i < lpHostCRD->outputChan); i++) 01268 { 01269 Output[i] = fTemp[i]; 01270 } 01271 01272 return TRUE; 01273 } 01274 01275 /*************************************************************************** 01276 * DoHostConversionCSA 01277 * function: 01278 * This function converts RGB/CMYK to XYZ/Lab by using HostCSA 01279 * parameters: 01280 * LPHOSTCLUT lpHostCLUT -- pointer to a HostCSA 01281 * float far *Input -- Input XYZ/Lab 01282 * float far *Output -- Output RGB/CMYK 01283 * returns: 01284 * BOOL -- TRUE 01285 ***************************************************************************/ 01286 01287 static BOOL 01288 DoHostConversionCSA (LPHOSTCLUT lpHostClut, float far *Input, float far *Output) 01289 { 01290 float fTemp[MAXCHANNELS]; 01291 int i; 01292 01296 for (i = 0; (i <= MAXCHANNELS) && (i < lpHostClut->inputChan); i++) 01297 { 01298 fTemp[i] = Input[i]; 01299 } 01300 01301 if (lpHostClut->dataType == DATA_matrix) 01302 { 01303 //Search input Table 01304 CheckInputOutputTable(lpHostClut, fTemp, 1, 1); 01305 ApplyMatrix(lpHostClut->e, fTemp, Output); 01306 } 01307 else 01308 { 01309 //Search input Table 01310 CheckInputOutputTable(lpHostClut, fTemp, 1, 1); 01311 01312 // Rendering table 01313 CheckColorLookupTable(lpHostClut, fTemp); 01314 01315 //Output Table 01316 CheckInputOutputTable(lpHostClut, fTemp, 1, 0 ); 01317 01321 for (i = 0; (i <= MAXCHANNELS) && (i < lpHostClut->outputChan); i++) 01322 { 01323 Output[i] = fTemp[i]; 01324 } 01325 } 01326 01327 return TRUE; 01328 } 01329 01330 static BOOL 01331 GetCRDInputOutputArraySize(CHANDLE cp, DWORD Intent, 01332 LPSINT lpInTbSize, LPSINT lpOutTbSize, 01333 LPCSIG lpIntentTag, LPSINT lpGrids) 01334 { 01335 CSIG Tag; 01336 SINT Index; 01337 SINT Ret = 0; 01338 MEMPTR Buff = NULL; 01339 SINT MemSize = 0; 01340 HGLOBAL hMem; 01341 SINT outputChan, outputEnt; 01342 SINT inputChan, inputEnt; 01343 SINT Grids; 01344 SINT i; 01345 01346 switch (Intent) 01347 { 01348 case icPerceptual: 01349 *lpIntentTag = icSigBToA0Tag; 01350 break; 01351 01352 case icRelativeColorimetric: 01353 case icAbsoluteColorimetric: 01354 *lpIntentTag = icSigBToA1Tag; 01355 break; 01356 01357 case icSaturation: 01358 *lpIntentTag = icSigBToA2Tag; 01359 break; 01360 01361 default: 01362 return FALSE; 01363 } 01364 if (!DoesCPTagExist (cp, *lpIntentTag) || 01365 !GetCPTagIndex (cp, *lpIntentTag, (LPSINT) & Index) || 01366 !GetCPElementType (cp, Index, (LPCSIG) & Tag) || 01367 ((Tag != icSigLut8Type) && (Tag != icSigLut16Type)) || 01368 !GetCPElementSize (cp, Index, (LPSINT) & MemSize) || 01369 !MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) & Buff) || 01370 !GetCPElement (cp, Index, Buff, MemSize)) 01371 { 01372 BOOL retVal = FALSE; 01373 01374 if (NULL != Buff) 01375 { 01376 MemFree (hMem); 01377 } 01378 01379 // Matrix icc profile. 01380 01381 *lpGrids = 2; 01382 if (lpInTbSize) 01383 { 01384 retVal = GetHostCSA_Intent (cp, NULL, lpInTbSize, 01385 (CSIG) Intent, TYPE_CIEBASEDDEF); 01386 *lpInTbSize = *lpInTbSize * 3; 01387 } 01388 if (lpOutTbSize) 01389 { 01390 retVal = GetHostCSA_Intent (cp, NULL, lpOutTbSize, 01391 (CSIG) Intent, TYPE_CIEBASEDDEF); 01392 *lpOutTbSize = *lpOutTbSize * 3; 01393 } 01394 return retVal; 01395 } 01396 01397 if (lpInTbSize) 01398 { 01399 GetCLUTinfo(Tag, Buff, &inputChan, &outputChan, 01400 &Grids, &inputEnt, &outputEnt, &i); 01401 01402 if (inputChan != 3) 01403 { 01404 MemFree (hMem); 01405 return FALSE; 01406 } 01407 01408 *lpInTbSize = inputChan * inputEnt * 6; // Number of INT bytes 01409 *lpGrids = Grids; 01410 } 01411 01412 if (lpOutTbSize) 01413 { 01414 GetCLUTinfo(Tag, Buff, &inputChan, &outputChan, 01415 &Grids, &inputEnt, &outputEnt, &i); 01416 01417 if ((outputChan != 3) && (outputChan != 4)) 01418 { 01419 MemFree (hMem); 01420 return FALSE; 01421 } 01422 *lpOutTbSize = outputChan * outputEnt * 6; // Number of INT bytes 01423 *lpGrids = Grids; 01424 } 01425 01426 MemFree (hMem); 01427 return TRUE; 01428 } 01429 01430 /*************************************************************************** 01431 * CreateOutputArray 01432 * function: 01433 * Create CSA/CRD output arrays from the data supplied in icc profile's 01434 * LUT8 or LUT16 tags. 01435 * parameters: 01436 * MEMPTR lpMem -- a pointer to a buffer which will contain the arrays. 01437 * SINT nOutputCh -- Number of output channel. if lpHostClut, no meaning. 01438 * SINT nOutputTable -- saze of each array. if lpHostClut, no meaning. 01439 * SINT Offset -- offset of Buff, point to the 1st byte of output array in CLUT. 01440 * if lpHostClut, no meaning. 01441 * MEMPTR Intent -- 01442 * CSIG Tag -- LUT8 or LUT16 01443 * MEMPTR Buff -- point to a buffer which contain LUT8 or LUT16. 01444 * if NULL, use lpHostClut. 01445 * BOOL AllowBinary -- 01446 * MEMPTR lpHostClut -- point to host CSA/CRD. if NULL, use Buff. 01447 * returns: 01448 * SINT -- The size of output array created. 01449 ***************************************************************************/ 01450 01451 SINT 01452 CreateOutputArray (MEMPTR lpMem, SINT nOutputCh, 01453 SINT nOutputTable, SINT Offset, MEMPTR Intent, 01454 CSIG Tag, MEMPTR Buff, BOOL AllowBinary, MEMPTR lpHostClut) 01455 { 01456 SINT i, j; 01457 MEMPTR lpOldMem; 01458 MEMPTR lpTable; 01459 MEMPTR lpLineStart; 01460 lpOldMem = lpMem; 01461 01462 if (lpHostClut) 01463 { 01464 nOutputCh = (SINT)(((LPHOSTCLUT)lpHostClut)->outputChan); 01465 nOutputTable = (SINT)(((LPHOSTCLUT)lpHostClut)->outputEnt); 01466 Tag = (((LPHOSTCLUT)lpHostClut)->lutBits == 8)? 01467 icSigLut8Type : icSigLut16Type; 01468 } 01469 01470 for (i = 0; i < nOutputCh; i++) 01471 { 01472 lpLineStart = lpMem; 01473 lpMem += WriteNewLineObject (lpMem, Slash); 01474 if (lpHostClut) 01475 lpMem += WriteObject (lpMem, PreViewOutArray); 01476 else 01477 lpMem += WriteObject (lpMem, OutputArray); 01478 lpMem += WriteObjectN (lpMem, Intent, lstrlen (Intent)); 01479 lpMem += WriteInt (lpMem, i); 01480 01481 if (lpHostClut) 01482 lpTable = ((LPHOSTCLUT)lpHostClut)->outputArray[i]; 01483 else 01484 { 01485 if (Tag == icSigLut8Type) 01486 lpTable = (MEMPTR) (((lpcpLut8Type) Buff)->lut.data) + 01487 Offset + 01488 nOutputTable * i; 01489 else 01490 lpTable = (MEMPTR) (((lpcpLut16Type) Buff)->lut.data) + 01491 2 * Offset + 01492 2 * nOutputTable * i; 01493 } 01494 01495 if (!AllowBinary) // Output ASCII CRD 01496 { 01497 if (Tag == icSigLut8Type) 01498 { 01499 lpMem += WriteObject (lpMem, BeginString); 01500 lpMem += WriteHexBuffer (lpMem, lpTable, lpLineStart, nOutputTable); 01501 lpMem += WriteObject (lpMem, EndString); 01502 } else 01503 { 01504 lpMem += WriteObject (lpMem, BeginArray); 01505 for (j = 0; j < nOutputTable; j++) 01506 { 01507 if (lpHostClut) 01508 lpMem += WriteInt (lpMem, *((PUSHORT)lpTable)); 01509 else 01510 lpMem += WriteInt (lpMem, ui16toSINT (lpTable)); 01511 lpTable += sizeof (icUInt16Number); 01512 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 01513 { 01514 lpLineStart = lpMem; 01515 lpMem += WriteObject (lpMem, NewLine); 01516 } 01517 } 01518 lpMem += WriteObject (lpMem, EndArray); 01519 } 01520 } else 01521 { // Output BINARY CRD 01522 if (Tag == icSigLut8Type) 01523 { 01524 lpMem += WriteStringToken (lpMem, 143, 256); 01525 lpMem += WriteByteString (lpMem, lpTable, 256L); 01526 } else 01527 { 01528 lpMem += WriteHNAToken (lpMem, 149, nOutputTable); 01529 if (lpHostClut) 01530 lpMem += WriteIntStringU2S_L (lpMem, lpTable, nOutputTable); 01531 else 01532 lpMem += WriteIntStringU2S (lpMem, lpTable, nOutputTable); 01533 } 01534 } 01535 lpMem += WriteObject (lpMem, DefOp); 01536 } 01537 01538 return ((SINT) (lpMem - lpOldMem)); 01539 } 01540 01541 /*************************************************************************** 01542 * CreateInputArray 01543 * function: 01544 * Create CSA/CRD Input arrays from the data supplied in icc profile's 01545 * LUT8 or LUT16 tags. 01546 * parameters: 01547 * MEMPTR lpMem -- a pointer to the buffer which will contain the arrays. 01548 * SINT nInputCh -- Number of input channel. if lpHostClut, no meaning. 01549 * SINT nInputTable -- saze of each array. if lpHostClut, no meaning. 01550 * SINT Offset -- offset of Buff, point to the 1st byte of output array in CLUT. 01551 * if lpHostClut, no meaning. 01552 * MEMPTR Intent -- 01553 * CSIG Tag -- LUT8 or LUT16 01554 * MEMPTR Buff -- point to a buffer which contains LUT8 or LUT16. 01555 * if NULL, use lpHostClut. 01556 * BOOL AllowBinary -- 01557 * MEMPTR lpHostClut -- point to host CSA/CRD. if NULL, use Buff. 01558 * returns: 01559 * SINT -- The size of inpput array created. 01560 ***************************************************************************/ 01561 01562 SINT 01563 CreateInputArray (MEMPTR lpMem, SINT nInputCh, 01564 SINT nInputTable, MEMPTR Intent, CSIG Tag, 01565 MEMPTR Buff, BOOL bAllowBinary, MEMPTR lpHostClut) 01566 { 01567 SINT i, j; 01568 MEMPTR lpOldMem; 01569 MEMPTR lpTable; 01570 MEMPTR lpLineStart; 01571 lpOldMem = lpMem; 01572 01573 if (lpHostClut) 01574 { 01575 nInputCh = (SINT)(((LPHOSTCLUT)lpHostClut)->inputChan); 01576 nInputTable = (SINT)(((LPHOSTCLUT)lpHostClut)->inputEnt); 01577 Tag = (((LPHOSTCLUT)lpHostClut)->lutBits == 8)? 01578 icSigLut8Type : icSigLut16Type; 01579 } 01580 01581 for (i = 0; i < nInputCh; i++) 01582 { 01583 lpLineStart = lpMem; 01584 lpMem += WriteNewLineObject (lpMem, Slash); 01585 if (lpHostClut) 01586 lpMem += WriteObject (lpMem, PreViewInArray); 01587 else 01588 lpMem += WriteObject (lpMem, InputArray); 01589 lpMem += WriteObjectN (lpMem, Intent, lstrlen (Intent)); 01590 lpMem += WriteInt (lpMem, i); 01591 01592 if (lpHostClut) 01593 { 01594 lpTable = ((LPHOSTCLUT)lpHostClut)->inputArray[i]; 01595 } 01596 else 01597 { 01598 if (Tag == icSigLut8Type) 01599 lpTable = (MEMPTR) (((lpcpLut8Type) Buff)->lut.data) + nInputTable * i; 01600 else 01601 lpTable = (MEMPTR) (((lpcpLut16Type) Buff)->lut.data) + 2 * nInputTable * i; 01602 } 01603 if (!bAllowBinary) // Output ASCII CRD 01604 { 01605 if (Tag == icSigLut8Type) 01606 { 01607 lpMem += WriteObject (lpMem, BeginString); 01608 lpMem += WriteHexBuffer (lpMem, lpTable,lpLineStart, nInputTable); 01609 lpMem += WriteObject (lpMem, EndString); 01610 } else 01611 { 01612 lpMem += WriteObject (lpMem, BeginArray); 01613 for (j = 0; j < nInputTable; j++) 01614 { 01615 if(lpHostClut) 01616 lpMem += WriteInt (lpMem, *((PUSHORT)lpTable)); 01617 else 01618 lpMem += WriteInt (lpMem, ui16toSINT (lpTable)); 01619 lpTable += sizeof (icUInt16Number); 01620 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 01621 { 01622 lpLineStart = lpMem; 01623 lpMem += WriteObject (lpMem, NewLine); 01624 } 01625 } 01626 lpMem += WriteObject (lpMem, EndArray); 01627 } 01628 } else 01629 { // Output BINARY CRD 01630 if (Tag == icSigLut8Type) 01631 { 01632 lpMem += WriteStringToken (lpMem, 143, 256); 01633 lpMem += WriteByteString (lpMem, lpTable, 256L); 01634 } else 01635 { 01636 lpMem += WriteHNAToken (lpMem, 149, nInputTable); 01637 if (lpHostClut) 01638 lpMem += WriteIntStringU2S_L (lpMem, lpTable, nInputTable); 01639 else 01640 lpMem += WriteIntStringU2S (lpMem, lpTable, nInputTable); 01641 } 01642 } 01643 lpMem += WriteObject (lpMem, DefOp); 01644 } 01645 01646 return ((SINT) (lpMem - lpOldMem)); 01647 } 01648 01649 SINT 01650 SendCRDLMN(MEMPTR lpMem, CSIG Intent, LPSFLOAT whitePoint, LPSFLOAT mediaWP, CSIG pcs) 01651 { 01652 MEMPTR lpOldMem; 01653 SINT i, j; 01654 01655 lpOldMem = lpMem; 01656 01657 //********** /MatrixLMN 01658 if (icAbsoluteColorimetric == Intent) 01659 { 01660 lpMem += WriteNewLineObject (lpMem, MatrixLMNTag); 01661 01662 lpMem += WriteObject (lpMem, BeginArray); 01663 for (i = 0; i < 3; i++) 01664 { 01665 for (j = 0; j < 3; j++) 01666 lpMem += WriteFloat (lpMem, 01667 (double) (i == j) ? whitePoint[i] / mediaWP[i] : 0.0); 01668 } 01669 lpMem += WriteObject (lpMem, EndArray); 01670 } 01671 //********** /RangeLMN 01672 lpMem += WriteNewLineObject (lpMem, RangeLMNTag); 01673 if (pcs == icSigXYZData) 01674 { 01675 lpMem += WriteObject (lpMem, BeginArray); 01676 for (i = 0; i < 3; i++) 01677 { 01678 lpMem += WriteFloat (lpMem, (double) 0); 01679 lpMem += WriteFloat (lpMem, (double) whitePoint[i]); 01680 } 01681 lpMem += WriteObject (lpMem, EndArray); 01682 } else 01683 { 01684 lpMem += WriteObject (lpMem, RangeLMNLab); 01685 } 01686 01687 //********** /EncodeLMN 01688 lpMem += WriteNewLineObject (lpMem, EncodeLMNTag); 01689 lpMem += WriteObject (lpMem, BeginArray); 01690 for (i = 0; i < 3; i++) 01691 { 01692 lpMem += WriteObject (lpMem, BeginFunction); 01693 if (pcs != icSigXYZData) 01694 { 01695 lpMem += WriteFloat (lpMem, (double)whitePoint[i]); 01696 lpMem += WriteObject (lpMem, DivOp); 01697 lpMem += WriteObject (lpMem, EncodeLMNLab); 01698 } 01699 lpMem += WriteObject (lpMem, EndFunction); 01700 } 01701 lpMem += WriteObject (lpMem, EndArray); 01702 01703 return (SINT)(lpMem - lpOldMem); 01704 } 01705 01706 01707 SINT 01708 SendCRDPQR(MEMPTR lpMem, CSIG Intent, LPSFLOAT whitePoint) 01709 { 01710 MEMPTR lpOldMem; 01711 SINT i; 01712 01713 lpOldMem = lpMem; 01714 01715 if (icAbsoluteColorimetric != Intent) 01716 { 01717 //********** /RangePQR 01718 lpMem += WriteNewLineObject (lpMem, RangePQRTag); 01719 lpMem += WriteObject (lpMem, RangePQR); 01720 01721 //********** /MatrixPQR 01722 lpMem += WriteNewLineObject (lpMem, MatrixPQRTag); 01723 lpMem += WriteObject (lpMem, MatrixPQR); 01724 } 01725 else 01726 { 01727 //********** /RangePQR 01728 lpMem += WriteNewLineObject (lpMem, RangePQRTag); 01729 lpMem += WriteObject (lpMem, BeginArray); 01730 for (i = 0; i < 3; i++) 01731 { 01732 lpMem += WriteFloat (lpMem, (double) 0); 01733 lpMem += WriteFloat (lpMem, (double)(whitePoint[i])); 01734 } 01735 lpMem += WriteObject (lpMem, EndArray); 01736 //********** /MatrixPQR 01737 lpMem += WriteNewLineObject (lpMem, MatrixPQRTag); 01738 lpMem += WriteObject (lpMem, Identity); 01739 } 01740 //********** /TransformPQR 01741 lpMem += WriteNewLineObject (lpMem, TransformPQRTag); 01742 lpMem += WriteObject (lpMem, BeginArray); 01743 for (i = 0; i < 3; i++) 01744 { 01745 lpMem += WriteObject (lpMem, BeginFunction); 01746 lpMem += WriteObject (lpMem, 01747 (icAbsoluteColorimetric != Intent) ? TransformPQR[i] : NullOp); 01748 lpMem += WriteObject (lpMem, EndFunction); 01749 } 01750 lpMem += WriteObject (lpMem, EndArray); 01751 01752 return (SINT)(lpMem - lpOldMem); 01753 } 01754 01755 SINT 01756 SendCRDABC(MEMPTR lpMem, MEMPTR PublicArrayName, CSIG pcs, SINT nInputCh, 01757 MEMPTR Buff, LPSFLOAT e, CSIG LutTag, BOOL bAllowBinary) 01758 { 01759 MEMPTR lpOldMem; 01760 SINT i, j; 01761 double TempMatrixABC[9]; 01762 MEMPTR lpTable; 01763 MEMPTR lpLineStart; 01764 lpOldMem = lpMem; 01765 01766 //********** /RangeABC 01767 lpMem += WriteNewLineObject (lpMem, RangeABCTag); 01768 lpMem += WriteObject (lpMem, RangeABC); 01769 //********** /MatrixABC 01770 lpMem += WriteNewLineObject (lpMem, MatrixABCTag); 01771 if (pcs == icSigXYZData) 01772 { 01773 lpMem += WriteObject (lpMem, BeginArray); 01774 if (e) 01775 { 01776 for (i = 0; i < 3; i++) 01777 { 01778 for (j = 0; j < 3; j++) 01779 { 01780 lpMem += WriteFloat (lpMem, e[i + j * 3]); 01781 } 01782 } 01783 } 01784 else 01785 { 01786 if (LutTag == icSigLut8Type) 01787 { 01788 lpTable = (MEMPTR) & ((lpcpLut8Type) Buff)->lut.e00; 01789 } else 01790 { 01791 lpTable = (MEMPTR) & ((lpcpLut16Type) Buff)->lut.e00; 01792 } 01793 for (i = 0; i < 9; i++) 01794 { 01795 TempMatrixABC[i] = ((double) si16f16toSFLOAT (lpTable)) / CIEXYZRange; 01796 lpTable += sizeof (icS15Fixed16Number); 01797 } 01798 for (i = 0; i < 3; i++) 01799 { 01800 for (j = 0; j < 3; j++) 01801 { 01802 lpMem += WriteFloat (lpMem, TempMatrixABC[i + j * 3]); 01803 } 01804 } 01805 } 01806 lpMem += WriteObject (lpMem, EndArray); 01807 } else 01808 { 01809 lpMem += WriteObject (lpMem, MatrixABCLabCRD); 01810 } 01811 //********** /EncodeABC 01812 if (nInputCh == 0) 01813 return (SINT)(lpMem - lpOldMem); 01814 01815 lpLineStart = lpMem; 01816 lpMem += WriteNewLineObject (lpMem, EncodeABCTag); 01817 lpMem += WriteObject (lpMem, BeginArray); 01818 for (i = 0; i < nInputCh; i++) 01819 { 01820 lpLineStart = lpMem; 01821 lpMem += WriteNewLineObject (lpMem, BeginFunction); 01822 if (pcs == icSigLabData) 01823 { 01824 lpMem += WriteObject (lpMem, 01825 (0 == i) ? EncodeABCLab1 : EncodeABCLab2); 01826 } 01827 lpMem += WriteObject (lpMem, StartClip); 01828 if (e) 01829 lpMem += WriteObject (lpMem, PreViewInArray); 01830 else 01831 lpMem += WriteObject (lpMem, InputArray); 01832 lpMem += WriteObjectN (lpMem, (MEMPTR) PublicArrayName, lstrlen (PublicArrayName)); 01833 lpMem += WriteInt (lpMem, i); 01834 01835 if (!bAllowBinary) // Output ASCII CRD 01836 { 01837 lpMem += WriteNewLineObject (lpMem, IndexArray); 01838 } else 01839 { // Output BINARY CRD 01840 if (LutTag == icSigLut8Type) 01841 { 01842 lpMem += WriteObject (lpMem, IndexArray); 01843 } else 01844 { 01845 lpMem += WriteObject (lpMem, IndexArray16b); 01846 } 01847 } 01848 lpMem += WriteObject (lpMem, (LutTag == icSigLut8Type) ? 01849 Scale8 : Scale16); 01850 lpMem += WriteObject (lpMem, EndClip); 01851 lpMem += WriteObject (lpMem, EndFunction); 01852 } 01853 lpMem += WriteObject (lpMem, EndArray); 01854 return (SINT)(lpMem - lpOldMem); 01855 } 01856 01857 SINT 01858 SendCRDBWPoint(MEMPTR lpMem, LPSFLOAT whitePoint) 01859 { 01860 MEMPTR lpOldMem; 01861 SINT i; 01862 01863 lpOldMem = lpMem; 01864 01865 //********** /BlackPoint 01866 lpMem += WriteNewLineObject (lpMem, BlackPointTag); 01867 lpMem += WriteObject (lpMem, BlackPoint); 01868 01869 //********** /WhitePoint 01870 lpMem += WriteNewLineObject (lpMem, WhitePointTag); 01871 lpMem += WriteObject (lpMem, BeginArray); 01872 for (i = 0; i < 3; i++) 01873 { 01874 lpMem += WriteFloat (lpMem, (double)(whitePoint[i])); 01875 } 01876 lpMem += WriteObject (lpMem, EndArray); 01877 return (SINT)(lpMem - lpOldMem); 01878 } 01879 01880 SINT SendCRDOutputTable(MEMPTR lpMem, MEMPTR PublicArrayName, 01881 SINT nOutputCh, CSIG LutTag, BOOL bHost, BOOL bAllowBinary) 01882 { 01883 MEMPTR lpOldMem; 01884 SINT i; 01885 01886 lpOldMem = lpMem; 01887 01888 for (i = 0; i < nOutputCh; i++) 01889 { 01890 lpMem += WriteNewLineObject (lpMem, BeginFunction); 01891 lpMem += WriteObject (lpMem, Clip01); 01892 if (bHost) 01893 lpMem += WriteObject (lpMem, PreViewOutArray); 01894 else 01895 lpMem += WriteObject (lpMem, OutputArray); 01896 lpMem += WriteObjectN (lpMem, (MEMPTR) PublicArrayName, lstrlen (PublicArrayName)); 01897 lpMem += WriteInt (lpMem, i); 01898 01899 if (!bAllowBinary) // Output ASCII CRD 01900 { 01901 lpMem += WriteObject (lpMem, NewLine); 01902 if (LutTag == icSigLut8Type) 01903 { 01904 lpMem += WriteObject (lpMem, TFunction8); 01905 } else 01906 { 01907 lpMem += WriteObject (lpMem, IndexArray); 01908 lpMem += WriteObject (lpMem, Scale16); 01909 } 01910 } else 01911 { // Output BINARY CRD 01912 if (LutTag == icSigLut8Type) 01913 { 01914 lpMem += WriteObject (lpMem, TFunction8); 01915 } else 01916 { 01917 lpMem += WriteObject (lpMem, IndexArray16b); 01918 lpMem += WriteObject (lpMem, Scale16); 01919 } 01920 } 01921 01922 lpMem += WriteObject (lpMem, EndFunction); 01923 } 01924 return (SINT)(lpMem - lpOldMem); 01925 } 01926 01927 //======================================================================== 01928 /*************************************************************************** 01929 * GetPS2PreviewColorRenderingDictionary 01930 * function: 01931 * This is the main function that creates proofing CRD. 01932 * It does the following: 01933 * 1) Creates host TargetCRD, TargetCSA and DevCRD. 01934 * 2) Create proofing CRD by sampling TargetCRD TargetCSA and DevCRD. 01935 * 3) Uses TargetCRD's input table as proofingCRD's input table. 01936 * 4) Uses DevCRD's output table as proofingCRD's output table. 01937 * 5) Sample data is XYZ or Lab, depends on PCS of TargetCRD. 01938 * 01939 * parameters: 01940 * CHANDLE cpDev -- handle to Target icc profile. 01941 * CHANDLE cpTarget -- handle to Dev icc profile. 01942 * DWORD Intent -- intent 01943 * MEMPTR lpMem -- pointer to buffer for proofCRD, 01944 * NULL means query buffer size. 01945 * LPDWORD lpcbSize -- as input: current buffer size 01946 * -- as output: real proofCRD size. 01947 * BOOL bAllowBinary -- create a ascii or binary proofCRD. 01948 * 01949 * returns: 01950 * BOOL -- TRUE/FALSE 01951 ***************************************************************************/ 01952 01953 BOOL EXTERN 01954 GetPS2PreviewColorRenderingDictionary (CHANDLE cpDev, 01955 CHANDLE cpTarget, 01956 DWORD Intent, 01957 MEMPTR lpMem, 01958 LPDWORD lpcbSize, 01959 BOOL bAllowBinary) 01960 { 01961 MEMPTR lpTargetCRD, lpTargetCSA, lpDevCRD; 01962 DWORD cbTargetCRD, cbTargetCSA, cbDevCRD; 01963 HGLOBAL hTargetCRD, hTargetCSA, hDevCRD; 01964 BOOL Success = FALSE; 01965 float Input[MAXCHANNELS]; 01966 float Output[MAXCHANNELS]; 01967 float Temp[MAXCHANNELS]; 01968 int i, j, k, l; 01969 MEMPTR lpLineStart; 01970 MEMPTR lpOldMem; 01971 CSIG ColorSpace; 01972 CSIG DevColorSpace; 01973 static CSIG IntentTag; 01974 static SINT PreviewCRDGrid; 01975 SINT OutArraySize, InArraySize; 01976 char PublicArrayName[TempBfSize]; 01977 SINT TargetGrids, DevGrids; 01978 01979 // First pass, return the size of Previewind CRD. 01980 if (lpMem == NULL) 01981 { 01982 SINT dwOutArraySizr = 0; 01983 01984 i = 3; // Default output channal; 01985 if ((GetCPDevSpace (cpDev, (LPCSIG) & DevColorSpace)) && 01986 (DevColorSpace == icSigCmykData)) 01987 { 01988 i = 4; 01989 } 01990 01991 // Get the input array size IntentTag and Grid of the Target icc profile. 01992 if (!GetCRDInputOutputArraySize(cpTarget, Intent, 01993 &InArraySize, NULL, &IntentTag, &TargetGrids )) 01994 return FALSE; 01995 01996 // Get the output array size IntentTag and Grid of the Dev icc profile. 01997 if (!GetCRDInputOutputArraySize(cpDev, Intent, 01998 NULL, &OutArraySize, &IntentTag, &DevGrids )) 01999 return FALSE; 02000 02001 PreviewCRDGrid = (TargetGrids > DevGrids)? TargetGrids: DevGrids; 02002 02003 // Min proofing CRD grid will be PREVIEWCRDGRID 02004 if (PreviewCRDGrid < PREVIEWCRDGRID) 02005 PreviewCRDGrid = PREVIEWCRDGRID; 02006 *lpcbSize = PreviewCRDGrid * PreviewCRDGrid * PreviewCRDGrid * 02007 i * 2 + // CLUT size (Hex output) 02008 OutArraySize + // Output Array size 02009 InArraySize + // Input Array size 02010 4096; // Extra PostScript staff. 02011 return (TRUE); 02012 } 02013 02014 // Second pass, return the Previewind CRD. 02015 lpOldMem = lpMem; 02016 02017 //Query the sizes of Host TargetCRD, TargetCSA and DevCRD. 02018 if (!(GetHostColorRenderingDictionary (cpTarget, Intent, NULL, &cbTargetCRD)) || 02019 !(GetHostColorSpaceArray (cpTarget, Intent, NULL, &cbTargetCSA)) || 02020 !(GetHostColorRenderingDictionary (cpDev, Intent, NULL, &cbDevCRD))) 02021 { 02022 return (Success); 02023 } 02024 02025 //Alloc the buffers for Host TargetCRD, TargetCSA and DevCRD. 02026 hTargetCRD = hTargetCSA = hDevCRD = 0; 02027 if (!MemAlloc (cbTargetCRD, (HGLOBAL FAR *)&hTargetCRD, (LPMEMPTR)&lpTargetCRD) || 02028 !MemAlloc (cbTargetCSA, (HGLOBAL FAR *)&hTargetCSA, (LPMEMPTR)&lpTargetCSA) || 02029 !MemAlloc (cbDevCRD, (HGLOBAL FAR *)&hDevCRD, (LPMEMPTR)&lpDevCRD)) 02030 { 02031 goto Done; 02032 } 02033 02034 //Build Host TargetCRD, TargetCSA and DevCRD. 02035 if (!(GetHostColorRenderingDictionary (cpTarget, Intent, lpTargetCRD, &cbTargetCRD)) || 02036 !(GetHostColorSpaceArray (cpTarget, Intent, lpTargetCSA, &cbTargetCSA)) || 02037 !(GetHostColorRenderingDictionary (cpDev, Intent, lpDevCRD, &cbDevCRD))) 02038 { 02039 goto Done; 02040 } 02041 02042 // Build Proofing CRD based on Host TargetCRD TargetCSA and DevCRD. 02043 // We use TargetCRD input tables and matrix as the 02044 // input tables and matrix of the ProofCRD. 02045 // We use DevCRD output tables as the output tables of the ProofCRD. 02046 02047 //******** Define golbal array used in EncodeABC and RenderTaber 02048 GetPublicArrayName (cpDev, IntentTag, PublicArrayName); 02049 lpMem += WriteNewLineObject (lpMem, CRDBegin); 02050 02051 lpMem += EnableGlobalDict(lpMem); 02052 lpMem += BeginGlobalDict(lpMem); 02053 02054 lpMem += CreateInputArray (lpMem, (SINT)0, (SINT)0, (MEMPTR)PublicArrayName, 02055 (CSIG)0, NULL, bAllowBinary, lpTargetCRD); 02056 02057 lpMem += CreateOutputArray (lpMem, (SINT)0, (SINT)0, (SINT)0, 02058 (MEMPTR)PublicArrayName, (CSIG)0, NULL, bAllowBinary, lpDevCRD); 02059 02060 lpMem += EndGlobalDict(lpMem); 02061 02062 //************* Start writing CRD **************************** 02063 lpMem += WriteNewLineObject (lpMem, BeginDict); // Begin dictionary 02064 lpMem += WriteObject (lpMem, DictType); // Dictionary type 02065 02066 lpMem += WriteNewLineObject (lpMem, IntentType); // RenderingIntent 02067 switch (Intent) 02068 { 02069 case icPerceptual: 02070 lpMem += WriteObject (lpMem, IntentPer); 02071 break; 02072 02073 case icSaturation: 02074 lpMem += WriteObject (lpMem, IntentSat); 02075 break; 02076 02077 case icRelativeColorimetric: 02078 lpMem += WriteObject (lpMem, IntentRCol); 02079 break; 02080 02081 case icAbsoluteColorimetric: 02082 lpMem += WriteObject (lpMem, IntentACol); 02083 break; 02084 } 02085 02086 //********** Send Black/White Point. 02087 lpMem += SendCRDBWPoint(lpMem, 02088 ((LPHOSTCLUT)lpTargetCRD)->whitePoint); 02089 02090 //********** Send PQR - For White Point correction 02091 lpMem += SendCRDPQR(lpMem, Intent, 02092 ((LPHOSTCLUT)lpTargetCRD)->whitePoint); 02093 02094 //********** Send LMN - For Absolute Colorimetric use WhitePoint's XYZs 02095 lpMem += SendCRDLMN(lpMem, Intent, 02096 ((LPHOSTCLUT)lpTargetCRD)->whitePoint, 02097 ((LPHOSTCLUT)lpTargetCRD)->mediaWP, 02098 ((LPHOSTCLUT)lpTargetCRD)->pcs); 02099 02100 //********** Create MatrixABC and EncodeABC stuff 02101 lpMem += SendCRDABC(lpMem, PublicArrayName, 02102 ((LPHOSTCLUT)lpTargetCRD)->pcs, 02103 ((LPHOSTCLUT)lpTargetCRD)->inputChan, 02104 NULL, 02105 ((LPHOSTCLUT)lpTargetCRD)->e, 02106 (((LPHOSTCLUT)lpTargetCRD)->lutBits == 8)? icSigLut8Type:icSigLut16Type, 02107 bAllowBinary); 02108 02109 //********** /RenderTable 02110 lpMem += WriteNewLineObject (lpMem, RenderTableTag); 02111 lpMem += WriteObject (lpMem, BeginArray); 02112 02113 lpMem += WriteInt (lpMem, PreviewCRDGrid); // Send down Na 02114 lpMem += WriteInt (lpMem, PreviewCRDGrid); // Send down Nb 02115 lpMem += WriteInt (lpMem, PreviewCRDGrid); // Send down Nc 02116 02117 lpLineStart = lpMem; 02118 lpMem += WriteNewLineObject (lpMem, BeginArray); 02119 ColorSpace = ((LPHOSTCLUT)lpDevCRD)->pcs; 02120 for (i = 0; i < PreviewCRDGrid; i++) // Na strings should be sent 02121 { 02122 lpMem += WriteObject (lpMem, NewLine); 02123 lpLineStart = lpMem; 02124 if (bAllowBinary) 02125 { 02126 lpMem += WriteStringToken (lpMem, 143, 02127 PreviewCRDGrid * PreviewCRDGrid * ((LPHOSTCLUT)lpDevCRD)->outputChan); 02128 } 02129 else 02130 { 02131 lpMem += WriteObject (lpMem, BeginString); 02132 } 02133 Input[0] = ((float)i) / (PreviewCRDGrid - 1); 02134 for (j = 0; j < PreviewCRDGrid; j++) 02135 { 02136 Input[1] = ((float)j) / (PreviewCRDGrid - 1); 02137 for (k = 0; k < PreviewCRDGrid; k++) 02138 { 02139 Input[2] = ((float)k) / (PreviewCRDGrid - 1); 02140 02141 DoHostConversionCRD ((LPHOSTCLUT)lpTargetCRD, NULL, Input, Output, ColorSpace, 1); 02142 DoHostConversionCSA ((LPHOSTCLUT)lpTargetCSA, Output, Temp); 02143 DoHostConversionCRD ((LPHOSTCLUT)lpDevCRD, (LPHOSTCLUT)lpTargetCSA, 02144 Temp, Output, 0, 0); 02145 for (l = 0; l < ((LPHOSTCLUT)lpDevCRD)->outputChan; l++) 02146 { 02147 if (bAllowBinary) 02148 { 02149 *lpMem++ = (BYTES)(Output[l]*255); 02150 } 02151 else 02152 { 02153 lpMem += WriteHex (lpMem, (USHORT)(Output[l]*255)); 02154 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 02155 { 02156 lpLineStart = lpMem; 02157 lpMem += WriteObject (lpMem, NewLine); 02158 } 02159 } 02160 } 02161 } 02162 } 02163 if (!bAllowBinary) 02164 lpMem += WriteObject (lpMem, EndString); 02165 } 02166 lpMem += WriteNewLineObject (lpMem, EndArray); 02167 lpMem += WriteInt (lpMem, ((LPHOSTCLUT)lpDevCRD)->outputChan); 02168 02169 //********** Send Output Table. 02170 lpMem += SendCRDOutputTable(lpMem, PublicArrayName, 02171 ((LPHOSTCLUT)lpDevCRD)->outputChan, 02172 (((LPHOSTCLUT)lpDevCRD)->lutBits == 8)? icSigLut8Type:icSigLut16Type, 02173 TRUE, 02174 bAllowBinary); 02175 02176 02177 lpMem += WriteNewLineObject (lpMem, EndArray); 02178 lpMem += WriteObject (lpMem, EndDict); // End dictionary definition 02179 lpMem += WriteNewLineObject (lpMem, CRDEnd); 02180 Success = TRUE; 02181 02182 Done: 02183 *lpcbSize = (DWORD)(lpMem - lpOldMem); 02184 02185 if (hTargetCRD) 02186 MemFree(hTargetCRD); 02187 if (hTargetCSA) 02188 MemFree(hTargetCSA); 02189 if (hDevCRD) 02190 MemFree(hDevCRD); 02191 return (Success); 02192 }

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