2 * MSCMS - Color Management System for Wine
4 * Copyright 2005, 2006, 2008 Hans Leidekker
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.
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.
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
30 #include "wine/debug.h"
32 #include "mscms_priv.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(mscms
);
36 static DWORD
from_bmformat( BMFORMAT format
)
38 static BOOL quietfixme
= FALSE
;
43 case BM_RGBTRIPLETS
: ret
= TYPE_BGR_8
; break;
44 case BM_BGRTRIPLETS
: ret
= TYPE_RGB_8
; break;
45 case BM_GRAY
: ret
= TYPE_GRAY_8
; break;
46 case BM_xRGBQUADS
: ret
= TYPE_BGRA_8
; break;
47 case BM_xBGRQUADS
: ret
= TYPE_RGBA_8
; break;
48 case BM_KYMCQUADS
: ret
= TYPE_CMYK_8
; break;
52 FIXME( "unhandled bitmap format %#x\n", format
);
58 TRACE( "color space: %#x -> %#lx\n", format
, ret
);
62 static DWORD
from_type( COLORTYPE type
)
68 case COLOR_GRAY
: ret
= TYPE_GRAY_16
; break;
69 case COLOR_RGB
: ret
= TYPE_RGB_16
; break;
70 case COLOR_XYZ
: ret
= TYPE_XYZ_16
; break;
71 case COLOR_Yxy
: ret
= TYPE_Yxy_16
; break;
72 case COLOR_Lab
: ret
= TYPE_Lab_16
; break;
73 case COLOR_CMYK
: ret
= TYPE_CMYK_16
; break;
75 FIXME( "unhandled color type %08x\n", type
);
80 TRACE( "color type: %#x -> %#lx\n", type
, ret
);
84 /******************************************************************************
85 * CreateColorTransformA [MSCMS.@]
87 * See CreateColorTransformW.
89 HTRANSFORM WINAPI
CreateColorTransformA( LPLOGCOLORSPACEA space
, HPROFILE dest
, HPROFILE target
, DWORD flags
)
91 LOGCOLORSPACEW spaceW
;
94 TRACE( "( %p, %p, %p, %#lx )\n", space
, dest
, target
, flags
);
96 if (!space
|| !dest
) return FALSE
;
98 memcpy( &spaceW
, space
, FIELD_OFFSET(LOGCOLORSPACEA
, lcsFilename
) );
99 spaceW
.lcsSize
= sizeof(LOGCOLORSPACEW
);
101 len
= MultiByteToWideChar( CP_ACP
, 0, space
->lcsFilename
, -1, NULL
, 0 );
102 MultiByteToWideChar( CP_ACP
, 0, space
->lcsFilename
, -1, spaceW
.lcsFilename
, len
);
104 return CreateColorTransformW( &spaceW
, dest
, target
, flags
);
107 static void close_transform( struct object
*obj
)
109 struct transform
*transform
= (struct transform
*)obj
;
110 if (transform
->cmstransform
) cmsDeleteTransform( transform
->cmstransform
);
113 /******************************************************************************
114 * CreateColorTransformW [MSCMS.@]
116 * Create a color transform.
119 * space [I] Input color space.
120 * dest [I] Color profile of destination device.
121 * target [I] Color profile of target device.
125 * Success: Handle to a transform.
128 HTRANSFORM WINAPI
CreateColorTransformW( LPLOGCOLORSPACEW space
, HPROFILE dest
, HPROFILE target
, DWORD flags
)
130 HTRANSFORM ret
= NULL
;
131 struct transform
*transform
;
132 cmsHTRANSFORM cmstransform
;
133 struct profile
*dst
, *tgt
= NULL
;
138 TRACE( "( %p, %p, %p, %#lx )\n", space
, dest
, target
, flags
);
140 if (!space
|| !(dst
= (struct profile
*)grab_object( dest
, OBJECT_TYPE_PROFILE
))) return FALSE
;
141 if (target
&& !(tgt
= (struct profile
*)grab_object( target
, OBJECT_TYPE_PROFILE
)))
143 release_object( &dst
->hdr
);
146 intent
= space
->lcsIntent
> 3 ? INTENT_PERCEPTUAL
: space
->lcsIntent
;
148 TRACE( "lcsIntent: %#lx\n", space
->lcsIntent
);
149 TRACE( "lcsCSType: %s\n", debugstr_fourcc( space
->lcsCSType
) );
150 TRACE( "lcsFilename: %s\n", debugstr_w( space
->lcsFilename
) );
152 input
= cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
153 if (target
) proofing
= cmsFLAGS_SOFTPROOFING
;
154 cmstransform
= cmsCreateProofingTransform( input
, 0, dst
->cmsprofile
, 0, tgt
? tgt
->cmsprofile
: NULL
,
155 intent
, INTENT_ABSOLUTE_COLORIMETRIC
, proofing
);
158 if (tgt
) release_object( &tgt
->hdr
);
159 release_object( &dst
->hdr
);
163 if ((transform
= calloc( 1, sizeof(*transform
) )))
165 transform
->hdr
.type
= OBJECT_TYPE_TRANSFORM
;
166 transform
->hdr
.close
= close_transform
;
167 transform
->cmstransform
= cmstransform
;
168 if (!(ret
= alloc_handle( &transform
->hdr
))) free( transform
);
171 if (tgt
) release_object( &tgt
->hdr
);
172 release_object( &dst
->hdr
);
176 /******************************************************************************
177 * CreateMultiProfileTransform [MSCMS.@]
179 * Create a color transform from an array of color profiles.
182 * profiles [I] Array of color profiles.
183 * nprofiles [I] Number of color profiles.
184 * intents [I] Array of rendering intents.
186 * cmm [I] Profile to take the CMM from.
189 * Success: Handle to a transform.
192 HTRANSFORM WINAPI
CreateMultiProfileTransform( PHPROFILE profiles
, DWORD nprofiles
,
193 PDWORD intents
, DWORD nintents
, DWORD flags
, DWORD cmm
)
195 HTRANSFORM ret
= NULL
;
196 cmsHPROFILE cmsprofiles
[2];
197 cmsHTRANSFORM cmstransform
;
198 struct transform
*transform
;
199 struct profile
*profile0
, *profile1
;
201 TRACE( "( %p, %#lx, %p, %lu, %#lx, %#lx )\n", profiles
, nprofiles
, intents
, nintents
, flags
, cmm
);
203 if (!profiles
|| !nprofiles
|| !intents
) return NULL
;
207 FIXME("more than 2 profiles not supported\n");
211 profile0
= (struct profile
*)grab_object( profiles
[0], OBJECT_TYPE_PROFILE
);
212 if (!profile0
) return NULL
;
213 profile1
= (struct profile
*)grab_object( profiles
[1], OBJECT_TYPE_PROFILE
);
216 release_object( &profile0
->hdr
);
220 cmsprofiles
[0] = profile0
->cmsprofile
;
221 cmsprofiles
[1] = profile1
->cmsprofile
;
222 if (!(cmstransform
= cmsCreateMultiprofileTransform( cmsprofiles
, nprofiles
, 0, 0, *intents
, 0 )))
224 release_object( &profile0
->hdr
);
225 release_object( &profile1
->hdr
);
229 if ((transform
= calloc( 1, sizeof(*transform
) )))
231 transform
->hdr
.type
= OBJECT_TYPE_TRANSFORM
;
232 transform
->hdr
.close
= close_transform
;
233 transform
->cmstransform
= cmstransform
;
234 if (!(ret
= alloc_handle( &transform
->hdr
))) free( transform
);
237 release_object( &profile0
->hdr
);
238 release_object( &profile1
->hdr
);
242 /******************************************************************************
243 * DeleteColorTransform [MSCMS.@]
245 * Delete a color transform.
248 * transform [I] Handle to a color transform.
254 BOOL WINAPI
DeleteColorTransform( HTRANSFORM handle
)
256 struct transform
*transform
= (struct transform
*)grab_object( handle
, OBJECT_TYPE_TRANSFORM
);
258 TRACE( "( %p )\n", handle
);
260 if (!transform
) return FALSE
;
261 free_handle( handle
);
262 release_object( &transform
->hdr
);
266 /******************************************************************************
267 * TranslateBitmapBits [MSCMS.@]
269 * Perform color translation.
272 * transform [I] Handle to a color transform.
273 * srcbits [I] Source bitmap.
274 * input [I] Format of the source bitmap.
275 * width [I] Width of the source bitmap.
276 * height [I] Height of the source bitmap.
277 * inputstride [I] Number of bytes in one scanline.
278 * destbits [I] Destination bitmap.
279 * output [I] Format of the destination bitmap.
280 * outputstride [I] Number of bytes in one scanline.
281 * callback [I] Callback function.
282 * data [I] Callback data.
288 BOOL WINAPI
TranslateBitmapBits( HTRANSFORM handle
, PVOID srcbits
, BMFORMAT input
,
289 DWORD width
, DWORD height
, DWORD inputstride
, PVOID destbits
, BMFORMAT output
,
290 DWORD outputstride
, PBMCALLBACKFN callback
, ULONG data
)
293 struct transform
*transform
= (struct transform
*)grab_object( handle
, OBJECT_TYPE_TRANSFORM
);
295 TRACE( "( %p, %p, %#x, %lu, %lu, %lu, %p, %#x, %lu, %p, %#lx )\n",
296 handle
, srcbits
, input
, width
, height
, inputstride
, destbits
, output
,
297 outputstride
, callback
, data
);
299 if (!transform
) return FALSE
;
300 ret
= cmsChangeBuffersFormat( transform
->cmstransform
, from_bmformat(input
), from_bmformat(output
) );
301 if (ret
) cmsDoTransform( transform
->cmstransform
, srcbits
, destbits
, width
* height
);
302 release_object( &transform
->hdr
);
306 /******************************************************************************
307 * TranslateColors [MSCMS.@]
309 * Perform color translation.
312 * transform [I] Handle to a color transform.
313 * input [I] Array of input colors.
314 * number [I] Number of colors to translate.
315 * input_type [I] Input color format.
316 * output [O] Array of output colors.
317 * output_type [I] Output color format.
323 BOOL WINAPI
TranslateColors( HTRANSFORM handle
, PCOLOR in
, DWORD count
,
324 COLORTYPE input_type
, PCOLOR out
, COLORTYPE output_type
)
328 struct transform
*transform
= (struct transform
*)grab_object( handle
, OBJECT_TYPE_TRANSFORM
);
330 TRACE( "( %p, %p, %lu, %d, %p, %d )\n", handle
, in
, count
, input_type
, out
, output_type
);
332 if (!transform
) return FALSE
;
334 ret
= cmsChangeBuffersFormat( transform
->cmstransform
, from_type(input_type
), from_type(output_type
) );
336 for (i
= 0; i
< count
; i
++) cmsDoTransform( transform
->cmstransform
, &in
[i
], &out
[i
], 1 );
338 release_object( &transform
->hdr
);