~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/mscms/transform.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * MSCMS - Color Management System for Wine
  3  *
  4  * Copyright 2005, 2006, 2008 Hans Leidekker
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 #include "wine/debug.h"
 23 
 24 #include <stdarg.h>
 25 
 26 #include "windef.h"
 27 #include "winbase.h"
 28 #include "winnls.h"
 29 #include "wingdi.h"
 30 #include "winuser.h"
 31 #include "icm.h"
 32 
 33 #include "mscms_priv.h"
 34 
 35 WINE_DEFAULT_DEBUG_CHANNEL(mscms);
 36 
 37 #ifdef HAVE_LCMS
 38 
 39 static DWORD from_profile( HPROFILE profile )
 40 {
 41     PROFILEHEADER header;
 42 
 43     GetColorProfileHeader( profile, &header );
 44     TRACE( "color space: 0x%08x %s\n", header.phDataColorSpace, MSCMS_dbgstr_tag( header.phDataColorSpace ) );
 45 
 46     switch (header.phDataColorSpace)
 47     {
 48     case 0x434d594b: return TYPE_CMYK_16;  /* 'CMYK' */
 49     case 0x47524159: return TYPE_GRAY_16;  /* 'GRAY' */
 50     case 0x4c616220: return TYPE_Lab_16;   /* 'Lab ' */
 51     case 0x52474220: return TYPE_RGB_16;   /* 'RGB ' */
 52     case 0x58595a20: return TYPE_XYZ_16;   /* 'XYZ ' */
 53     default:
 54         WARN("unhandled format\n");
 55         return TYPE_RGB_16;
 56     }
 57 }
 58 
 59 static DWORD from_bmformat( BMFORMAT format )
 60 {
 61     static int quietfixme = 0;
 62     TRACE( "bitmap format: 0x%08x\n", format );
 63 
 64     switch (format)
 65     {
 66     case BM_RGBTRIPLETS: return TYPE_RGB_8;
 67     case BM_BGRTRIPLETS: return TYPE_BGR_8;
 68     case BM_GRAY:        return TYPE_GRAY_8;
 69     default:
 70         if (quietfixme == 0)
 71         {
 72             FIXME("unhandled bitmap format 0x%x\n", format);
 73             quietfixme = 1;
 74         }
 75         return TYPE_RGB_8;
 76     }
 77 }
 78 
 79 static DWORD from_type( COLORTYPE type )
 80 {
 81     TRACE( "color type: 0x%08x\n", type );
 82 
 83     switch (type)
 84     {
 85     case COLOR_GRAY:    return TYPE_GRAY_16;
 86     case COLOR_RGB:     return TYPE_RGB_16;
 87     case COLOR_XYZ:     return TYPE_XYZ_16;
 88     case COLOR_Yxy:     return TYPE_Yxy_16;
 89     case COLOR_Lab:     return TYPE_Lab_16;
 90     case COLOR_CMYK:    return TYPE_CMYK_16;
 91     default:
 92         FIXME("unhandled color type\n");
 93         return TYPE_RGB_16;
 94     }
 95 }
 96 
 97 #endif /* HAVE_LCMS */
 98 
 99 /******************************************************************************
100  * CreateColorTransformA            [MSCMS.@]
101  *
102  * See CreateColorTransformW.
103  */
104 HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest,
105     HPROFILE target, DWORD flags )
106 {
107     LOGCOLORSPACEW spaceW;
108     DWORD len;
109 
110     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
111 
112     if (!space || !dest) return FALSE;
113 
114     memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) );
115     spaceW.lcsSize = sizeof(LOGCOLORSPACEW);
116 
117     len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 );
118     MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len );
119 
120     return CreateColorTransformW( &spaceW, dest, target, flags );
121 }
122 
123 /******************************************************************************
124  * CreateColorTransformW            [MSCMS.@]
125  *
126  * Create a color transform.
127  *
128  * PARAMS
129  *  space  [I] Input color space.
130  *  dest   [I] Color profile of destination device.
131  *  target [I] Color profile of target device.
132  *  flags  [I] Flags.
133  *
134  * RETURNS
135  *  Success: Handle to a transform.
136  *  Failure: NULL
137  */
138 HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
139     HPROFILE target, DWORD flags )
140 {
141     HTRANSFORM ret = NULL;
142 #ifdef HAVE_LCMS
143     struct transform transform;
144     struct profile *dst, *tgt = NULL;
145     cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
146     DWORD in_format, out_format, proofing = 0;
147     int intent;
148 
149     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
150 
151     if (!space || !(dst = grab_profile( dest ))) return FALSE;
152 
153     if (target && !(tgt = grab_profile( target )))
154     {
155         release_profile( dst );
156         return FALSE;
157     }
158     intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
159 
160     TRACE( "lcsIntent:   %x\n", space->lcsIntent );
161     TRACE( "lcsCSType:   %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) );
162     TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) );
163 
164     in_format  = TYPE_RGB_16;
165     out_format = from_profile( dest );
166 
167     cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
168     if (target)
169     {
170         proofing = cmsFLAGS_SOFTPROOFING;
171         cmstarget = tgt->cmsprofile;
172     }
173     cmsoutput = dst->cmsprofile;
174     transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
175                                                         intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
176 
177     ret = create_transform( &transform );
178 
179     if (tgt) release_profile( tgt );
180     release_profile( dst );
181 
182 #endif /* HAVE_LCMS */
183     return ret;
184 }
185 
186 /******************************************************************************
187  * CreateMultiProfileTransform      [MSCMS.@]
188  *
189  * Create a color transform from an array of color profiles.
190  *
191  * PARAMS
192  *  profiles  [I] Array of color profiles.
193  *  nprofiles [I] Number of color profiles.
194  *  intents   [I] Array of rendering intents.
195  *  flags     [I] Flags.
196  *  cmm       [I] Profile to take the CMM from.
197  *
198  * RETURNS
199  *  Success: Handle to a transform.
200  *  Failure: NULL
201  */ 
202 HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles,
203     PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm )
204 {
205     HTRANSFORM ret = NULL;
206 #ifdef HAVE_LCMS
207     cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
208     struct transform transform;
209     struct profile *profile0, *profile1;
210     DWORD in_format, out_format;
211 
212     TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
213            profiles, nprofiles, intents, nintents, flags, cmm );
214 
215     if (!profiles || !nprofiles || !intents) return NULL;
216 
217     if (nprofiles > 2)
218     {
219         FIXME("more than 2 profiles not supported\n");
220         return NULL;
221     }
222 
223     profile0 = grab_profile( profiles[0] );
224     if (!profile0) return NULL;
225     profile1 = grab_profile( profiles[1] );
226     if (!profile1)
227     {
228         release_profile( profile0 );
229         return NULL;
230     }
231     in_format  = from_profile( profiles[0] );
232     out_format = from_profile( profiles[nprofiles - 1] );
233 
234     if (in_format != out_format)
235     {
236         /* insert a conversion profile for pairings that lcms doesn't handle */
237         if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile();
238         if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL );
239     }
240 
241     cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) );
242     if (cmsprofiles)
243     {
244         cmsprofiles[0] = profile0->cmsprofile;
245         if (cmsconvert)
246         {
247             cmsprofiles[1] = cmsconvert;
248             cmsprofiles[2] = profile1->cmsprofile;
249             nprofiles++;
250         }
251         else
252         {
253             cmsprofiles[1] = profile1->cmsprofile;
254         }
255         transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
256 
257         HeapFree( GetProcessHeap(), 0, cmsprofiles );
258         ret = create_transform( &transform );
259     }
260 
261     release_profile( profile0 );
262     release_profile( profile1 );
263 
264 #endif /* HAVE_LCMS */
265     return ret;
266 }
267 
268 /******************************************************************************
269  * DeleteColorTransform             [MSCMS.@]
270  *
271  * Delete a color transform.
272  *
273  * PARAMS
274  *  transform [I] Handle to a color transform.
275  *
276  * RETURNS
277  *  Success: TRUE
278  *  Failure: FALSE
279  */ 
280 BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
281 {
282     BOOL ret = FALSE;
283 #ifdef HAVE_LCMS
284 
285     TRACE( "( %p )\n", handle );
286 
287     ret = close_transform( handle );
288 
289 #endif /* HAVE_LCMS */
290     return ret;
291 }
292 
293 /******************************************************************************
294  * TranslateBitmapBits              [MSCMS.@]
295  *
296  * Perform color translation.
297  *
298  * PARAMS
299  *  transform    [I] Handle to a color transform.
300  *  srcbits      [I] Source bitmap.
301  *  input        [I] Format of the source bitmap.
302  *  width        [I] Width of the source bitmap.
303  *  height       [I] Height of the source bitmap.
304  *  inputstride  [I] Number of bytes in one scanline.
305  *  destbits     [I] Destination bitmap.
306  *  output       [I] Format of the destination bitmap.
307  *  outputstride [I] Number of bytes in one scanline. 
308  *  callback     [I] Callback function.
309  *  data         [I] Callback data. 
310  *
311  * RETURNS
312  *  Success: TRUE
313  *  Failure: FALSE
314  */
315 BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input,
316     DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
317     DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
318 {
319     BOOL ret = FALSE;
320 #ifdef HAVE_LCMS
321     struct transform *transform = grab_transform( handle );
322 
323     TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
324            handle, srcbits, input, width, height, inputstride, destbits, output,
325            outputstride, callback, data );
326 
327     if (!transform) return FALSE;
328     cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
329 
330     cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
331     release_transform( transform );
332     ret = TRUE;
333 
334 #endif /* HAVE_LCMS */
335     return ret;
336 }
337 
338 /******************************************************************************
339  * TranslateColors              [MSCMS.@]
340  *
341  * Perform color translation.
342  *
343  * PARAMS
344  *  transform    [I] Handle to a color transform.
345  *  input        [I] Array of input colors.
346  *  number       [I] Number of colors to translate.
347  *  input_type   [I] Input color format.
348  *  output       [O] Array of output colors.
349  *  output_type  [I] Output color format.
350  *
351  * RETURNS
352  *  Success: TRUE
353  *  Failure: FALSE
354  */
355 BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
356                              COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
357 {
358     BOOL ret = FALSE;
359 #ifdef HAVE_LCMS
360     struct transform *transform = grab_transform( handle );
361     cmsHTRANSFORM xfrm;
362     unsigned int i;
363 
364     TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
365 
366     if (!transform) return FALSE;
367 
368     xfrm = transform->cmstransform;
369     cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
370 
371     switch (input_type)
372     {
373     case COLOR_RGB:
374     {
375         switch (output_type)
376         {
377         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); return TRUE;
378         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); return TRUE;
379         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); return TRUE;
380         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); return TRUE;
381         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); return TRUE;
382         default:
383             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
384             return FALSE;
385         }
386     }
387     case COLOR_Lab:
388     {
389         switch (output_type)
390         {
391         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); return TRUE;
392         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); return TRUE;
393         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); return TRUE;
394         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); return TRUE;
395         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); return TRUE;
396         default:
397             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
398             return FALSE;
399         }
400     }
401     case COLOR_GRAY:
402     {
403         switch (output_type)
404         {
405         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); return TRUE;
406         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); return TRUE;
407         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); return TRUE;
408         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); return TRUE;
409         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); return TRUE;
410         default:
411             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
412             return FALSE;
413         }
414     }
415     case COLOR_CMYK:
416     {
417         switch (output_type)
418         {
419         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); return TRUE;
420         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); return TRUE;
421         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); return TRUE;
422         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); return TRUE;
423         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); return TRUE;
424         default:
425             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
426             return FALSE;
427         }
428     }
429     case COLOR_XYZ:
430     {
431         switch (output_type)
432         {
433         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); return TRUE;
434         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); return TRUE;
435         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); return TRUE;
436         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); return TRUE;
437         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); return TRUE;
438         default:
439             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
440             return FALSE;
441         }
442     }
443     default:
444         FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
445         break;
446     }
447     release_transform( transform );
448 
449 #endif /* HAVE_LCMS */
450     return ret;
451 }
452 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.