mscms: Move liblcms support to a new Unix library.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-11-10 12:46:37 +01:00
parent 881dad6503
commit daf9f12850
8 changed files with 286 additions and 300 deletions

View File

@ -7,6 +7,7 @@ EXTRALIBS = $(LCMS2_LIBS)
C_SRCS = \ C_SRCS = \
handle.c \ handle.c \
icc.c \ icc.c \
liblcms.c \
mscms_main.c \ mscms_main.c \
profile.c \ profile.c \
stub.c \ stub.c \

View File

@ -31,8 +31,6 @@
#include "mscms_priv.h" #include "mscms_priv.h"
#ifdef HAVE_LCMS2
static CRITICAL_SECTION mscms_handle_cs; static CRITICAL_SECTION mscms_handle_cs;
static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug = static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug =
{ {
@ -176,7 +174,7 @@ BOOL close_profile( HPROFILE handle )
} }
CloseHandle( profile->file ); CloseHandle( profile->file );
} }
cmsCloseProfile( profile->cmsprofile ); if (profile->cmsprofile) lcms_funcs->close_profile( profile->cmsprofile );
HeapFree( GetProcessHeap(), 0, profile->data ); HeapFree( GetProcessHeap(), 0, profile->data );
memset( profile, 0, sizeof(struct profile) ); memset( profile, 0, sizeof(struct profile) );
@ -242,11 +240,10 @@ BOOL close_transform( HTRANSFORM handle )
} }
transform = &transformtable[index]; transform = &transformtable[index];
cmsDeleteTransform( transform->cmstransform ); lcms_funcs->close_transform( transform->cmstransform );
memset( transform, 0, sizeof(struct transform) ); memset( transform, 0, sizeof(struct transform) );
LeaveCriticalSection( &mscms_handle_cs ); LeaveCriticalSection( &mscms_handle_cs );
return TRUE; return TRUE;
} }
#endif /* HAVE_LCMS2 */

View File

@ -31,8 +31,6 @@
#include "mscms_priv.h" #include "mscms_priv.h"
#ifdef HAVE_LCMS2
static inline void adjust_endianness32( ULONG *ptr ) static inline void adjust_endianness32( ULONG *ptr )
{ {
#ifndef WORDS_BIGENDIAN #ifndef WORDS_BIGENDIAN
@ -165,5 +163,3 @@ BOOL set_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, co
memcpy( profile->data + tag.offset + offset, buffer, *len ); memcpy( profile->data + tag.offset + offset, buffer, *len );
return TRUE; return TRUE;
} }
#endif /* HAVE_LCMS2 */

226
dlls/mscms/liblcms.c Normal file
View File

