~ [ 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     TRACE( "bitmap format: 0x%08x\n", format );
 62 
 63     switch (format)
 64     {
 65     case BM_RGBTRIPLETS: return TYPE_RGB_8;
 66     case BM_BGRTRIPLETS: return TYPE_BGR_8;
 67     case BM_GRAY:        return TYPE_GRAY_8;
 68     default:
 69         FIXME("unhandled bitmap format\n");
 70         return TYPE_RGB_8;
 71     }
 72 }
 73 
 74 static DWORD from_type( COLORTYPE type )
 75 {
 76     TRACE( "color type: 0x%08x\n", type );
 77 
 78     switch (type)
 79     {
 80     case COLOR_GRAY:    return TYPE_GRAY_16;
 81     case COLOR_RGB:     return TYPE_RGB_16;
 82     case COLOR_XYZ:     return TYPE_XYZ_16;
 83     case COLOR_Yxy:     return TYPE_Yxy_16;
 84     case COLOR_Lab:     return TYPE_Lab_16;
 85     case COLOR_CMYK:    return TYPE_CMYK_16;
 86     default:
 87         FIXME("unhandled color type\n");
 88         return TYPE_RGB_16;
 89     }
 90 }
 91 
 92 #endif /* HAVE_LCMS */
 93 
 94 /******************************************************************************
 95  * CreateColorTransformA            [MSCMS.@]
 96  *
 97  * See CreateColorTransformW.
 98  */
 99 HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest,
