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

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