@ -0,0 +1,226 @@
/*
* Unix interface for liblcms2
*
* Copyright 2020 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#if 0
#pragma makedep unix
#endif
#include "config.h"
#ifdef HAVE_LCMS2
#include <stdarg.h>
#include <lcms2.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wingdi.h"
#include "winuser.h"
#include "icm.h"
#include "mscms_priv.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
static DWORD from_bmformat( BMFORMAT format )
{
static BOOL quietfixme = FALSE;
DWORD ret;
switch (format)
{
case BM_RGBTRIPLETS: ret = TYPE_RGB_8; break;
case BM_BGRTRIPLETS: ret = TYPE_BGR_8; break;
case BM_GRAY: ret = TYPE_GRAY_8; break;
case BM_xRGBQUADS: ret = TYPE_ARGB_8; break;
case BM_xBGRQUADS: ret = TYPE_ABGR_8; break;
case BM_KYMCQUADS: ret = TYPE_KYMC_8; break;
default:
if (!quietfixme)
{
FIXME( "unhandled bitmap format %08x\n", format );
quietfixme = TRUE;
}
ret = TYPE_RGB_8;
break;
}
TRACE( "color space: %08x -> %08x\n", format, ret );
return ret;
}
static DWORD from_type( COLORTYPE type )
{
DWORD ret;
switch (type)
{
case COLOR_GRAY: ret = TYPE_GRAY_16; break;
case COLOR_RGB: ret = TYPE_RGB_16; break;
case COLOR_XYZ: ret = TYPE_XYZ_16; break;
case COLOR_Yxy: ret = TYPE_Yxy_16; break;
case COLOR_Lab: ret = TYPE_Lab_16; break;
case COLOR_CMYK: ret = TYPE_CMYK_16; break;
default:
FIXME( "unhandled color type %08x\n", type );
ret = TYPE_RGB_16;
break;
}
TRACE( "color type: %08x -> %08x\n", type, ret );
return ret;
}
static void * CDECL lcms_open_profile( void *data, DWORD size )
{
return cmsOpenProfileFromMem( data, size );
}
static void CDECL lcms_close_profile( void *profile )
{
cmsCloseProfile( profile );
}
static void * CDECL lcms_create_transform( void *output, void *target, DWORD intent )
{
DWORD proofing = 0;
cmsHPROFILE input = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
if (target) proofing = cmsFLAGS_SOFTPROOFING;
return cmsCreateProofingTransform( input, 0, output, 0, target,
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing );
}
static void * CDECL lcms_create_multi_transform( void *profiles, DWORD count, DWORD intent )
{
return cmsCreateMultiprofileTransform( profiles, count, 0, 0, intent, 0 );
}
static BOOL CDECL lcms_translate_bits( void *transform, void *srcbits, BMFORMAT input,
void *dstbits, BMFORMAT output, DWORD size )
{
if (!cmsChangeBuffersFormat( transform, from_bmformat(input), from_bmformat(output) )) return FALSE;
cmsDoTransform( transform, srcbits, dstbits, size );
return TRUE;
}
static BOOL CDECL lcms_translate_colors( void *transform, COLOR *in, DWORD count, COLORTYPE input_type,
COLOR *out, COLORTYPE output_type )
{
unsigned int i;
if (!cmsChangeBuffersFormat( transform, from_type(input_type), from_type(output_type) )) return FALSE;
switch (input_type)
{
case COLOR_RGB:
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].rgb, 1 ); return TRUE;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].Lab, 1 ); return TRUE;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].gray, 1 ); return TRUE;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].cmyk, 1 ); return TRUE;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].rgb, &out[i].XYZ, 1 ); return TRUE;
default: break;
}
break;
case COLOR_Lab:
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].rgb, 1 ); return TRUE;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].Lab, 1 ); return TRUE;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].gray, 1 ); return TRUE;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].cmyk, 1 ); return TRUE;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].Lab, &out[i].XYZ, 1 ); return TRUE;
default: break;
}
break;
case COLOR_GRAY:
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].rgb, 1 ); return TRUE;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].Lab, 1 ); return TRUE;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].gray, 1 ); return TRUE;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].cmyk, 1 ); return TRUE;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].gray, &out[i].XYZ, 1 ); return TRUE;
default: break;
}
break;
case COLOR_CMYK:
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].rgb, 1 ); return TRUE;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].Lab, 1 ); return TRUE;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].gray, 1 ); return TRUE;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].cmyk, 1 ); return TRUE;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].cmyk, &out[i].XYZ, 1 ); return TRUE;
default: break;
}
break;
case COLOR_XYZ:
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].rgb, 1 ); return TRUE;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].Lab, 1 ); return TRUE;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].gray, 1 ); return TRUE;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].cmyk, 1 ); return TRUE;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i].XYZ, &out[i].XYZ, 1 ); return TRUE;
default: break;
}
break;
default:
break;
}
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
return FALSE;
}
static void CDECL lcms_close_transform( void *transform )
{
cmsDeleteTransform( transform );
}
static const struct lcms_funcs funcs =
{
lcms_open_profile,
lcms_close_profile,
lcms_create_transform,
lcms_create_multi_transform,
lcms_translate_bits,
lcms_translate_colors,
lcms_close_transform
};
static void lcms_error_handler(cmsContext ctx, cmsUInt32Number error, const char *text)
{
TRACE("%u %s\n", error, debugstr_a(text));
}
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
{
if (reason != DLL_PROCESS_ATTACH) return STATUS_SUCCESS;
cmsSetLogErrorHandler( lcms_error_handler );
*(const struct lcms_funcs **)ptr_out = &funcs;
return STATUS_SUCCESS;
}
#endif /* HAVE_LCMS2 */

View File

