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

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