ReactOS 0.4.15-dev-8052-gc0e3179
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
39static 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
65static 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{
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{
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 */
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
442done:
443 release_transform( transform );
444 return ret;
445
446#else /* HAVE_LCMS2 */
447 return FALSE;
448#endif /* HAVE_LCMS2 */
449}
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define FIXME(fmt,...)
Definition: debug.h:114
#define COLOR_GRAY
Definition: ui.h:329
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define MultiByteToWideChar
Definition: compat.h:110
BOOL WINAPI DeleteColorTransform(HTRANSFORM handle)
Definition: transform.c:261
HTRANSFORM WINAPI CreateColorTransformA(LPLOGCOLORSPACEA space, HPROFILE dest, HPROFILE target, DWORD flags)
Definition: transform.c:94
BOOL WINAPI TranslateColors(HTRANSFORM handle, PCOLOR in, DWORD count, COLORTYPE input_type, PCOLOR out, COLORTYPE output_type)
Definition: transform.c:337
HTRANSFORM WINAPI CreateMultiProfileTransform(PHPROFILE profiles, DWORD nprofiles, PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm)
Definition: transform.c:196
HTRANSFORM WINAPI CreateColorTransformW(LPLOGCOLORSPACEW space, HPROFILE dest, HPROFILE target, DWORD flags)
Definition: transform.c:128
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
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint GLenum GLenum transform
Definition: glext.h:9407
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLenum GLsizei len
Definition: glext.h:6722
GLenum GLenum GLenum input
Definition: glext.h:9031
GLenum target
Definition: glext.h:7315
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
COLORTYPE
Definition: icm.h:123
@ COLOR_XYZ
Definition: icm.h:126
@ COLOR_CMYK
Definition: icm.h:130
@ COLOR_Yxy
Definition: icm.h:127
@ COLOR_Lab
Definition: icm.h:128
@ COLOR_RGB
Definition: icm.h:125
#define INTENT_ABSOLUTE_COLORIMETRIC
Definition: icm.h:191
BOOL(CALLBACK * PBMCALLBACKFN)(ULONG, ULONG, LPARAM)
Definition: icm.h:185
BMFORMAT
Definition: icm.h:139
@ BM_RGBTRIPLETS
Definition: icm.h:142
@ BM_BGRTRIPLETS
Definition: icm.h:143
@ BM_xBGRQUADS
Definition: icm.h:147
@ BM_xRGBQUADS
Definition: icm.h:144
@ BM_KYMCQUADS
Definition: icm.h:166
@ BM_GRAY
Definition: icm.h:161
#define INTENT_PERCEPTUAL
Definition: icm.h:188
#define profile
Definition: kernel32.h:12
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static IPrintDialogCallback callback
Definition: printdlg.c:326
static const char profile1[]
Definition: profile.c:116
static char * dest
Definition: rtl.c:135
const char * dbgstr_tag(DWORD) DECLSPEC_HIDDEN
Definition: profile.c:58
static const WCHAR spaceW[]
Definition: mxwriter.c:44
DWORD * PDWORD
Definition: pedump.c:68
static FILE * out
Definition: regtests2xml.c:44
#define TRACE(s)
Definition: solgame.cpp:4
output_type
Definition: stylesheet.c:56
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint32_t ULONG
Definition: typedefs.h:59
Definition: icm.h:105
int ret
_In_ ULONG _In_ ULONG rgb
Definition: winddi.h:3521
#define WINAPI
Definition: msvc.h:6
struct tagLOGCOLORSPACEW LOGCOLORSPACEW