include: Move InterlockedCompareExchange128 next to the other InterlockedCompareExcha...
[wine.git] / dlls / mscms / liblcms.c
blob1f43c359c4a684d26041772bafe50062cbc1099c
1 /*
2 * Unix interface for liblcms2
4 * Copyright 2020 Alexandre Julliard
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
21 #if 0
22 #pragma makedep unix
23 #endif
25 #include "config.h"
27 #ifdef HAVE_LCMS2
29 #include <stdarg.h>
30 #include <lcms2.h>
32 #include "ntstatus.h"
33 #define WIN32_NO_STATUS
34 #include "windef.h"
35 #include "winbase.h"
36 #include "winternl.h"
37 #include "wingdi.h"
38 #include "winuser.h"
39 #include "icm.h"
40 #include "mscms_priv.h"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(mscms);
45 static DWORD from_bmformat( BMFORMAT format )
47 static BOOL quietfixme = FALSE;
48 DWORD ret;
50 switch (format)
52 case BM_RGBTRIPLETS: ret = TYPE_RGB_8; break;
53 case BM_BGRTRIPLETS: ret = TYPE_BGR_8; break;
54 case BM_GRAY: ret = TYPE_GRAY_8; break;
55 case BM_xRGBQUADS: ret = TYPE_ARGB_8; break;
56 case BM_xBGRQUADS: ret = TYPE_ABGR_8; break;
57 case BM_KYMCQUADS: ret = TYPE_KYMC_8; break;
58 default:
59 if (!quietfixme)
61 FIXME( "unhandled bitmap format %08x\n", format );
62 quietfixme = TRUE;
64 ret = TYPE_RGB_8;
65 break;
67 TRACE( "color space: %08x -> %08x\n", format, ret );
68 return ret;
71 static DWORD from_type( COLORTYPE type )
73 DWORD ret;
75 switch (type)
77 case COLOR_GRAY: ret = TYPE_GRAY_16; break;
78 case COLOR_RGB: ret = TYPE_RGB_16; break;
79 case COLOR_XYZ: ret = TYPE_XYZ_16; break;
80 case COLOR_Yxy: ret = TYPE_Yxy_16; break;
81 case COLOR_Lab: ret = TYPE_Lab_16; break;
82 case COLOR_CMYK: ret = TYPE_CMYK_16; break;
83 default:
84 FIXME( "unhandled color type %08x\n", type );
85 ret = TYPE_RGB_16;
86 break;
89 TRACE( "color type: %08x -> %08x\n", type, ret );
90 return ret;
93 static void * CDECL lcms_open_profile( void *data, DWORD size )
95 return cmsOpenProfileFromMem( data, size );
98 static void CDECL lcms_close_profile( void *profile )
100 cmsCloseProfile( profile );
103 static void * CDECL lcms_create_transform( void *output, void *target, DWORD intent )
105 DWORD proofing = 0;
106 cmsHPROFILE input = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
108 if (target) proofing = cmsFLAGS_SOFTPROOFING;
109 return cmsCreateProofingTransform( input, 0, output, 0, target,
110 intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing );
113 static void * CDECL lcms_create_multi_transform( void *profiles, DWORD count, DWORD intent )
115 return cmsCreateMultiprofileTransform( profiles, count, 0, 0, intent, 0 );
118 static BOOL CDECL lcms_translate_bits( void *transform, void *srcbits, BMFORMAT input,
119 void *dstbits, BMFORMAT output, DWORD size )
121 if (!cmsChangeBuffersFormat( transform, from_bmformat(input), from_bmformat(output) )) return FALSE;
122 cmsDoTransform( transform, srcbits, dstbits, size );
123 return TRUE;
126 static BOOL CDECL lcms_translate_colors( void *transform, COLOR *in, DWORD count, COLORTYPE input_type,
127 COLOR *out, COLORTYPE output_type )
129 unsigned int i;
131 if (!cmsChangeBuffersFormat( transform, from_type(input_type), from_type(output_type) )) return FALSE;
133 switch (input_type)
135 case COLOR_RGB:
136 switch (output_type)
138 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].rgb, 1 ); return TRUE;
139 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].Lab, 1 ); return TRUE;
140 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].gray, 1 ); return TRUE;
141 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].cmyk, 1 ); return TRUE;
142 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].XYZ, 1 ); return TRUE;
143 default: break;
145 break;
146 case COLOR_Lab:
147 switch (output_type)
149 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].rgb, 1 ); return TRUE;
150 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].Lab, 1 ); return TRUE;
151 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].gray, 1 ); return TRUE;
152 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].cmyk, 1 ); return TRUE;
153 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].XYZ, 1 ); return TRUE;
154 default: break;
156 break;
157 case COLOR_GRAY:
158 switch (output_type)
160 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].rgb, 1 ); return TRUE;
161 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].Lab, 1 ); return TRUE;
162 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].gray, 1 ); return TRUE;
163 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].cmyk, 1 ); return TRUE;
164 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].XYZ, 1 ); return TRUE;
165 default: break;
167 break;
168 case COLOR_CMYK:
169 switch (output_type)
171 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].rgb, 1 ); return TRUE;
172 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].Lab, 1 ); return TRUE;
173 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].gray, 1 ); return TRUE;
174 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].cmyk, 1 ); return TRUE;
175 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].XYZ, 1 ); return TRUE;
176 default: break;
178 break;
179 case COLOR_XYZ:
180 switch (output_type)
182 case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].rgb, 1 ); return TRUE;
183 case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].Lab, 1 ); return TRUE;
184 case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].gray, 1 ); return TRUE;
185 case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].cmyk, 1 ); return TRUE;
186 case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].XYZ, 1 ); return TRUE;
187 default: break;
189 break;
190 default:
191 break;
193 FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
194 return FALSE;
197 static void CDECL lcms_close_transform( void *transform )
199 cmsDeleteTransform( transform );
202 static const struct lcms_funcs funcs =
204 lcms_open_profile,
205 lcms_close_profile,
206 lcms_create_transform,
207 lcms_create_multi_transform,
208 lcms_translate_bits,
209 lcms_translate_colors,
210 lcms_close_transform
213 static void lcms_error_handler(cmsContext ctx, cmsUInt32Number error, const char *text)
215 TRACE("%u %s\n", error, debugstr_a(text));
218 NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
220 if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
221 cmsSetLogErrorHandler( lcms_error_handler );
222 *(const struct lcms_funcs **)ptr_out = &funcs;
223 return STATUS_SUCCESS;
226 #endif /* HAVE_LCMS2 */