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

getcrd.c

Go to the documentation of this file.
00001 #include "generic.h" 00002 00003 #pragma code_seg(_ICMSEG) 00004 00005 char ICMSEG BeginString[] = "<"; 00006 char ICMSEG EndString[] = ">"; 00007 char ICMSEG BeginArray[] = "["; 00008 char ICMSEG EndArray[] = "]"; 00009 char ICMSEG BeginFunction[] = "{"; 00010 char ICMSEG EndFunction[] = "}bind "; 00011 char ICMSEG BeginDict[] = "<<" ; 00012 char ICMSEG EndDict[] = ">>" ; 00013 char ICMSEG BlackPoint[] = "[0 0 0]" ; 00014 char ICMSEG DictType[] = "/ColorRenderingType 1 "; 00015 00016 char ICMSEG WhitePointTag[] = "/WhitePoint " ; 00017 char ICMSEG BlackPointTag[] = "/BlackPoint " ; 00018 char ICMSEG RangePQRTag[] = "/RangePQR " ; 00019 char ICMSEG TransformPQRTag[] = "/TransformPQR " ; 00020 char ICMSEG MatrixPQRTag[] = "/MatrixPQR " ; 00021 00022 char ICMSEG RangeABCTag[] = "/RangeABC " ; 00023 char ICMSEG MatrixATag[] = "/MatrixA "; 00024 char ICMSEG MatrixABCTag[] = "/MatrixABC "; 00025 char ICMSEG EncodeABCTag[] = "/EncodeABC " ; 00026 char ICMSEG RangeLMNTag[] = "/RangeLMN " ; 00027 char ICMSEG MatrixLMNTag[] = "/MatrixLMN " ; 00028 char ICMSEG EncodeLMNTag[] = "/EncodeLMN " ; 00029 char ICMSEG RenderTableTag[] = "/RenderTable " ; 00030 char ICMSEG CIEBasedATag[] = "/CIEBasedA " ; 00031 char ICMSEG CIEBasedABCTag[] = "/CIEBasedABC " ; 00032 char ICMSEG CIEBasedDEFGTag[] = "/CIEBasedDEFG " ; 00033 char ICMSEG CIEBasedDEFTag[] = "/CIEBasedDEF " ; 00034 char ICMSEG DecodeATag[] = "/DecodeA " ; 00035 char ICMSEG DecodeABCTag[] = "/DecodeABC " ; 00036 char ICMSEG DecodeLMNTag[] = "/DecodeLMN " ; 00037 char ICMSEG DeviceRGBTag[] = "/DeviceRGB " ; 00038 char ICMSEG DeviceCMYKTag[] = "/DeviceCMYK " ; 00039 char ICMSEG DeviceGrayTag[] = "/DeviceGray " ; 00040 char ICMSEG TableTag[] = "/Table " ; 00041 char ICMSEG DecodeDEFGTag[] = "/DecodeDEFG " ; 00042 char ICMSEG DecodeDEFTag[] = "/DecodeDEF " ; 00043 00044 char ICMSEG NullOp[] = ""; 00045 char ICMSEG DupOp[] = "dup "; 00046 char ICMSEG UserDictOp[] = "userdict "; 00047 char ICMSEG GlobalDictOp[] = "globaldict "; 00048 char ICMSEG CurrentGlobalOp[] = "currentglobal "; 00049 char ICMSEG SetGlobalOp[] = "setglobal "; 00050 char ICMSEG DefOp[] = "def "; 00051 char ICMSEG BeginOp[] = "begin "; 00052 char ICMSEG EndOp[] = "end "; 00053 char ICMSEG TrueOp[] = "true "; 00054 char ICMSEG FalseOp[] = "false "; 00055 char ICMSEG MulOp[] = "mul "; 00056 char ICMSEG DivOp[] = "div "; 00057 00058 char ICMSEG NewLine[] = "\n" ; 00059 char ICMSEG Slash[] = "/" ; 00060 char ICMSEG Space[] = " " ; 00061 char ICMSEG CRDBegin[] = "%** CRD Begin "; 00062 char ICMSEG CRDEnd[] = "%** CRD End "; 00063 char ICMSEG CieBasedDEFGBegin[] = "%** CieBasedDEFG CSA Begin "; 00064 char ICMSEG CieBasedDEFBegin[] = "%** CieBasedDEF CSA Begin "; 00065 char ICMSEG CieBasedABCBegin[] = "%** CieBasedABC CSA Begin "; 00066 char ICMSEG CieBasedABegin[] = "%** CieBasedA CSA Begin "; 00067 char ICMSEG CieBasedDEFGEnd[] = "%** CieBasedDEFG CSA End "; 00068 char ICMSEG CieBasedDEFEnd[] = "%** CieBasedDEF CSA End "; 00069 char ICMSEG CieBasedABCEnd[] = "%** CieBasedABC CSA End "; 00070 char ICMSEG CieBasedAEnd[] = "%** CieBasedA CSA End "; 00071 char ICMSEG RangeABC[] = "[ 0 1 0 1 0 1 ] "; 00072 char ICMSEG RangeLMN[] = "[ 0 2 0 2 0 2 ] "; 00073 char ICMSEG Identity[] = "[1 0 0 0 1 0 0 0 1]"; 00074 char ICMSEG RangeABC_Lab[] = "[0 100 -128 127 -128 127]"; 00075 00076 /********** This PostScript code clips incoming value between 0.0 and 1.0 00077 Use: x <clip> -- <clipped x> */ 00078 char ICMSEG Clip01[] = "dup 1.0 ge{pop 1.0}{dup 0.0 lt{pop 0.0}if}ifelse " ; 00079 char ICMSEG DecodeA3[] = "256 div exp "; 00080 char ICMSEG DecodeA3Rev[] = "256 div 1.0 exch div exp "; 00081 char ICMSEG DecodeABCArray[] = "DecodeABC_"; 00082 char ICMSEG InputArray[] = "Inp_"; 00083 char ICMSEG OutputArray[] = "Out_"; 00084 char ICMSEG PreViewInArray[] = "IPV_"; 00085 char ICMSEG PreViewOutArray[] = "OPV_"; 00086 00087 00088 // This PostScript segment takes value in range from 0.0 to 1.0 and 00089 // interpolates the result using array supplied. 00090 // x [array] -- <interpolated value> 00091 00092 char ICMSEG IndexArray16b[] = \ 00093 " dup length 1 sub 3 -1 roll mul dup dup floor cvi \ 00094 exch ceiling cvi 3 index exch get 32768 add 4 -1 roll 3 -1 roll get 32768 add \ 00095 dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add "; 00096 00097 char ICMSEG IndexArray[] = \ 00098 " dup length 1 sub 3 -1 roll mul dup dup floor cvi \ 00099 exch ceiling cvi 3 index exch get 4 -1 roll 3 -1 roll get \ 00100 dup 3 1 roll sub 3 -1 roll dup floor cvi sub mul add "; 00101 00102 char ICMSEG TestingDEFG[] = \ 00103 "/SupportDEFG? {/CIEBasedDEFG /ColorSpaceFamily resourcestatus { pop pop true}{false} ifelse} def"; 00104 00105 char ICMSEG SupportDEFG_S[] = "SupportDEFG? { "; 00106 char ICMSEG NotSupportDEFG_S[] = "SupportDEFG? not { "; 00107 char ICMSEG SupportDEFG_E[] = "}if "; 00108 00109 char ICMSEG StartClip[] = "dup 1.0 le{dup 0.0 ge{" ; 00110 char ICMSEG EndClip[] = "}if}if " ; 00111 00112 char ICMSEG Scale8[] = "255 div " ; 00113 char ICMSEG Scale16[] = "65535 div " ; 00114 char ICMSEG Scale16XYZ[] = "32768 div " ; 00115 char ICMSEG TFunction8[] = "exch 255 mul round cvi get 255 div " ; 00116 char ICMSEG TFunction8XYZ[] = "exch 255 mul round cvi get 128 div " ; 00117 char ICMSEG MatrixABCLab[] = "[1 1 1 1 0 0 0 0 -1]" ; 00118 char ICMSEG DecodeABCLab1[] = "[{16 add 116 div} bind {500 div} bind {200 div} bind]"; 00119 char ICMSEG DecodeALab[] = " 50 mul 16 add 116 div "; 00120 char ICMSEG DecodeLMNLab[] = \ 00121 "dup 0.206897 ge{dup dup mul mul}{0.137931 sub 0.128419 mul} ifelse "; 00122 00123 char ICMSEG RangeLMNLab[] = "[0 1 0 1 0 1]" ; 00124 char ICMSEG EncodeLMNLab[] = "\ 00125 dup 0.008856 le{7.787 mul 0.13793 add}{0.3333 exp}ifelse " ; 00126 00127 char ICMSEG MatrixABCLabCRD[] = "[0 500 0 116 -500 200 0 0 -200]" ; 00128 char ICMSEG MatrixABCXYZCRD[] = "[0 1 0 1 0 0 0 0 1]" ; 00129 char ICMSEG EncodeABCLab1[] = "16 sub 100 div " ; 00130 char ICMSEG EncodeABCLab2[] = "128 add 255 div " ; 00131 00132 char ICMSEG RangePQR[] = "[ -0.07 2.2 -0.02 1.4 -0.2 4.8 ]"; 00133 char ICMSEG MatrixPQR[] = "[0.8951 -0.7502 0.0389 0.2664 1.7135 -0.0685 -0.1614 0.0367 1.0296]"; 00134 00135 char *TransformPQR[3] = { 00136 "exch pop exch 3 get mul exch pop exch 3 get div ", 00137 "exch pop exch 4 get mul exch pop exch 4 get div ", 00138 "exch pop exch 5 get mul exch pop exch 5 get div " }; 00139 00140 #pragma optimize("",off) 00141 00142 /*************************************************************************** 00143 * CreateLutCRD 00144 * function: 00145 * this is the function which creates the Color Rendering Dictionary (CRD) 00146 * from the data supplied in the ColorProfile's LUT8 or LUT16 tag. 00147 * prototype: 00148 * SINT EXTERN CreateLutCRD( 00149 * CHANDLE cp, 00150 * SINT Index, 00151 * MEMPTR lpMem, 00152 * BOOL AllowBinary) 00153 * parameters: 00154 * cp -- Color Profile handle 00155 * Index -- Index of the tag 00156 * lpMem -- Pointer to the memory block 00157 * AllowBinary -- 1: binary CRD allowed, 0: only ascii CRD allowed. 00158 * 00159 * returns: 00160 * SINT -- !=0 if the function was successful, 00161 * 0 otherwise. 00162 * Returns number of bytes required/transferred 00163 ***************************************************************************/ 00164 00165 SINT EXTERN 00166 CreateLutCRD (CHANDLE cp, SINT Index, MEMPTR lpMem, DWORD InputIntent, BOOL AllowBinary) 00167 { 00168 SINT nInputCh, nOutputCh, nGrids; 00169 SINT nInputTable, nOutputTable, nNumbers; 00170 CSIG Tag, PCS; 00171 CSIG IntentSig; 00172 00173 SINT Ret; 00174 SINT i, j; 00175 MEMPTR lpTable; 00176 00177 SFLOAT IlluminantWP[3]; 00178 SFLOAT MediaWP[3]; 00179 MEMPTR Buff = NULL; 00180 SINT MemSize = 0; 00181 MEMPTR lpOldMem = lpMem; 00182 char PublicArrayName[TempBfSize]; 00183 HGLOBAL hMem; 00184 MEMPTR lpLineStart; 00185 // Check if we can generate the CRD 00186 if (!GetCPTagSig (cp, Index, (LPCSIG) & IntentSig) || 00187 !GetCPElementType (cp, Index, (LPCSIG) & Tag) || 00188 ((Tag != icSigLut8Type) && (Tag != icSigLut16Type)) || 00189 !GetCPConnSpace (cp, (LPCSIG) & PCS) || 00190 !GetCPElementSize (cp, Index, (LPSINT) & MemSize) || 00191 !MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) & Buff) || 00192 !GetCPElement (cp, Index, Buff, MemSize)) 00193 { 00194 if (NULL != Buff) 00195 { 00196 MemFree (hMem); 00197 } 00198 return (0); 00199 } 00200 GetCLUTinfo(Tag, Buff, &nInputCh, &nOutputCh, 00201 &nGrids, &nInputTable, &nOutputTable, &i); 00202 // Level 2 printers support only tri-component CIEBasedABC input, 00203 // but can have either 3 or 4 output channels. 00204 if (((nOutputCh != 3) && 00205 (nOutputCh != 4)) || 00206 (nInputCh != 3)) 00207 { 00208 SetCPLastError (CP_POSTSCRIPT_ERR); 00209 MemFree (hMem); 00210 return (0); 00211 } 00212 Ret = nInputCh * nInputTable * 6 + 00213 nOutputCh * nOutputTable * 6 + // Number of INT bytes 00214 nOutputCh * nGrids * nGrids * nGrids * 2 + // LUT HEX bytes 00215 nInputCh * (lstrlen (IndexArray) + 00216 lstrlen (StartClip) + 00217 lstrlen (EndClip)) + 00218 nOutputCh * (lstrlen (IndexArray) + 00219 lstrlen (StartClip) + 00220 lstrlen (EndClip)) + 00221 2048; // + other PS stuff 00222 00223 if (lpMem == NULL) // This is a size request 00224 { 00225 MemFree (hMem); 00226 return (Ret); 00227 } 00228 // Get all necessary params from the header 00229 // GetCPRenderIntent (cp, (LPCSIG) & Intent); // Get Intent 00230 GetCPWhitePoint (cp, (LPSFLOAT) & IlluminantWP); // .. Illuminant 00231 00232 // Support absolute whitePoint 00233 if (InputIntent == icAbsoluteColorimetric) 00234 { 00235 if (!GetCPMediaWhitePoint (cp, (LPSFLOAT) & MediaWP)) // .. Media WhitePoint 00236 { 00237 MediaWP[0] = IlluminantWP[0]; 00238 MediaWP[1] = IlluminantWP[1]; 00239 MediaWP[2] = IlluminantWP[2]; 00240 } 00241 } 00242 00243 //******** Define golbal array used in EncodeABC and RenderTaber 00244 GetPublicArrayName (cp, IntentSig, PublicArrayName); 00245 lpMem += WriteNewLineObject (lpMem, CRDBegin); 00246 00247 lpMem += EnableGlobalDict(lpMem); 00248 lpMem += BeginGlobalDict(lpMem); 00249 00250 lpMem += CreateInputArray (lpMem, nInputCh, nInputTable, 00251 (MEMPTR) PublicArrayName, Tag, Buff, AllowBinary, NULL); 00252 00253 i = nInputTable * nInputCh + 00254 nGrids * nGrids * nGrids * nOutputCh; 00255 lpMem += CreateOutputArray (lpMem, nOutputCh, nOutputTable, i, 00256 (MEMPTR) PublicArrayName, Tag, Buff, AllowBinary, NULL); 00257 00258 lpMem += EndGlobalDict(lpMem); 00259 00260 //************* Start writing CRD **************************** 00261 lpMem += WriteNewLineObject (lpMem, BeginDict); // Begin dictionary 00262 lpMem += WriteObject (lpMem, DictType); // Dictionary type 00263 00264 //********** Send Black/White Point. 00265 lpMem += SendCRDBWPoint(lpMem, IlluminantWP); 00266 00267 //********** Send PQR - used for Absolute Colorimetric ***** 00268 lpMem += SendCRDPQR(lpMem, InputIntent, IlluminantWP); 00269 00270 //********** Send LMN - For Absolute Colorimetric use WhitePoint's XYZs 00271 lpMem += SendCRDLMN(lpMem, InputIntent, IlluminantWP, MediaWP, PCS); 00272 00273 // ******** Create MatrixABC and EncodeABC stuff 00274 lpMem += SendCRDABC(lpMem, PublicArrayName, 00275 PCS, nInputCh, Buff, NULL, Tag, AllowBinary); 00276 00277 //********** /RenderTable 00278 lpMem += WriteNewLineObject (lpMem, RenderTableTag); 00279 lpMem += WriteObject (lpMem, BeginArray); 00280 00281 lpMem += WriteInt (lpMem, nGrids); // Send down Na 00282 lpMem += WriteInt (lpMem, nGrids); // Send down Nb 00283 lpMem += WriteInt (lpMem, nGrids); // Send down Nc 00284 00285 lpLineStart = lpMem; 00286 lpMem += WriteNewLineObject (lpMem, BeginArray); 00287 nNumbers = nGrids * nGrids * nOutputCh; 00288 for (i = 0; i < nGrids; i++) // Na strings should be sent 00289 { 00290 lpMem += WriteObject (lpMem, NewLine); 00291 lpLineStart = lpMem; 00292 if (Tag == icSigLut8Type) 00293 { 00294 lpTable = (MEMPTR) (((lpcpLut8Type) Buff)->lut.data) + 00295 nInputTable * nInputCh + 00296 nNumbers * i; 00297 } else 00298 { 00299 lpTable = (MEMPTR) (((lpcpLut16Type) Buff)->lut.data) + 00300 2 * nInputTable * nInputCh + 00301 2 * nNumbers * i; 00302 } 00303 if (!AllowBinary) // Output ASCII CRD 00304 { 00305 lpMem += WriteObject (lpMem, BeginString); 00306 if (Tag == icSigLut8Type) 00307 lpMem += WriteHexBuffer (lpMem, lpTable, lpLineStart, nNumbers); 00308 else 00309 { 00310 for (j = 0; j < nNumbers; j++) 00311 { 00312 lpMem += WriteHex (lpMem, ui16toSINT (lpTable) / 256); 00313 lpTable += sizeof (icUInt16Number); 00314 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 00315 { 00316 lpLineStart = lpMem; 00317 lpMem += WriteObject (lpMem, NewLine); 00318 } 00319 } 00320 } 00321 lpMem += WriteObject (lpMem, EndString); 00322 } else 00323 { // Output BINARY CRD 00324 lpMem += WriteStringToken (lpMem, 143, nNumbers); 00325 if (Tag == icSigLut8Type) 00326 lpMem += WriteByteString (lpMem, lpTable, nNumbers); 00327 else 00328 lpMem += WriteInt2ByteString (lpMem, lpTable, nNumbers); 00329 } 00330 } 00331 00332 lpMem += WriteObject (lpMem, EndArray); // End array 00333 lpMem += WriteInt (lpMem, nOutputCh); // Send down m 00334 00335 //********** Send Output Table. 00336 lpMem += SendCRDOutputTable(lpMem, PublicArrayName, 00337 nOutputCh, Tag, FALSE, AllowBinary); 00338 00339 lpMem += WriteObject (lpMem, EndArray); // End array 00340 lpMem += WriteObject (lpMem, EndDict); // End dictionary definition 00341 00342 lpMem += WriteNewLineObject (lpMem, CRDEnd); 00343 00344 // Testing Convert binary to ascii 00345 // i = ConvertBinaryData2Ascii(lpOldMem, (SINT)(lpMem - lpOldMem), Ret); 00346 // lpMem = lpOldMem + i; 00347 // Testing Convert binary to ascii 00348 00349 MemFree (hMem); 00350 return ((SINT) ((unsigned long) (lpMem - lpOldMem))); 00351 } 00352 /*************************************************************************** 00353 * GetRevCurve 00354 * function: 00355 * prototype: 00356 * BOOL GetRevCurve( 00357 * MEMPTR Buff, 00358 * MEMPTR lpRevCurve) 00359 * parameters: 00360 * Buff -- 00361 * lpRevCurve -- 00362 * returns: 00363 * BOOL -- TRUE: successful, 00364 * FALSE: otherwise. 00365 ***************************************************************************/ 00366 00367 BOOL 00368 GetRevCurve (MEMPTR lpBuff, MEMPTR lpCurve, MEMPTR lpRevCurve) 00369 { 00370 SINT i, j, nCount; 00371 MEMPTR lpTable; 00372 PUSHORT lpInput, lpOutput; 00373 SFLOAT fTemp; 00374 SINT iBegin, iEnd, iTemp; 00375 nCount = ui32toSINT (((lpcpCurveType) lpBuff)->curve.count); 00376 lpTable = (MEMPTR) (((lpcpCurveType) lpBuff)->curve.data); 00377 lpOutput = (PUSHORT) lpRevCurve; 00378 lpInput = (PUSHORT) lpCurve; 00379 00380 for (i = 0; i < nCount; i++) 00381 { 00382 lpInput[i] = (USHORT) (ui16toSINT (lpTable)); 00383 lpTable += sizeof (icUInt16Number); 00384 } 00385 00386 j = nCount * REVCURVE_RATIO; 00387 for (i = 0; i < j; i++) 00388 { 00389 fTemp = (SFLOAT) i *65535 / (j - 1); 00390 lpOutput[i] = (fTemp < 65535) ? (USHORT) fTemp : (USHORT) 65535; 00391 } 00392 00393 for (i = 0; i < j; i++) 00394 { 00395 iBegin = 0; 00396 iEnd = nCount - 1; 00397 for (;;) 00398 { 00399 if ((iEnd - iBegin) <= 1) 00400 break; 00401 iTemp = (iEnd + iBegin) / 2; 00402 if (lpOutput[i] < lpInput[iTemp]) 00403 iEnd = iTemp; 00404 else 00405 iBegin = iTemp; 00406 } 00407 if (lpOutput[i] <= lpInput[iBegin]) 00408 fTemp = (SFLOAT) iBegin; 00409 else if (lpOutput[i] >= lpInput[iEnd]) 00410 fTemp = (SFLOAT) iEnd; 00411 else 00412 { 00413 fTemp = ((SFLOAT) (lpInput[iEnd] - lpOutput[i])) / 00414 (lpOutput[i] - lpInput[iBegin]); 00415 fTemp = (iBegin * fTemp + iEnd) / (fTemp + 1); 00416 } 00417 fTemp = (fTemp / (nCount - 1)) * 65535; 00418 lpOutput[i] = (fTemp < 65535) ? (USHORT) fTemp : (USHORT) 65535; 00419 } 00420 00421 return TRUE; 00422 } 00423 /*************************************************************************** 00424 * CreateMonoCRD 00425 * function: 00426 * this is the function which creates the Color Rendering Dictionary (CRD) 00427 * from the data supplied in the GrayTRC tag. 00428 * prototype: 00429 * BOOL EXTERN CreateMonoCRD( 00430 * CHANDLE cp, 00431 * SINT Index, 00432 * MEMPTR lpMem) 00433 * parameters: 00434 * cp -- Color Profile handle 00435 * Index -- Index of the tag 00436 * lpMem -- Pointer to the memory block 00437 * returns: 00438 * SINT -- !=0 if the function was successful, 00439 * 0 otherwise. 00440 * Returns number of bytes required/transferred 00441 ***************************************************************************/ 00442 // According to the spec this tag-based function only converts from 00443 // Device to PCS, so we need to create an inverse function to perform 00444 // PCS->device conversion. By definition the CRD is only 00445 // for XYZ->DeviceRGB/CMYK conversion. 00446 SINT EXTERN 00447 CreateMonoCRD (CHANDLE cp, SINT Index, MEMPTR lpMem, DWORD InputIntent) 00448 { 00449 SINT nCount; 00450 CSIG Tag, PCS; 00451 00452 MEMPTR Buff = NULL; 00453 SINT MemSize = 0; 00454 MEMPTR lpOldMem = lpMem; 00455 MEMPTR lpCurve, lpRevCurve; 00456 HGLOBAL hRevCurve; 00457 SINT Ret = 0; 00458 HGLOBAL hMem; 00459 SINT i; 00460 MEMPTR lpTable; 00461 SFLOAT IlluminantWP[3]; 00462 SFLOAT MediaWP[3]; 00463 MEMPTR lpLineStart; 00464 // Check if we can generate the CRD 00465 if (!GetCPElementType (cp, Index, (LPCSIG) & Tag) || 00466 (Tag != icSigCurveType) || 00467 !GetCPConnSpace (cp, (LPCSIG) & PCS) || 00468 !GetCPElementSize (cp, Index, (LPSINT) & MemSize) || 00469 !MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) & Buff) || 00470 !GetCPElement (cp, Index, Buff, MemSize)) 00471 { 00472 if (NULL != Buff) 00473 { 00474 MemFree (hMem); 00475 } 00476 return (0); 00477 } 00478 nCount = ui32toSINT (((lpcpCurveType) Buff)->curve.count); 00479 00480 // Estimate the memory size required to hold CRD 00481 // SRGB98 00482 Ret = nCount * 6 * REVCURVE_RATIO + // Number of INT elements 00483 2048; // + other PS stuff 00484 if (lpMem == NULL) // This is a size request 00485 { 00486 MemFree (hMem); 00487 return (Ret); 00488 } 00489 if (!MemAlloc (nCount * 2 * (REVCURVE_RATIO + 1), 00490 (HGLOBAL FAR *) &hRevCurve, (LPMEMPTR) & lpRevCurve)) 00491 { 00492 MemFree (hMem); 00493 return (FALSE); 00494 } 00495 lpCurve = lpRevCurve + 2 * REVCURVE_RATIO * nCount; 00496 GetRevCurve (Buff, lpCurve, lpRevCurve); 00497 00498 // GetCPCMMType (cp, (LPCSIG) & Intent); // Get Intent 00499 GetCPWhitePoint (cp, (LPSFLOAT) & IlluminantWP); // .. Illuminant 00500 00501 // Support absolute whitePoint 00502 if (InputIntent == icAbsoluteColorimetric) 00503 { 00504 if (!GetCPMediaWhitePoint (cp, (LPSFLOAT) & MediaWP)) // .. Media WhitePoint 00505 { 00506 MediaWP[0] = IlluminantWP[0]; 00507 MediaWP[1] = IlluminantWP[1]; 00508 MediaWP[2] = IlluminantWP[2]; 00509 } 00510 } 00511 00512 //************* Start writing CRD **************************** 00513 lpMem += WriteNewLineObject (lpMem, BeginDict); // Begin dictionary 00514 lpMem += WriteObject (lpMem, DictType); // Dictionary type 00515 00516 //********** Send Black/White Point. 00517 lpMem += SendCRDBWPoint(lpMem, IlluminantWP); 00518 00519 //********** /TransformPQR 00520 lpMem += SendCRDPQR(lpMem, InputIntent, IlluminantWP); 00521 00522 //********** /MatrixLMN 00523 lpMem += SendCRDLMN(lpMem, InputIntent, IlluminantWP, MediaWP, PCS); 00524 00525 //********** /MatrixABC 00526 if (PCS == icSigXYZData) 00527 { // Switch ABC to BAC, since we want to output B which is converted from Y. 00528 lpMem += WriteNewLineObject (lpMem, MatrixABCTag); 00529 lpMem += WriteObject (lpMem, MatrixABCXYZCRD); 00530 } 00531 else if (PCS == icSigLabData) 00532 { 00533 lpMem += WriteNewLineObject (lpMem, MatrixABCTag); 00534 lpMem += WriteObject (lpMem, MatrixABCLabCRD); 00535 } 00536 //********** /EncodeABC 00537 if (nCount != 0) 00538 { 00539 lpMem += WriteObject (lpMem, NewLine); 00540 lpLineStart = lpMem; 00541 lpMem += WriteObject (lpMem, EncodeABCTag); 00542 lpMem += WriteObject (lpMem, BeginArray); 00543 lpMem += WriteObject (lpMem, BeginFunction); 00544 if (nCount == 1) // Gamma supplied in ui16 format 00545 { 00546 lpTable = (MEMPTR) (((lpcpCurveType) Buff)->curve.data); 00547 lpMem += WriteInt (lpMem, ui16toSINT (lpTable)); 00548 lpMem += WriteObject (lpMem, DecodeA3Rev); 00549 } else 00550 { 00551 if (PCS == icSigLabData) 00552 { 00553 lpMem += WriteObject (lpMem, EncodeABCLab1); 00554 } 00555 lpMem += WriteObject (lpMem, StartClip); 00556 lpMem += WriteObject (lpMem, BeginArray); 00557 for (i = 0; i < nCount * REVCURVE_RATIO; i++) 00558 { 00559 lpMem += WriteInt (lpMem, (SINT) (*((PUSHORT) lpRevCurve))); 00560 lpRevCurve += sizeof (icUInt16Number); 00561 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 00562 { 00563 lpLineStart = lpMem; 00564 lpMem += WriteObject (lpMem, NewLine); 00565 } 00566 } 00567 lpMem += WriteObject (lpMem, EndArray); 00568 lpLineStart = lpMem; 00569 lpMem += WriteNewLineObject (lpMem, IndexArray); 00570 lpMem += WriteObject (lpMem, Scale16); 00571 lpMem += WriteObject (lpMem, EndClip); 00572 } 00573 lpMem += WriteObject (lpMem, EndFunction); 00574 lpMem += WriteObject (lpMem, DupOp); 00575 lpMem += WriteObject (lpMem, DupOp); 00576 lpMem += WriteObject (lpMem, EndArray); 00577 } 00578 lpMem += WriteObject (lpMem, EndDict); // End dictionary definition 00579 00580 MemFree (hRevCurve); 00581 MemFree (hMem); 00582 return ((SINT) ((unsigned long) (lpMem - lpOldMem))); 00583 } 00584 00585 // SRGB98 start 00586 BOOL 00587 GetTRCElementSize(CHANDLE cp, CSIG icSigXTRCTag, LPSINT pIndex, LPSINT pTRCSize) 00588 { 00589 CSIG Tag; 00590 00591 if (!GetCPTagIndex (cp, icSigXTRCTag, (LPSINT) pIndex) || 00592 !GetCPElementType (cp, *pIndex, (LPCSIG) & Tag) || 00593 !(Tag == icSigCurveType) || 00594 !GetCPElementSize (cp, *pIndex, (LPSINT) pTRCSize)) 00595 { 00596 return FALSE; 00597 } 00598 return TRUE; 00599 } 00600 00601 BOOL 00602 DoesTRCAndColorantTagExist (CHANDLE cp) 00603 { 00604 if (DoesCPTagExist (cp, icSigRedColorantTag) && 00605 DoesCPTagExist (cp, icSigRedTRCTag ) && 00606 DoesCPTagExist (cp, icSigGreenColorantTag) && 00607 DoesCPTagExist (cp, icSigGreenTRCTag ) && 00608 DoesCPTagExist (cp, icSigBlueColorantTag) && 00609 DoesCPTagExist (cp, icSigBlueTRCTag )) 00610 { 00611 return TRUE; 00612 } 00613 00614 return FALSE; 00615 } 00616 00617 static SINT 00618 CreateRevArray (CHANDLE cp, MEMPTR lpMem, MEMPTR lpBuff, 00619 MEMPTR lpRevCurve, CSIG CPTag, BOOL AllowBinary) 00620 { 00621 SINT i, nCount; 00622 SINT MemSize = 0; 00623 MEMPTR lpOldMem, lpLineStart; 00624 MEMPTR lpCurve; 00625 00626 lpOldMem = lpMem; 00627 00628 lpLineStart = lpMem; 00629 nCount = ui32toSINT (((lpcpCurveType) lpBuff)->curve.count); 00630 if (nCount > 1) 00631 { 00632 lpMem += WriteNewLineObject (lpMem, Slash); 00633 lpMem += WriteObject (lpMem, InputArray); 00634 lpMem += WriteInt (lpMem, (SINT) CPTag); 00635 00636 lpCurve = lpRevCurve + 2 * REVCURVE_RATIO * nCount; 00637 GetRevCurve (lpBuff, lpCurve, lpRevCurve); 00638 00639 if (!AllowBinary) // Output ASCII DATA 00640 { 00641 lpMem += WriteObject (lpMem, BeginArray); 00642 for (i = 0; i < nCount * REVCURVE_RATIO; i++) 00643 { 00644 lpMem += WriteInt (lpMem, (SINT) (*((PUSHORT) lpRevCurve))); 00645 lpRevCurve += sizeof (icUInt16Number); 00646 if (((SINT) (lpMem - lpLineStart)) > MAX_LINELENG) 00647 { 00648 lpLineStart = lpMem; 00649 lpMem += WriteObject (lpMem, NewLine); 00650 } 00651 } 00652 lpMem += WriteObject (lpMem, EndArray); 00653 } else 00654 { // Output BINARY DATA 00655 lpMem += WriteHNAToken (lpMem, 149, nCount); 00656 lpMem += WriteIntStringU2S_L (lpMem, lpRevCurve, nCount); 00657 } 00658 } 00659 lpMem += WriteObject (lpMem, DefOp); 00660 return ((SINT) (lpMem - lpOldMem)); 00661 } 00662 00663 static SINT 00664 SendRevArray (CHANDLE cp, MEMPTR lpMem, MEMPTR lpBuff, 00665 CSIG CPTag, BOOL AllowBinary) 00666 { 00667 SINT nCount; 00668 MEMPTR lpOldMem; 00669 MEMPTR lpTable; 00670 00671 lpOldMem = lpMem; 00672 lpMem += WriteObject (lpMem, BeginFunction); 00673 nCount = ui32toSINT (((lpcpCurveType) lpBuff)->curve.count); 00674 if (nCount != 0) 00675 { 00676 if (nCount == 1) // Gamma supplied in ui16 format 00677 { 00678 lpTable = (MEMPTR) (((lpcpCurveType) lpBuff)->curve.data); 00679 lpMem += WriteInt (lpMem, ui16toSINT (lpTable)); 00680 lpMem += WriteObject (lpMem, DecodeA3Rev); 00681 } else 00682 { 00683 lpMem += WriteObject (lpMem, StartClip); 00684 lpMem += WriteObject (lpMem, InputArray); 00685 lpMem += WriteInt (lpMem, (SINT) CPTag); 00686 00687 if (!AllowBinary) // Output ASCII CS 00688 { 00689 lpMem += WriteObject (lpMem, IndexArray); 00690 } else 00691 { // Output BINARY CS 00692 lpMem += WriteObject (lpMem, IndexArray16b); 00693 } 00694 lpMem += WriteObject (lpMem, Scale16); 00695 lpMem += WriteObject (lpMem, EndClip); 00696 } 00697 } 00698 lpMem += WriteObject (lpMem, EndFunction); 00699 return ((SINT) (lpMem - lpOldMem)); 00700 } 00701 00702 SINT 00703 CreateColorantArray(CHANDLE cp, double FAR *lpArray, CSIG CPTag) 00704 { 00705 SINT i, Index; 00706 MEMPTR lpTable; 00707 MEMPTR Buff = NULL; 00708 SINT MemSize = 0; 00709 HGLOBAL hBuff; 00710 00711 if (GetCPTagIndex (cp, CPTag, (LPSINT) & Index) && 00712 GetCPElementSize (cp, Index, (LPSINT) & MemSize) && 00713 MemAlloc (MemSize, (HGLOBAL FAR *)&hBuff, (LPMEMPTR) & Buff) && 00714 GetCPElement (cp, Index, Buff, MemSize)) 00715 { 00716 lpTable = (MEMPTR) & (((lpcpXYZType) Buff)->data); 00717 for (i = 0; i < 3; i++) 00718 { 00719 *lpArray++ = (SFLOAT)si16f16toSFLOAT (lpTable); 00720 lpTable += sizeof (icS15Fixed16Number); 00721 } 00722 MemFree (hBuff); 00723 } 00724 return ( TRUE ); 00725 } 00726 /*************************************************************************** 00727 * CreateMatrixCRD 00728 * function: 00729 * this is the function which creates the Color Rendering Dictionary (CRD) 00730 * from the data supplied in the redTRC, greenTRC, blueTRA, redColorant, 00731 * greenColorant and BlueColorant tags 00732 * prototype: 00733 * BOOL EXTERN CreateMatrixCRD( 00734 * CHANDLE cp, 00735 * MEMPTR lpMem, 00736 * BOOL AllowBinary) 00737 * parameters: 00738 * cp -- Color Profile handle 00739 * lpMem -- Pointer to the memory block 00740 * AllowBinary -- 00741 * returns: 00742 * SINT -- !=0 if the function was successful, 00743 * 0 otherwise. 00744 * Returns number of bytes required/transferred 00745 ***************************************************************************/ 00746 // With matrix/TRC model, only the CIEXYZ encoding of the PCS can be used. 00747 // So, we don't need to worry about CIELAB. 00748 SINT EXTERN 00749 CreateMatrixCRD (CHANDLE cp, MEMPTR lpMem, DWORD InputIntent, BOOL AllowBinary) 00750 { 00751 SINT RedTRCIndex, GreenTRCIndex, BlueTRCIndex; 00752 SINT i, MemSize; 00753 SINT nRedCount, nGreenCount, nBlueCount; 00754 MEMPTR lpRed = NULL,lpGreen, lpBlue; 00755 SINT RedTRCSize = 0, GreenTRCSize = 0, BlueTRCSize = 0; 00756 MEMPTR lpOldMem = lpMem; 00757 MEMPTR lpRevCurve; 00758 HGLOBAL hRevCurve; 00759 SINT Ret = 0; 00760 HGLOBAL hMem; 00761 SFLOAT IlluminantWP[3]; 00762 double Colorant[9]; 00763 double RevColorant[9]; 00764 00765 // Check if we can generate the CRD 00766 if (!GetTRCElementSize(cp, icSigRedTRCTag, &RedTRCIndex, &RedTRCSize) || 00767 !GetTRCElementSize(cp, icSigGreenTRCTag, &GreenTRCIndex, &GreenTRCSize) || 00768 !GetTRCElementSize(cp, icSigBlueTRCTag, &BlueTRCIndex, &BlueTRCSize)) 00769 { 00770 return 0; 00771 } 00772 MemSize = RedTRCSize + GreenTRCSize + BlueTRCSize; 00773 if (!MemAlloc (MemSize, (HGLOBAL FAR *)&hMem, (LPMEMPTR) & lpRed)) 00774 return 0; 00775 00776 lpGreen = lpRed + RedTRCSize; 00777 lpBlue = lpGreen + GreenTRCSize; 00778 if (!GetCPElement (cp, RedTRCIndex, lpRed, RedTRCSize) || 00779 !GetCPElement (cp, GreenTRCIndex, lpGreen, GreenTRCSize ) || 00780 !GetCPElement (cp, BlueTRCIndex, lpBlue, BlueTRCSize )) 00781 { 00782 MemFree (hMem); 00783 return (0); 00784 } 00785 nRedCount = ui32toSINT (((lpcpCurveType) lpRed)->curve.count); 00786 nGreenCount = ui32toSINT (((lpcpCurveType) lpGreen)->curve.count); 00787 nBlueCount = ui32toSINT (((lpcpCurveType) lpBlue)->curve.count); 00788 00789 // Estimate the memory size required to hold CRD 00790 Ret = (nRedCount + nGreenCount + nBlueCount) * 6 * REVCURVE_RATIO + 00791 2048; // Number of INT elements + other PS stuff 00792 if (lpMem == NULL) // This is a size request 00793 { 00794 MemFree (hMem); 00795 return (Ret); 00796 } 00797 00798 if (!MemAlloc (nRedCount * 2 * (REVCURVE_RATIO + 1), 00799 (HGLOBAL FAR *) &hRevCurve, (LPMEMPTR) & lpRevCurve)) 00800 { 00801 MemFree (hMem); 00802 return (0); 00803 } 00804 00805 lpMem += EnableGlobalDict(lpMem); 00806 lpMem += BeginGlobalDict(lpMem); 00807 00808 lpMem += CreateRevArray (cp, lpMem, lpRed, lpRevCurve, icSigRedTRCTag, AllowBinary); 00809 lpMem += CreateRevArray (cp, lpMem, lpGreen, lpRevCurve, icSigGreenTRCTag, AllowBinary); 00810 lpMem += CreateRevArray (cp, lpMem, lpBlue, lpRevCurve, icSigBlueTRCTag, AllowBinary); 00811 00812 lpMem += EndGlobalDict(lpMem); 00813 00814 // GetCPCMMType (cp, (LPCSIG) & Intent); // Get Intent 00815 GetCPWhitePoint (cp, (LPSFLOAT) & IlluminantWP); // .. Illuminant 00816 00817 //************* Start writing CRD **************************** 00818 lpMem += WriteNewLineObject (lpMem, CRDBegin); 00819 00820 lpMem += WriteNewLineObject (lpMem, BeginDict); // Begin dictionary 00821 lpMem += WriteObject (lpMem, DictType); // Dictionary type 00822 00823 //********** Send Black/White Point. 00824 lpMem += SendCRDBWPoint(lpMem, IlluminantWP); 00825 00826 //********** /TransformPQR 00827 lpMem += SendCRDPQR(lpMem, InputIntent, IlluminantWP); 00828 00829 //********** /MatrixLMN 00830 CreateColorantArray(cp, &Colorant[0], icSigRedColorantTag); 00831 CreateColorantArray(cp, &Colorant[3], icSigGreenColorantTag); 00832 CreateColorantArray(cp, &Colorant[6], icSigBlueColorantTag); 00833 InvertMatrix (Colorant, RevColorant); 00834 00835 lpMem += WriteNewLineObject (lpMem, MatrixLMNTag); 00836 00837 lpMem += WriteObject (lpMem, BeginArray); 00838 for (i = 0; i < 9; i++) 00839 { 00840 lpMem += WriteFloat (lpMem, (SFLOAT)RevColorant[i]); 00841 } 00842 lpMem += WriteObject (lpMem, EndArray); 00843 00844 //********** /EncodeABC 00845 lpMem += WriteNewLineObject (lpMem, EncodeABCTag); 00846 lpMem += WriteObject (lpMem, BeginArray); 00847 00848 lpMem += WriteObject (lpMem, NewLine); 00849 lpMem += SendRevArray (cp, lpMem, lpRed, icSigRedTRCTag, AllowBinary); 00850 lpMem += WriteObject (lpMem, NewLine); 00851 lpMem += SendRevArray (cp, lpMem, lpGreen, icSigGreenTRCTag, AllowBinary); 00852 lpMem += WriteObject (lpMem, NewLine); 00853 lpMem += SendRevArray (cp, lpMem, lpBlue, icSigBlueTRCTag, AllowBinary); 00854 lpMem += WriteNewLineObject (lpMem, EndArray); 00855 00856 lpMem += WriteObject (lpMem, EndDict); // End dictionary definition 00857 00858 lpMem += WriteNewLineObject (lpMem, CRDEnd); 00859 00860 MemFree (hRevCurve); 00861 MemFree (hMem); 00862 return ((SINT) ((unsigned long) (lpMem - lpOldMem))); 00863 } 00864 // SRGB98 End 00865 00866 BOOL EXTERN 00867 GetPS2ColorRenderingDictionary ( 00868 CHANDLE cp, 00869 DWORD Intent, 00870 MEMPTR lpMem, 00871 LPDWORD lpcbSize, 00872 BOOL AllowBinary) 00873 { 00874 SINT Index; 00875 SINT Ret, Size; 00876 CSIG icSigPs2CRDx, icSigBToAx; 00877 00878 if (!cp) 00879 return FALSE; 00880 00881 if ((lpMem == NULL) || (*lpcbSize == 0)) 00882 { 00883 lpMem = NULL; 00884 *lpcbSize = 0; 00885 } 00886 Ret = 0; 00887 Size = (SINT) * lpcbSize; 00888 00889 switch (Intent) 00890 { 00891 case icPerceptual: 00892 icSigPs2CRDx = icSigPs2CRD0Tag; 00893 icSigBToAx = icSigBToA0Tag; 00894 break; 00895 00896 case icRelativeColorimetric: 00897 icSigPs2CRDx = icSigPs2CRD1Tag; 00898 icSigBToAx = icSigBToA1Tag; 00899 break; 00900 00901 case icSaturation: 00902 icSigPs2CRDx = icSigPs2CRD2Tag; 00903 icSigBToAx = icSigBToA2Tag; 00904 break; 00905 00906 case icAbsoluteColorimetric: 00907 icSigPs2CRDx = icSigPs2CRD3Tag; 00908 icSigBToAx = icSigBToA1Tag; 00909 break; 00910 00911 default: 00912 *lpcbSize = (DWORD) Ret; 00913 return (Ret > 0); 00914 } 00915 00916 if ( 00917 (DoesCPTagExist (cp, icSigPs2CRDx) && 00918 GetCPTagIndex (cp, icSigPs2CRDx, (LPSINT) & Index) && 00919 GetCPElementDataSize (cp, Index, (LPSINT) & Ret) && 00920 ((Size == 0) || 00921 GetCPElementData (cp, Index, lpMem, Size)) && 00922 (Ret = Convert2Ascii (cp, Index, lpMem, Size, Ret, AllowBinary)) 00923 ) || 00924 (DoesCPTagExist (cp, icSigBToAx) && 00925 GetCPTagIndex (cp, icSigBToAx, (LPSINT) & Index) && 00926 (Ret = CreateLutCRD (cp, Index, lpMem, Intent, AllowBinary)) 00927 ) || 00928 // SRGB98 Support Windows 98 sRGB icc profile. 00929 // Create CRD from TRC and Colorant Tags. 00930 (DoesTRCAndColorantTagExist (cp) && 00931 (Ret = CreateMatrixCRD (cp, lpMem, Intent, AllowBinary)) 00932 ) || 00933 (DoesCPTagExist (cp, icSigGrayTRCTag) && 00934 GetCPTagIndex (cp, icSigGrayTRCTag, (LPSINT) & Index) && 00935 (Ret = CreateMonoCRD (cp, Index, lpMem, Intent)) 00936 ) 00937 ) 00938 { 00939 } 00940 00941 *lpcbSize = (DWORD) Ret; 00942 return (Ret > 0); 00943 }

Generated on Sat May 15 19:40:11 2004 for test by doxygen 1.3.7