@ -29,18 +29,14 @@
#include "winbase.h" #include "winbase.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "winternl.h"
#include "icm.h" #include "icm.h"
#include "mscms_priv.h" #include "mscms_priv.h"
WINE_DEFAULT_DEBUG_CHANNEL(mscms); WINE_DEFAULT_DEBUG_CHANNEL(mscms);
#ifdef HAVE_LCMS2 const struct lcms_funcs *lcms_funcs = NULL;
static void lcms_error_handler(cmsContext ctx, cmsUInt32Number error, const char *text)
{
TRACE("%u %s\n", error, debugstr_a(text));
}
#endif
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{ {
@ -50,17 +46,12 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
{ {
case DLL_PROCESS_ATTACH: case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls( hinst ); DisableThreadLibraryCalls( hinst );
#ifdef HAVE_LCMS2 if (__wine_init_unix_lib( hinst, reason, NULL, &lcms_funcs ))
cmsSetLogErrorHandler( lcms_error_handler ); ERR( "No liblcms2 support, expect problems\n" );
#else
ERR( "Wine was built without support for liblcms2, expect problems\n" );
#endif
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
if (reserved) break; if (reserved) break;
#ifdef HAVE_LCMS2
free_handle_tables(); free_handle_tables();
#endif
break; break;
} }
return TRUE; return TRUE;

View File

@ -18,9 +18,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#ifdef HAVE_LCMS2
#include <lcms2.h>
/* A simple structure to tie together a pointer to an icc profile, an lcms /* A simple structure to tie together a pointer to an icc profile, an lcms
* color profile handle and a Windows file handle. If the profile is memory * color profile handle and a Windows file handle. If the profile is memory
* based the file handle field is set to INVALID_HANDLE_VALUE. The 'access' * based the file handle field is set to INVALID_HANDLE_VALUE. The 'access'
@ -34,12 +31,12 @@ struct profile
DWORD access; DWORD access;
char *data; char *data;
DWORD size; DWORD size;
cmsHPROFILE cmsprofile; void *cmsprofile;
}; };
struct transform struct transform
{ {
cmsHTRANSFORM cmstransform; void *cmstransform;
}; };
extern HPROFILE create_profile( struct profile * ) DECLSPEC_HIDDEN; extern HPROFILE create_profile( struct profile * ) DECLSPEC_HIDDEN;
@ -71,6 +68,19 @@ extern BOOL set_tag_data( const struct profile *, TAGTYPE, DWORD, const void *,
extern void get_profile_header( const struct profile *, PROFILEHEADER * ) DECLSPEC_HIDDEN; extern void get_profile_header( const struct profile *, PROFILEHEADER * ) DECLSPEC_HIDDEN;
extern void set_profile_header( const struct profile *, const PROFILEHEADER * ) DECLSPEC_HIDDEN; extern void set_profile_header( const struct profile *, const PROFILEHEADER * ) DECLSPEC_HIDDEN;
#endif /* HAVE_LCMS2 */ struct lcms_funcs
{
void * (CDECL *open_profile)( void *data, DWORD size );
void (CDECL *close_profile)( void *profile );
void * (CDECL *create_transform)( void *output, void *target, DWORD intent );
void * (CDECL *create_multi_transform)( void *profiles, DWORD count, DWORD intent );
BOOL (CDECL *translate_bits)( void *transform, void *srcbits, BMFORMAT input,
void *dstbits, BMFORMAT output, DWORD size );
BOOL (CDECL *translate_colors)( void *transform, COLOR *in, DWORD count, COLORTYPE input_type,
COLOR *out, COLORTYPE output_type );
void (CDECL *close_transform)( void *transform );
};
extern const struct lcms_funcs *lcms_funcs;
extern const char *dbgstr_tag(DWORD) DECLSPEC_HIDDEN; extern const char *dbgstr_tag(DWORD) DECLSPEC_HIDDEN;

View File

@ -334,8 +334,7 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
PVOID buffer, PBOOL ref ) PVOID buffer, PBOOL ref )
{ {
BOOL ret = FALSE; BOOL ret;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref ); TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
@ -349,7 +348,6 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
} }
ret = get_tag_data( profile, type, offset, buffer, size, ref ); ret = get_tag_data( profile, type, offset, buffer, size, ref );
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -373,8 +371,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
*/ */
BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type ) BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type )
{ {
BOOL ret = FALSE; BOOL ret;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
struct tag_entry tag; struct tag_entry tag;
@ -389,8 +386,6 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty
} }
if ((ret = get_tag_entry( profile, index, &tag ))) *type = tag.sig; if ((ret = get_tag_entry( profile, index, &tag ))) *type = tag.sig;
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -414,8 +409,6 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty
*/ */
BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size ) BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size )
{ {
BOOL ret = FALSE;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
PROFILEHEADER header; PROFILEHEADER header;
@ -442,10 +435,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
*size = profile->size; *size = profile->size;
release_profile( profile ); release_profile( profile );
ret = TRUE; return TRUE;
#endif /* HAVE_LCMS2 */
return ret;
} }
/****************************************************************************** /******************************************************************************
@ -466,7 +456,6 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
*/ */
BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{ {
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, %p )\n", handle, header ); TRACE( "( %p, %p )\n", handle, header );
@ -481,10 +470,6 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
get_profile_header( profile, header ); get_profile_header( profile, header );
release_profile( profile ); release_profile( profile );
return TRUE; return TRUE;
#else
return FALSE;
#endif /* HAVE_LCMS2 */
} }
/****************************************************************************** /******************************************************************************
@ -503,8 +488,6 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
*/ */
BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
{ {
BOOL ret = FALSE;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, %p )\n", handle, count ); TRACE( "( %p, %p )\n", handle, count );
@ -518,9 +501,7 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
} }
*count = get_tag_count( profile ); *count = get_tag_count( profile );
release_profile( profile ); release_profile( profile );
return TRUE;
#endif /* HAVE_LCMS2 */
return ret;
} }
/****************************************************************************** /******************************************************************************
@ -1126,8 +1107,6 @@ BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile )
*/ */
BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present ) BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present )
{ {
BOOL ret = FALSE;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
struct tag_entry tag; struct tag_entry tag;
@ -1142,10 +1121,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
} }
*present = get_adjusted_tag( profile, type, &tag ); *present = get_adjusted_tag( profile, type, &tag );
release_profile( profile ); release_profile( profile );
ret = TRUE; return TRUE;
#endif /* HAVE_LCMS2 */
return ret;
} }
/****************************************************************************** /******************************************************************************
@ -1164,8 +1140,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
*/ */
BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid ) BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
{ {
BOOL ret = FALSE; BOOL ret;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, %p )\n", handle, valid ); TRACE( "( %p, %p )\n", handle, valid );
@ -1179,8 +1154,6 @@ BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
} }
if (profile->data) ret = *valid = TRUE; if (profile->data) ret = *valid = TRUE;
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -1204,8 +1177,7 @@ BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
PVOID buffer ) PVOID buffer )
{ {
BOOL ret = FALSE; BOOL ret;
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer ); TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
@ -1219,7 +1191,6 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
} }
ret = set_tag_data( profile, type, offset, buffer, size ); ret = set_tag_data( profile, type, offset, buffer, size );
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -1238,7 +1209,6 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
*/ */
BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{ {
#ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
TRACE( "( %p, %p )\n", handle, header ); TRACE( "( %p, %p )\n", handle, header );
@ -1253,10 +1223,6 @@ BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
set_profile_header( profile, header ); set_profile_header( profile, header );
release_profile( profile ); release_profile( profile );
return TRUE; return TRUE;
#else
return FALSE;
#endif /* HAVE_LCMS2 */
} }
/****************************************************************************** /******************************************************************************
@ -1374,8 +1340,9 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing
*/ */
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation ) HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
{ {
#ifdef HAVE_LCMS2 struct profile prof;
cmsHPROFILE cmsprofile = NULL; HPROFILE hprof;
void *cmsprofile = NULL;
char *data = NULL; char *data = NULL;
HANDLE handle = INVALID_HANDLE_VALUE; HANDLE handle = INVALID_HANDLE_VALUE;
DWORD size; DWORD size;
@ -1391,7 +1358,7 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
if (!(data = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL; if (!(data = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL;
memcpy( data, profile->pProfileData, profile->cbDataSize ); memcpy( data, profile->pProfileData, profile->cbDataSize );
if (!(cmsprofile = cmsOpenProfileFromMem( data, profile->cbDataSize ))) if (lcms_funcs && !(cmsprofile = lcms_funcs->open_profile( data, profile->cbDataSize )))
{ {
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
return FALSE; return FALSE;
@ -1453,7 +1420,7 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
return NULL; return NULL;
} }
if (!(cmsprofile = cmsOpenProfileFromMem( data, size ))) if (lcms_funcs && !(cmsprofile = lcms_funcs->open_profile( data, size )))
{ {
CloseHandle( handle ); CloseHandle( handle );
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
@ -1466,24 +1433,17 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
return NULL; return NULL;
} }
if (cmsprofile) prof.file = handle;
{ prof.access = access;
struct profile profile; prof.data = data;
HPROFILE hprof; prof.size = size;
prof.cmsprofile = cmsprofile;
profile.file = handle; if ((hprof = create_profile( &prof ))) return hprof;
profile.access = access;
profile.data = data;
profile.size = size;
profile.cmsprofile = cmsprofile;
if ((hprof = create_profile( &profile ))) return hprof; if (cmsprofile) lcms_funcs->close_profile( cmsprofile );
HeapFree( GetProcessHeap(), 0, data ); HeapFree( GetProcessHeap(), 0, data );
cmsCloseProfile( cmsprofile );
}
CloseHandle( handle ); CloseHandle( handle );
#endif /* HAVE_LCMS2 */
return NULL; return NULL;
} }
@ -1501,14 +1461,8 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
*/ */
BOOL WINAPI CloseColorProfile( HPROFILE profile ) BOOL WINAPI CloseColorProfile( HPROFILE profile )
{ {
BOOL ret = FALSE;
#ifdef HAVE_LCMS2
TRACE( "( %p )\n", profile ); TRACE( "( %p )\n", profile );
ret = close_profile( profile ); return close_profile( profile );
#endif /* HAVE_LCMS2 */
return ret;
} }
/****************************************************************************** /******************************************************************************

View File

@ -34,58 +34,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(mscms); WINE_DEFAULT_DEBUG_CHANNEL(mscms);
#ifdef HAVE_LCMS2
static DWORD from_bmformat( BMFORMAT format )
{
static BOOL quietfixme = FALSE;
DWORD ret;
switch (format)
{
case BM_RGBTRIPLETS: ret = TYPE_RGB_8; break;
case BM_BGRTRIPLETS: ret = TYPE_BGR_8; break;
case BM_GRAY: ret = TYPE_GRAY_8; break;
case BM_xRGBQUADS: ret = TYPE_ARGB_8; break;
case BM_xBGRQUADS: ret = TYPE_ABGR_8; break;
case BM_KYMCQUADS: ret = TYPE_KYMC_8; break;
default:
if (!quietfixme)
{
FIXME( "unhandled bitmap format %08x\n", format );
quietfixme = TRUE;
}
ret = TYPE_RGB_8;
break;
}
TRACE( "color space: %08x -> %08x\n", format, ret );
return ret;
}
static DWORD from_type( COLORTYPE type )
{
DWORD ret;
switch (type)
{
case COLOR_GRAY: ret = TYPE_GRAY_16; break;
case COLOR_RGB: ret = TYPE_RGB_16; break;
case COLOR_XYZ: ret = TYPE_XYZ_16; break;
case COLOR_Yxy: ret = TYPE_Yxy_16; break;
case COLOR_Lab: ret = TYPE_Lab_16; break;
case COLOR_CMYK: ret = TYPE_CMYK_16; break;
default:
FIXME( "unhandled color type %08x\n", type );
ret = TYPE_RGB_16;
break;
}
TRACE( "color type: %08x -> %08x\n", type, ret );
return ret;
}
#endif /* HAVE_LCMS2 */
/****************************************************************************** /******************************************************************************
* CreateColorTransformA [MSCMS.@] * CreateColorTransformA [MSCMS.@]
* *
@ -129,15 +77,13 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
HPROFILE target, DWORD flags ) HPROFILE target, DWORD flags )
{ {
HTRANSFORM ret = NULL; HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS2
struct transform transform; struct transform transform;
struct profile *dst, *tgt = NULL; struct profile *dst, *tgt = NULL;
cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
DWORD proofing = 0;
int intent; int intent;
TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags ); TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
if (!lcms_funcs) return FALSE;
if (!space || !(dst = grab_profile( dest ))) return FALSE; if (!space || !(dst = grab_profile( dest ))) return FALSE;
if (target && !(tgt = grab_profile( target ))) if (target && !(tgt = grab_profile( target )))
@ -151,16 +97,8 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
TRACE( "lcsCSType: %s\n", dbgstr_tag( space->lcsCSType ) ); TRACE( "lcsCSType: %s\n", dbgstr_tag( space->lcsCSType ) );
TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) ); TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) );
cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */ transform.cmstransform = lcms_funcs->create_transform( dst->cmsprofile,
if (target) tgt ? tgt->cmsprofile : NULL, intent );
{
proofing = cmsFLAGS_SOFTPROOFING;
cmstarget = tgt->cmsprofile;
}
cmsoutput = dst->cmsprofile;
transform.cmstransform = cmsCreateProofingTransform(cmsinput, 0, cmsoutput, 0, cmstarget,
intent, INTENT_ABSOLUTE_COLORIMETRIC,
proofing);
if (!transform.cmstransform) if (!transform.cmstransform)
{ {
if (tgt) release_profile( tgt ); if (tgt) release_profile( tgt );
@ -172,8 +110,6 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
if (tgt) release_profile( tgt ); if (tgt) release_profile( tgt );
release_profile( dst ); release_profile( dst );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -197,14 +133,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm ) PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm )
{ {
HTRANSFORM ret = NULL; HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS2 void *cmsprofiles[2];
cmsHPROFILE *cmsprofiles;
struct transform transform; struct transform transform;
struct profile *profile0, *profile1; struct profile *profile0, *profile1;
TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n", TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
profiles, nprofiles, intents, nintents, flags, cmm ); profiles, nprofiles, intents, nintents, flags, cmm );
if (!lcms_funcs) return NULL;
if (!profiles || !nprofiles || !intents) return NULL; if (!profiles || !nprofiles || !intents) return NULL;
if (nprofiles > 2) if (nprofiles > 2)
@ -222,27 +158,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
return NULL; return NULL;
} }
if ((cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE) )))
{
cmsprofiles[0] = profile0->cmsprofile; cmsprofiles[0] = profile0->cmsprofile;
cmsprofiles[1] = profile1->cmsprofile; cmsprofiles[1] = profile1->cmsprofile;
transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, 0, transform.cmstransform = lcms_funcs->create_multi_transform( cmsprofiles, nprofiles, *intents );
0, *intents, 0 ); if (transform.cmstransform) ret = create_transform( &transform );
HeapFree( GetProcessHeap(), 0, cmsprofiles );
if (!transform.cmstransform)
{
release_profile( profile0 );
release_profile( profile1 );
return FALSE;
}
ret = create_transform( &transform );
}
release_profile( profile0 ); release_profile( profile0 );
release_profile( profile1 ); release_profile( profile1 );
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -260,15 +183,9 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
*/ */
BOOL WINAPI DeleteColorTransform( HTRANSFORM handle ) BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
{ {
BOOL ret = FALSE;
#ifdef HAVE_LCMS2
TRACE( "( %p )\n", handle ); TRACE( "( %p )\n", handle );
ret = close_transform( handle ); return close_transform( handle );
#endif /* HAVE_LCMS2 */
return ret;
} }
/****************************************************************************** /******************************************************************************
@ -297,8 +214,7 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT inpu
DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output, DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output,
DWORD outputstride, PBMCALLBACKFN callback, ULONG data ) DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
{ {
BOOL ret = FALSE; BOOL ret;
#ifdef HAVE_LCMS2
struct transform *transform = grab_transform( handle ); struct transform *transform = grab_transform( handle );
TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n", TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n",
@ -306,14 +222,9 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT inpu
outputstride, callback, data ); outputstride, callback, data );
if (!transform) return FALSE; if (!transform) return FALSE;
if (!cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) )) ret = lcms_funcs->translate_bits( transform->cmstransform, srcbits, input,
return FALSE; destbits, output, width * height );
cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
release_transform( transform ); release_transform( transform );
ret = TRUE;
#endif /* HAVE_LCMS2 */
return ret; return ret;
} }
@ -337,113 +248,13 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT inpu
BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count, BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
COLORTYPE input_type, PCOLOR out, COLORTYPE output_type ) COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
{ {
#ifdef HAVE_LCMS2 BOOL ret;
BOOL ret = TRUE;
struct transform *transform = grab_transform( handle ); struct transform *transform = grab_transform( handle );
cmsHTRANSFORM xfrm;
unsigned int i;
TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type ); TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
if (!transform) return FALSE; if (!transform) return FALSE;
ret = lcms_funcs->translate_colors( transform->cmstransform, in, count, input_type, out, output_type );
xfrm = transform->cmstransform;
if (!cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) ))
return FALSE;
switch (input_type)
{
case COLOR_RGB:
{
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); goto done;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); goto done;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); goto done;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); goto done;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); goto done;
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
break;
}
case COLOR_Lab:
{
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); goto done;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); goto done;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); goto done;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); goto done;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); goto done;
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
break;
}
case COLOR_GRAY:
{
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); goto done;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); goto done;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); goto done;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); goto done;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); goto done;
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
break;
}
case COLOR_CMYK:
{
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); goto done;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); goto done;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); goto done;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); goto done;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); goto done;
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
break;
}
case COLOR_XYZ:
{
switch (output_type)
{
case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); goto done;
case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); goto done;
case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); goto done;
case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); goto done;
case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); goto done;
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
break;
}
default:
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
ret = FALSE;
break;
}
done:
release_transform( transform ); release_transform( transform );
return ret; return ret;
#else /* HAVE_LCMS2 */
return FALSE;
#endif /* HAVE_LCMS2 */
} }