Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentransform.c
Go to the documentation of this file.
00001 /* 00002 * MSCMS - Color Management System for Wine 00003 * 00004 * Copyright 2005, 2006, 2008 Hans Leidekker 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 #include "wine/debug.h" 00023 00024 #include <stdarg.h> 00025 00026 #include "windef.h" 00027 #include "winbase.h" 00028 #include "winnls.h" 00029 #include "wingdi.h" 00030 #include "winuser.h" 00031 #include "icm.h" 00032 00033 #include "mscms_priv.h" 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(mscms); 00036 00037 #ifdef HAVE_LCMS 00038 00039 static DWORD from_profile( HPROFILE profile ) 00040 { 00041 PROFILEHEADER header; 00042 00043 GetColorProfileHeader( profile, &header ); 00044 TRACE( "color space: 0x%08x %s\n", header.phDataColorSpace, MSCMS_dbgstr_tag( header.phDataColorSpace ) ); 00045 00046 switch (header.phDataColorSpace) 00047 { 00048 case 0x434d594b: return TYPE_CMYK_16; /* 'CMYK' */ 00049 case 0x47524159: return TYPE_GRAY_16; /* 'GRAY' */ 00050 case 0x4c616220: return TYPE_Lab_16; /* 'Lab ' */ 00051 case 0x52474220: return TYPE_RGB_16; /* 'RGB ' */ 00052 case 0x58595a20: return TYPE_XYZ_16; /* 'XYZ ' */ 00053 default: 00054 WARN("unhandled format\n"); 00055 return TYPE_RGB_16; 00056 } 00057 } 00058 00059 static DWORD from_bmformat( BMFORMAT format ) 00060 { 00061 static int quietfixme = 0; 00062 TRACE( "bitmap format: 0x%08x\n", format ); 00063 00064 switch (format) 00065 { 00066 case BM_RGBTRIPLETS: return TYPE_RGB_8; 00067 case BM_BGRTRIPLETS: return TYPE_BGR_8; 00068 case BM_GRAY: return TYPE_GRAY_8; 00069 default: 00070 if (quietfixme == 0) 00071 { 00072 FIXME("unhandled bitmap format 0x%x\n", format); 00073 quietfixme = 1; 00074 } 00075 return TYPE_RGB_8; 00076 } 00077 } 00078 00079 static DWORD from_type( COLORTYPE type ) 00080 { 00081 TRACE( "color type: 0x%08x\n", type ); 00082 00083 switch (type) 00084 { 00085 case COLOR_GRAY: return TYPE_GRAY_16; 00086 case COLOR_RGB: return TYPE_RGB_16; 00087 case COLOR_XYZ: return TYPE_XYZ_16; 00088 case COLOR_Yxy: return TYPE_Yxy_16; 00089 case COLOR_Lab: return TYPE_Lab_16; 00090 case COLOR_CMYK: return TYPE_CMYK_16; 00091 default: 00092 FIXME("unhandled color type\n"); 00093 return TYPE_RGB_16; 00094 } 00095 } 00096 00097 #endif /* HAVE_LCMS */ 00098 00099 /****************************************************************************** 00100 * CreateColorTransformA [MSCMS.@] 00101 * 00102 * See CreateColorTransformW. 00103 */ 00104 HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, 00105 HPROFILE target, DWORD flags ) 00106 { 00107 LOGCOLORSPACEW spaceW; 00108 DWORD len; 00109 00110 TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags ); 00111 00112 if (!space || !dest) return FALSE; 00113 00114 memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) ); 00115 spaceW.lcsSize = sizeof(LOGCOLORSPACEW); 00116 00117 len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 ); 00118 MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len ); 00119 00120 return CreateColorTransformW( &spaceW, dest, target, flags ); 00121 } 00122 00123 /****************************************************************************** 00124 * CreateColorTransformW [MSCMS.@] 00125 * 00126 * Create a color transform. 00127 * 00128 * PARAMS 00129 * space [I] Input color space. 00130 * dest [I] Color profile of destination device. 00131 * target [I] Color profile of target device. 00132 * flags [I] Flags. 00133 * 00134 * RETURNS 00135 * Success: Handle to a transform. 00136 * Failure: NULL 00137 */ 00138 HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, 00139 HPROFILE target, DWORD flags ) 00140 { 00141 HTRANSFORM ret = NULL; 00142 #ifdef HAVE_LCMS 00143 struct transform transform; 00144 struct profile *dst, *tgt = NULL; 00145 cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL; 00146 DWORD in_format, out_format, proofing = 0; 00147 int intent; 00148 00149 TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags ); 00150 00151 if (!space || !(dst = grab_profile( dest ))) return FALSE; 00152 00153 if (target && !(tgt = grab_profile( target ))) 00154 { 00155 release_profile( dst ); 00156 return FALSE; 00157 } 00158 intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent; 00159 00160 TRACE( "lcsIntent: %x\n", space->lcsIntent ); 00161 TRACE( "lcsCSType: %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) ); 00162 TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) ); 00163 00164 in_format = TYPE_RGB_16; 00165 out_format = from_profile( dest ); 00166 00167 cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */ 00168 if (target) 00169 { 00170 proofing = cmsFLAGS_SOFTPROOFING; 00171 cmstarget = tgt->cmsprofile; 00172 } 00173 cmsoutput = dst->cmsprofile; 00174 transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget, 00175 intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing); 00176 00177 ret = create_transform( &transform ); 00178 00179 if (tgt) release_profile( tgt ); 00180 release_profile( dst ); 00181 00182 #endif /* HAVE_LCMS */ 00183 return ret; 00184 } 00185 00186 /****************************************************************************** 00187 * CreateMultiProfileTransform [MSCMS.@] 00188 * 00189 * Create a color transform from an array of color profiles. 00190 * 00191 * PARAMS 00192 * profiles [I] Array of color profiles. 00193 * nprofiles [I] Number of color profiles. 00194 * intents [I] Array of rendering intents. 00195 * flags [I] Flags. 00196 * cmm [I] Profile to take the CMM from. 00197 * 00198 * RETURNS 00199 * Success: Handle to a transform. 00200 * Failure: NULL 00201 */ 00202 HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles, 00203 PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm ) 00204 { 00205 HTRANSFORM ret = NULL; 00206 #ifdef HAVE_LCMS 00207 cmsHPROFILE *cmsprofiles, cmsconvert = NULL; 00208 struct transform transform; 00209 struct profile *profile0, *profile1; 00210 DWORD in_format, out_format; 00211 00212 TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n", 00213 profiles, nprofiles, intents, nintents, flags, cmm ); 00214 00215 if (!profiles || !nprofiles || !intents) return NULL; 00216 00217 if (nprofiles > 2) 00218 { 00219 FIXME("more than 2 profiles not supported\n"); 00220 return NULL; 00221 } 00222 00223 profile0 = grab_profile( profiles[0] ); 00224 if (!profile0) return NULL; 00225 profile1 = grab_profile( profiles[1] ); 00226 if (!profile1) 00227 { 00228 release_profile( profile0 ); 00229 return NULL; 00230 } 00231 in_format = from_profile( profiles[0] ); 00232 out_format = from_profile( profiles[nprofiles - 1] ); 00233 00234 if (in_format != out_format) 00235 { 00236 /* insert a conversion profile for pairings that lcms doesn't handle */ 00237 if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile(); 00238 if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL ); 00239 } 00240 00241 cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE) ); 00242 if (cmsprofiles) 00243 { 00244 cmsprofiles[0] = profile0->cmsprofile; 00245 if (cmsconvert) 00246 { 00247 cmsprofiles[1] = cmsconvert; 00248 cmsprofiles[2] = profile1->cmsprofile; 00249 nprofiles++; 00250 } 00251 else 00252 { 00253 cmsprofiles[1] = profile1->cmsprofile; 00254 } 00255 transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 ); 00256 00257 HeapFree( GetProcessHeap(), 0, cmsprofiles ); 00258 ret = create_transform( &transform ); 00259 } 00260 00261 release_profile( profile0 ); 00262 release_profile( profile1 ); 00263 00264 #endif /* HAVE_LCMS */ 00265 return ret; 00266 } 00267 00268 /****************************************************************************** 00269 * DeleteColorTransform [MSCMS.@] 00270 * 00271 * Delete a color transform. 00272 * 00273 * PARAMS 00274 * transform [I] Handle to a color transform. 00275 * 00276 * RETURNS 00277 * Success: TRUE 00278 * Failure: FALSE 00279 */ 00280 BOOL WINAPI DeleteColorTransform( HTRANSFORM handle ) 00281 { 00282 BOOL ret = FALSE; 00283 #ifdef HAVE_LCMS 00284 00285 TRACE( "( %p )\n", handle ); 00286 00287 ret = close_transform( handle ); 00288 00289 #endif /* HAVE_LCMS */ 00290 return ret; 00291 } 00292 00293 /****************************************************************************** 00294 * TranslateBitmapBits [MSCMS.@] 00295 * 00296 * Perform color translation. 00297 * 00298 * PARAMS 00299 * transform [I] Handle to a color transform. 00300 * srcbits [I] Source bitmap. 00301 * input [I] Format of the source bitmap. 00302 * width [I] Width of the source bitmap. 00303 * height [I] Height of the source bitmap. 00304 * inputstride [I] Number of bytes in one scanline. 00305 * destbits [I] Destination bitmap. 00306 * output [I] Format of the destination bitmap. 00307 * outputstride [I] Number of bytes in one scanline. 00308 * callback [I] Callback function. 00309 * data [I] Callback data. 00310 * 00311 * RETURNS 00312 * Success: TRUE 00313 * Failure: FALSE 00314 */ 00315 BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input, 00316 DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output, 00317 DWORD outputstride, PBMCALLBACKFN callback, ULONG data ) 00318 { 00319 BOOL ret = FALSE; 00320 #ifdef HAVE_LCMS 00321 struct transform *transform = grab_transform( handle ); 00322 00323 TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n", 00324 handle, srcbits, input, width, height, inputstride, destbits, output, 00325 outputstride, callback, data ); 00326 00327 if (!transform) return FALSE; 00328 cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) ); 00329 00330 cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height ); 00331 release_transform( transform ); 00332 ret = TRUE; 00333 00334 #endif /* HAVE_LCMS */ 00335 return ret; 00336 } 00337 00338 /****************************************************************************** 00339 * TranslateColors [MSCMS.@] 00340 * 00341 * Perform color translation. 00342 * 00343 * PARAMS 00344 * transform [I] Handle to a color transform. 00345 * input [I] Array of input colors. 00346 * number [I] Number of colors to translate. 00347 * input_type [I] Input color format. 00348 * output [O] Array of output colors. 00349 * output_type [I] Output color format. 00350 * 00351 * RETURNS 00352 * Success: TRUE 00353 * Failure: FALSE 00354 */ 00355 BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count, 00356 COLORTYPE input_type, PCOLOR out, COLORTYPE output_type ) 00357 { 00358 #ifdef HAVE_LCMS 00359 BOOL ret = TRUE; 00360 struct transform *transform = grab_transform( handle ); 00361 cmsHTRANSFORM xfrm; 00362 unsigned int i; 00363 00364 TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type ); 00365 00366 if (!transform) return FALSE; 00367 00368 xfrm = transform->cmstransform; 00369 cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) ); 00370 00371 switch (input_type) 00372 { 00373 case COLOR_RGB: 00374 { 00375 switch (output_type) 00376 { 00377 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); goto done; 00378 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); goto done; 00379 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); goto done; 00380 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); goto done; 00381 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); goto done; 00382 default: 00383 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00384 ret = FALSE; 00385 break; 00386 } 00387 break; 00388 } 00389 case COLOR_Lab: 00390 { 00391 switch (output_type) 00392 { 00393 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); goto done; 00394 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); goto done; 00395 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); goto done; 00396 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); goto done; 00397 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); goto done; 00398 default: 00399 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00400 ret = FALSE; 00401 break; 00402 } 00403 break; 00404 } 00405 case COLOR_GRAY: 00406 { 00407 switch (output_type) 00408 { 00409 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); goto done; 00410 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); goto done; 00411 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); goto done; 00412 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); goto done; 00413 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); goto done; 00414 default: 00415 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00416 ret = FALSE; 00417 break; 00418 } 00419 break; 00420 } 00421 case COLOR_CMYK: 00422 { 00423 switch (output_type) 00424 { 00425 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); goto done; 00426 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); goto done; 00427 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); goto done; 00428 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); goto done; 00429 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); goto done; 00430 default: 00431 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00432 ret = FALSE; 00433 break; 00434 } 00435 break; 00436 } 00437 case COLOR_XYZ: 00438 { 00439 switch (output_type) 00440 { 00441 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); goto done; 00442 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); goto done; 00443 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); goto done; 00444 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); goto done; 00445 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); goto done; 00446 default: 00447 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00448 ret = FALSE; 00449 break; 00450 } 00451 break; 00452 } 00453 default: 00454 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); 00455 ret = FALSE; 00456 break; 00457 } 00458 00459 done: 00460 release_transform( transform ); 00461 return ret; 00462 00463 #else /* HAVE_LCMS */ 00464 return FALSE; 00465 #endif /* HAVE_LCMS */ 00466 } Generated on Sat May 26 2012 04:18:28 for ReactOS by
1.7.6.1
|