100     HPROFILE target, DWORD flags )
101 {
102     LOGCOLORSPACEW spaceW;
103     DWORD len;
104 
105     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
106 
107     if (!space || !dest) return FALSE;
108 
109     memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) );
110     spaceW.lcsSize = sizeof(LOGCOLORSPACEW);
111 
112     len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 );
113     MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len );
114 
115     return CreateColorTransformW( &spaceW, dest, target, flags );
116 }
117 
118 /******************************************************************************
119  * CreateColorTransformW            [MSCMS.@]
120  *
121  * Create a color transform.
122  *
123  * PARAMS
124  *  space  [I] Input color space.
125  *  dest   [I] Color profile of destination device.
126  *  target [I] Color profile of target device.
127  *  flags  [I] Flags.
128  *
129  * RETURNS
130  *  Success: Handle to a transform.
131  *  Failure: NULL
132  */
133 HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
134     HPROFILE target, DWORD flags )
135 {
136     HTRANSFORM ret = NULL;
137 #ifdef HAVE_LCMS
138     struct transform transform;
139     struct profile *dst, *tgt = NULL;
140     cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
141     DWORD in_format, out_format, proofing = 0;
142     int intent;
143 
144     TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
145 
146     if (!space || !(dst = grab_profile( dest ))) return FALSE;
147 
148     if (target && !(tgt = grab_profile( target )))
149     {
150         release_profile( dst );
151         return FALSE;
152     }
153     intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
154 
155     TRACE( "lcsIntent:   %x\n", space->lcsIntent );
156     TRACE( "lcsCSType:   %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) );
157     TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) );
158 
159     in_format  = TYPE_RGB_16;
160     out_format = from_profile( dest );
161 
162     cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
163     if (target)
164     {
165         proofing = cmsFLAGS_SOFTPROOFING;
166         cmstarget = tgt->cmsprofile;
167     }
168     cmsoutput = dst->cmsprofile;
169     transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
170                                                         intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
171 
172     ret = create_transform( &transform );
173 
174     if (tgt) release_profile( tgt );
175     release_profile( dst );
176 
177 #endif /* HAVE_LCMS */
178     return ret;
179 }
180 
181 /******************************************************************************
182  * CreateMultiProfileTransform      [MSCMS.@]
183  *
184  * Create a color transform from an array of color profiles.
185  *
186  * PARAMS
187  *  profiles  [I] Array of color profiles.
188  *  nprofiles [I] Number of color profiles.
189  *  intents   [I] Array of rendering intents.
190  *  flags     [I] Flags.
191  *  cmm       [I] Profile to take the CMM from.
192  *
193  * RETURNS
194  *  Success: Handle to a transform.
195  *  Failure: NULL
196  */ 
197 HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles,
198     PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm )
199 {
200     HTRANSFORM ret = NULL;
201 #ifdef HAVE_LCMS
202     cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
203     struct transform transform;
204     struct profile *profile0, *profile1;
205     DWORD in_format, out_format;
206 
207     TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
208            profiles, nprofiles, intents, nintents, flags, cmm );
209 
210     if (!profiles || !nprofiles || !intents) return NULL;
211 
212     if (nprofiles > 2)
213     {
214         FIXME("more than 2 profiles not supported\n");
215         return NULL;
216     }
217 
218     profile0 = grab_profile( profiles[0] );
219     if (!profile0) return NULL;
220     profile1 = grab_profile( profiles[1] );
221     if (!profile1)
222     {
223         release_profile( profile0 );
224         return NULL;
225     }
226     in_format  = from_profile( profiles[0] );
227     out_format = from_profile( profiles[nprofiles - 1] );
228 
229     if (in_format != out_format)
230     {
231         /* insert a conversion profile for pairings that lcms doesn't handle */
232         if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile();
233         if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL );
234     }
235 
236     cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) );
237     if (cmsprofiles)
238     {
239         cmsprofiles[0] = profile0->cmsprofile;
240         if (cmsconvert)
241         {
242             cmsprofiles[1] = cmsconvert;
243             cmsprofiles[2] = profile1->cmsprofile;
244             nprofiles++;
245         }
246         else
247         {
248             cmsprofiles[1] = profile1->cmsprofile;
249         }
250         transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
251 
252         HeapFree( GetProcessHeap(), 0, cmsprofiles );
253         ret = create_transform( &transform );
254     }
255 
256     release_profile( profile0 );
257     release_profile( profile1 );
258 
259 #endif /* HAVE_LCMS */
260     return ret;
261 }
262 
263 /******************************************************************************
264  * DeleteColorTransform             [MSCMS.@]
265  *
266  * Delete a color transform.
267  *
268  * PARAMS
269  *  transform [I] Handle to a color transform.
270  *
271  * RETURNS
272  *  Success: TRUE
273  *  Failure: FALSE
274  */ 
275 BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
276 {
277     BOOL ret = FALSE;
278 #ifdef HAVE_LCMS
279 
280     TRACE( "( %p )\n", handle );
281 
282     ret = close_transform( handle );
283 
284 #endif /* HAVE_LCMS */
285     return ret;
286 }
287 
288 /******************************************************************************
289  * TranslateBitmapBits              [MSCMS.@]
290  *
291  * Perform color translation.
292  *
293  * PARAMS
294  *  transform    [I] Handle to a color transform.
295  *  srcbits      [I] Source bitmap.
296  *  input        [I] Format of the source bitmap.
297  *  width        [I] Width of the source bitmap.
298  *  height       [I] Height of the source bitmap.
299  *  inputstride  [I] Number of bytes in one scanline.
300  *  destbits     [I] Destination bitmap.
301  *  output       [I] Format of the destination bitmap.
302  *  outputstride [I] Number of bytes in one scanline. 
303  *  callback     [I] Callback function.
304  *  data         [I] Callback data. 
305  *
306  * RETURNS
307  *  Success: TRUE
308  *  Failure: FALSE
309  */
310 BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input,
311     DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
312     DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
313 {
314     BOOL ret = FALSE;
315 #ifdef HAVE_LCMS
316     struct transform *transform = grab_transform( handle );
317 
318     TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
319            handle, srcbits, input, width, height, inputstride, destbits, output,
320            outputstride, callback, data );
321 
322     if (!transform) return FALSE;
323     cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
324 
325     cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
326     release_transform( transform );
327     ret = TRUE;
328 
329 #endif /* HAVE_LCMS */
330     return ret;
331 }
332 
333 /******************************************************************************
334  * TranslateColors              [MSCMS.@]
335  *
336  * Perform color translation.
337  *
338  * PARAMS
339  *  transform    [I] Handle to a color transform.
340  *  input        [I] Array of input colors.
341  *  number       [I] Number of colors to translate.
342  *  input_type   [I] Input color format.
343  *  output       [O] Array of output colors.
344  *  output_type  [I] Output color format.
345  *
346  * RETURNS
347  *  Success: TRUE
348  *  Failure: FALSE
349  */
350 BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
351                              COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
352 {
353     BOOL ret = FALSE;
354 #ifdef HAVE_LCMS
355     struct transform *transform = grab_transform( handle );
356     cmsHTRANSFORM xfrm;
357     unsigned int i;
358 
359     TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
360 
361     if (!transform) return FALSE;
362 
363     xfrm = transform->cmstransform;
364     cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
365 
366     switch (input_type)
367     {
368     case COLOR_RGB:
369     {
370         switch (output_type)
371         {
372         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); return TRUE;
373         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); return TRUE;
374         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); return TRUE;
375         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); return TRUE;
376         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); return TRUE;
377         default:
378             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
379             return FALSE;
380         }
381     }
382     case COLOR_Lab:
383     {
384         switch (output_type)
385         {
386         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); return TRUE;
387         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); return TRUE;
388         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); return TRUE;
389         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); return TRUE;
390         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); return TRUE;
391         default:
392             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
393             return FALSE;
394         }
395     }
396     case COLOR_GRAY:
397     {
398         switch (output_type)
399         {
400         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); return TRUE;
401         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); return TRUE;
402         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); return TRUE;
403         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); return TRUE;
404         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); return TRUE;
405         default:
406             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
407             return FALSE;
408         }
409     }
410     case COLOR_CMYK:
411     {
412         switch (output_type)
413         {
414         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); return TRUE;
415         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); return TRUE;
416         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); return TRUE;
417         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); return TRUE;
418         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); return TRUE;
419         default:
420             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
421             return FALSE;
422         }
423     }
424     case COLOR_XYZ:
425     {
426         switch (output_type)
427         {
428         case COLOR_RGB:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); return TRUE;
429         case COLOR_Lab:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); return TRUE;
430         case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); return TRUE;
431         case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); return TRUE;
432         case COLOR_XYZ:  for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); return TRUE;
433         default:
434             FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
435             return FALSE;
436         }
437     }
438     default:
439         FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
440         break;
441     }
442     release_transform( transform );
443 
444 #endif /* HAVE_LCMS */
445     return ret;
446 }
447 

~ [ 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.