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