/*
* MSCMS - Color Management System for Wine
*
- * Copyright 2004, 2005 Hans Leidekker
+ * Copyright 2004, 2005, 2008 Hans Leidekker
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
*/
#include "config.h"
+#include "wine/debug.h"
+
#include <stdarg.h>
#include "windef.h"
};
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };
-/* A simple structure to tie together a pointer to an icc profile, an lcms
- * color profile handle and a Windows file handle. Windows color profile
- * handles are built from indexes into an array of these structures. If
- * the profile is memory based the file handle field is set to
- * INVALID_HANDLE_VALUE. The 'access' field records the access parameter
- * supplied to an OpenColorProfile() call, i.e. PROFILE_READ or PROFILE_READWRITE.
- */
+static struct profile *profiletable;
+static struct transform *transformtable;
-struct profile
-{
- HANDLE file;
- DWORD access;
- icProfile *iccprofile;
- cmsHPROFILE cmsprofile;
-};
+static unsigned int num_profile_handles;
+static unsigned int num_transform_handles;
-struct transform
-{
- cmsHTRANSFORM cmstransform;
-};
+WINE_DEFAULT_DEBUG_CHANNEL(mscms);
-#define CMSMAXHANDLES 0x80
-
-static struct profile profiletable[CMSMAXHANDLES];
-static struct transform transformtable[CMSMAXHANDLES];
-
-HPROFILE MSCMS_handle2hprofile( HANDLE file )
+void free_handle_tables( void )
{
- HPROFILE profile = NULL;
- DWORD_PTR i;
-
- if (!file) return NULL;
-
- EnterCriticalSection( &MSCMS_handle_cs );
+ HeapFree( GetProcessHeap(), 0, profiletable );
+ profiletable = NULL;
+ num_profile_handles = 0;
- for (i = 0; i <= CMSMAXHANDLES; i++)
- {
- if (profiletable[i].file == file)
- {
- profile = (HPROFILE)(i + 1); goto out;
- }
- }
-
-out:
- LeaveCriticalSection( &MSCMS_handle_cs );
- return profile;
+ HeapFree( GetProcessHeap(), 0, transformtable );
+ transformtable = NULL;
+ num_transform_handles = 0;
}
-HANDLE MSCMS_hprofile2handle( HPROFILE profile )
+struct profile *grab_profile( HPROFILE handle )
{
- HANDLE file;
- DWORD_PTR i;
+ DWORD_PTR index;
EnterCriticalSection( &MSCMS_handle_cs );
- i = (DWORD_PTR)profile - 1;
- file = profiletable[i].file;
-
- LeaveCriticalSection( &MSCMS_handle_cs );
- return file;
+ index = (DWORD_PTR)handle - 1;
+ if (index > num_profile_handles)
+ {
+ LeaveCriticalSection( &MSCMS_handle_cs );
+ return NULL;
+ }
+ return &profiletable[index];
}
-DWORD MSCMS_hprofile2access( HPROFILE profile )
+void release_profile( struct profile *profile )
{
- DWORD access;
- DWORD_PTR i;
-
- EnterCriticalSection( &MSCMS_handle_cs );
-
- i = (DWORD_PTR)profile - 1;
- access = profiletable[i].access;
-
LeaveCriticalSection( &MSCMS_handle_cs );
- return access;
}
-HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
+struct transform *grab_transform( HTRANSFORM handle )
{
- HPROFILE profile = NULL;
- DWORD_PTR i;
-
- if (!cmsprofile) return NULL;
+ DWORD_PTR index;
EnterCriticalSection( &MSCMS_handle_cs );
- for (i = 0; i <= CMSMAXHANDLES; i++)
+ index = (DWORD_PTR)handle - 1;
+ if (index > num_transform_handles)
{
- if (profiletable[i].cmsprofile == cmsprofile)
- {
- profile = (HPROFILE)(i + 1); goto out;
- }
+ LeaveCriticalSection( &MSCMS_handle_cs );
+ return NULL;
}
-
-out:
- LeaveCriticalSection( &MSCMS_handle_cs );
- return profile;
+ return &transformtable[index];
}
-cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile )
+void release_transform( struct transform *transform )
{
- cmsHPROFILE cmsprofile;
- DWORD_PTR i;
-
- EnterCriticalSection( &MSCMS_handle_cs );
-
- i = (DWORD_PTR)profile - 1;
- cmsprofile = profiletable[i].cmsprofile;
-
LeaveCriticalSection( &MSCMS_handle_cs );
- return cmsprofile;
}
-HPROFILE MSCMS_iccprofile2hprofile( const icProfile *iccprofile )
+static HPROFILE alloc_profile_handle( void )
{
- HPROFILE profile = NULL;
- DWORD_PTR i;
+ DWORD_PTR index;
+ struct profile *p;
+ unsigned int count = 128;
- if (!iccprofile) return NULL;
-
- EnterCriticalSection( &MSCMS_handle_cs );
-
- for (i = 0; i <= CMSMAXHANDLES; i++)
+ for (index = 0; index < num_profile_handles; index++)
{
- if (profiletable[i].iccprofile == iccprofile)
- {
- profile = (HPROFILE)(i + 1); goto out;
- }
+ if (!profiletable[index].iccprofile) return (HPROFILE)(index + 1);
}
+ if (!profiletable)
+ {
+ p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct profile) );
+ }
+ else
+ {
+ count = num_profile_handles * 2;
+ p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, profiletable, count * sizeof(struct profile) );
+ }
+ if (!p) return NULL;
-out:
- LeaveCriticalSection( &MSCMS_handle_cs );
- return profile;
+ profiletable = p;
+ num_profile_handles = count;
+
+ return (HPROFILE)(index + 1);
}
-icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile )
+HPROFILE create_profile( struct profile *profile )
{
- icProfile *iccprofile;
- DWORD_PTR i;
+ HPROFILE handle;
EnterCriticalSection( &MSCMS_handle_cs );
- i = (DWORD_PTR)profile - 1;
- iccprofile = profiletable[i].iccprofile;
-
+ if ((handle = alloc_profile_handle()))
+ {
+ DWORD_PTR index = (DWORD_PTR)handle - 1;
+ memcpy( &profiletable[index], profile, sizeof(struct profile) );
+ }
LeaveCriticalSection( &MSCMS_handle_cs );
- return iccprofile;
+ return handle;
}
-HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile,
- cmsHPROFILE cmsprofile, DWORD access )
+BOOL close_profile( HPROFILE handle )
{
- HPROFILE profile = NULL;
- DWORD_PTR i;
-
- if (!cmsprofile || !iccprofile) return NULL;
+ DWORD_PTR index;
+ struct profile *profile;
EnterCriticalSection( &MSCMS_handle_cs );
- for (i = 0; i <= CMSMAXHANDLES; i++)
+ index = (DWORD_PTR)handle - 1;
+ if (index > num_profile_handles)
{
- if (profiletable[i].iccprofile == 0)
- {
- profiletable[i].file = file;
- profiletable[i].access = access;
- profiletable[i].iccprofile = iccprofile;
- profiletable[i].cmsprofile = cmsprofile;
+ LeaveCriticalSection( &MSCMS_handle_cs );
+ return FALSE;
+ }
+ profile = &profiletable[index];
- profile = (HPROFILE)(i + 1); goto out;
+ if (profile->file != INVALID_HANDLE_VALUE)
+ {
+ if (profile->access & PROFILE_READWRITE)
+ {
+ DWORD written, size = MSCMS_get_profile_size( profile->iccprofile );
+
+ if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) ||
+ !WriteFile( profile->file, profile->iccprofile, size, &written, NULL ) ||
+ written != size)
+ {
+ ERR( "Unable to write color profile\n" );
+ }
}
+ CloseHandle( profile->file );
}
+ cmsCloseProfile( profile->cmsprofile );
+ HeapFree( GetProcessHeap(), 0, profile->iccprofile );
+
+ memset( profile, 0, sizeof(struct profile) );
-out:
LeaveCriticalSection( &MSCMS_handle_cs );
- return profile;
+ return TRUE;
}
-void MSCMS_destroy_hprofile_handle( HPROFILE profile )
+static HTRANSFORM alloc_transform_handle( void )
{
- DWORD_PTR i;
+ DWORD_PTR index;
+ struct transform *p;
+ unsigned int count = 128;
- if (profile)
+ for (index = 0; index < num_transform_handles; index++)
{
- EnterCriticalSection( &MSCMS_handle_cs );
-
- i = (DWORD_PTR)profile - 1;
- memset( &profiletable[i], 0, sizeof(struct profile) );
-
- LeaveCriticalSection( &MSCMS_handle_cs );
+ if (!transformtable[index].cmstransform) return (HTRANSFORM)(index + 1);
}
-}
-
-cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform )
-{
- cmsHTRANSFORM cmstransform;
- DWORD_PTR i;
-
- EnterCriticalSection( &MSCMS_handle_cs );
+ if (!transformtable)
+ {
+ p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct transform) );
+ }
+ else
+ {
+ count = num_transform_handles * 2;
+ p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, transformtable, count * sizeof(struct transform) );
+ }
+ if (!p) return NULL;
- i = (DWORD_PTR)transform - 1;
- cmstransform = transformtable[i].cmstransform;
+ transformtable = p;
+ num_transform_handles = count;
- LeaveCriticalSection( &MSCMS_handle_cs );
- return cmstransform;
+ return (HTRANSFORM)(index + 1);
}
-HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform )
+HTRANSFORM create_transform( struct transform *transform )
{
- HTRANSFORM transform = NULL;
- DWORD_PTR i;
-
- if (!cmstransform) return NULL;
+ HTRANSFORM handle;
EnterCriticalSection( &MSCMS_handle_cs );
- for (i = 0; i <= CMSMAXHANDLES; i++)
+ if ((handle = alloc_transform_handle()))
{
- if (transformtable[i].cmstransform == 0)
- {
- transformtable[i].cmstransform = cmstransform;
- transform = (HTRANSFORM)(i + 1); goto out;
- }
+ DWORD_PTR index = (DWORD_PTR)handle - 1;
+ memcpy( &transformtable[index], transform, sizeof(struct transform) );
}
-
-out:
LeaveCriticalSection( &MSCMS_handle_cs );
- return transform;
+ return handle;
}
-void MSCMS_destroy_htransform_handle( HTRANSFORM transform )
+BOOL close_transform( HTRANSFORM handle )
{
- DWORD_PTR i;
-
- if (transform)
- {
- EnterCriticalSection( &MSCMS_handle_cs );
+ DWORD_PTR index;
+ struct transform *transform;
- i = (DWORD_PTR)transform - 1;
- memset( &transformtable[i], 0, sizeof(struct transform) );
+ EnterCriticalSection( &MSCMS_handle_cs );
+ index = (DWORD_PTR)handle - 1;
+ if (index > num_transform_handles)
+ {
LeaveCriticalSection( &MSCMS_handle_cs );
+ return FALSE;
}
+ transform = &transformtable[index];
+
+ cmsDeleteTransform( transform->cmstransform );
+ memset( transform, 0, sizeof(struct transform) );
+
+ LeaveCriticalSection( &MSCMS_handle_cs );
+ return TRUE;
}
#endif /* HAVE_LCMS */
#include "winuser.h"
#include "icm.h"
+#include "mscms_priv.h"
+
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
DisableThreadLibraryCalls( hinst );
break;
case DLL_PROCESS_DETACH:
+ free_handle_tables();
break;
}
return TRUE;
#define DWORD DWORD
#define LPDWORD LPDWORD
-extern DWORD MSCMS_hprofile2access( HPROFILE );
-extern HPROFILE MSCMS_handle2hprofile( HANDLE file );
-extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile );
-extern HPROFILE MSCMS_iccprofile2hprofile( const icProfile *iccprofile );
-extern HANDLE MSCMS_hprofile2handle( HPROFILE profile );
-extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
-extern icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile );
-
-extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile,
- cmsHPROFILE cmsprofile, DWORD access );
-extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
-
-extern cmsHTRANSFORM MSCMS_htransform2cmstransform( HTRANSFORM transform );
-extern HTRANSFORM MSCMS_create_htransform_handle( cmsHTRANSFORM cmstransform );
-extern void MSCMS_destroy_htransform_handle( HTRANSFORM transform );
+/* 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
+ * based the file handle field is set to INVALID_HANDLE_VALUE. The 'access'
+ * field records the access parameter supplied to an OpenColorProfile()
+ * call, i.e. PROFILE_READ or PROFILE_READWRITE.
+ */
+
+struct profile
+{
+ HANDLE file;
+ DWORD access;
+ icProfile *iccprofile;
+ cmsHPROFILE cmsprofile;
+};
+
+struct transform
+{
+ cmsHTRANSFORM cmstransform;
+};
+
+extern HPROFILE create_profile( struct profile * );
+extern BOOL close_profile( HPROFILE );
+
+extern HTRANSFORM create_transform( struct transform * );
+extern BOOL close_transform( HTRANSFORM );
+
+struct profile *grab_profile( HPROFILE );
+struct transform *grab_transform( HTRANSFORM );
+
+void release_profile( struct profile * );
+void release_transform( struct transform * );
+
+extern void free_handle_tables( void );
extern DWORD MSCMS_get_tag_count( const icProfile *iccprofile );
extern void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag );
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
+BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
PVOID buffer, PBOOL ref )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
DWORD i, count;
icTag tag;
- TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", profile, type, offset, size, buffer, ref );
+ TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
- if (!iccprofile || !size || !ref) return FALSE;
- count = MSCMS_get_tag_count( iccprofile );
+ if (!profile) return FALSE;
+
+ if (!size || !ref)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ count = MSCMS_get_tag_count( profile->iccprofile );
for (i = 0; i < count; i++)
{
- MSCMS_get_tag_by_index( iccprofile, i, &tag );
+ MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
if (tag.sig == type)
{
if ((tag.size - offset) > *size || !buffer)
{
*size = (tag.size - offset);
+ release_profile( profile );
return FALSE;
}
-
- MSCMS_get_tag_data( iccprofile, &tag, offset, buffer );
+ MSCMS_get_tag_data( profile->iccprofile, &tag, offset, buffer );
*ref = FALSE; /* FIXME: calculate properly */
+ release_profile( profile );
return TRUE;
}
}
+ release_profile( profile );
#endif /* HAVE_LCMS */
return ret;
* The tag table index starts at 1.
* Use GetCountColorProfileElements to retrieve a count of tagged elements.
*/
-BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE type )
+BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
DWORD count;
icTag tag;
- TRACE( "( %p, %d, %p )\n", profile, index, type );
-
- if (!iccprofile || !type) return FALSE;
+ TRACE( "( %p, %d, %p )\n", handle, index, type );
- count = MSCMS_get_tag_count( iccprofile );
- if (index > count || index < 1) return FALSE;
+ if (!profile) return FALSE;
- MSCMS_get_tag_by_index( iccprofile, index - 1, &tag );
+ if (!type)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ count = MSCMS_get_tag_count( profile->iccprofile );
+ if (index > count || index < 1)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ MSCMS_get_tag_by_index( profile->iccprofile, index - 1, &tag );
*type = tag.sig;
+ release_profile( profile );
ret = TRUE;
#endif /* HAVE_LCMS */
* NOTES
* The profile returned will be in big-endian format.
*/
-BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD size )
+BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
PROFILEHEADER header;
- TRACE( "( %p, %p, %p )\n", profile, buffer, size );
+ TRACE( "( %p, %p, %p )\n", handle, buffer, size );
- if (!iccprofile || !size) return FALSE;
- MSCMS_get_profile_header( iccprofile, &header );
+ if (!profile) return FALSE;
+
+ if (!size)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ MSCMS_get_profile_header( profile->iccprofile, &header );
if (!buffer || header.phSize > *size)
{
*size = header.phSize;
+ release_profile( profile );
return FALSE;
}
/* No endian conversion needed */
- memcpy( buffer, iccprofile, header.phSize );
-
+ memcpy( buffer, profile->iccprofile, header.phSize );
*size = header.phSize;
+
+ release_profile( profile );
ret = TRUE;
#endif /* HAVE_LCMS */
* NOTES
* The profile header returned will be adjusted for endianess.
*/
-BOOL WINAPI GetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
+BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
+
+ TRACE( "( %p, %p )\n", handle, header );
- TRACE( "( %p, %p )\n", profile, header );
+ if (!profile) return FALSE;
- if (!iccprofile || !header) return FALSE;
+ if (!header)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ MSCMS_get_profile_header( profile->iccprofile, header );
- MSCMS_get_profile_header( iccprofile, header );
+ release_profile( profile );
return TRUE;
#else
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI GetCountColorProfileElements( HPROFILE profile, PDWORD count )
+BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
- TRACE( "( %p, %p )\n", profile, count );
+ TRACE( "( %p, %p )\n", handle, count );
- if (!iccprofile || !count) return FALSE;
- *count = MSCMS_get_tag_count( iccprofile );
+ if (!profile) return FALSE;
+
+ if (!count)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ *count = MSCMS_get_tag_count( profile->iccprofile );
+
+ release_profile( profile );
ret = TRUE;
#endif /* HAVE_LCMS */
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE type, PBOOL present )
+BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
DWORD i, count;
icTag tag;
- TRACE( "( %p, 0x%08x, %p )\n", profile, type, present );
+ TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
- if (!iccprofile || !present) return FALSE;
+ if (!profile) return FALSE;
- count = MSCMS_get_tag_count( iccprofile );
+ if (!present)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ count = MSCMS_get_tag_count( profile->iccprofile );
for (i = 0; i < count; i++)
{
- MSCMS_get_tag_by_index( iccprofile, i, &tag );
+ MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
if (tag.sig == type)
{
break;
}
}
+ release_profile( profile );
#endif /* HAVE_LCMS */
return ret;
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI IsColorProfileValid( HPROFILE profile, PBOOL valid )
+BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
+ struct profile *profile = grab_profile( handle );
+
+ TRACE( "( %p, %p )\n", handle, valid );
- TRACE( "( %p, %p )\n", profile, valid );
+ if (!profile) return FALSE;
- if (!valid) return FALSE;
- if (iccprofile) return *valid = TRUE;
+ if (!valid)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ if (profile->iccprofile) ret = *valid = TRUE;
+ release_profile( profile );
#endif /* HAVE_LCMS */
return ret;
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI SetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
+BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size,
PVOID buffer )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
- DWORD i, count, access = MSCMS_hprofile2access( profile );
+ struct profile *profile = grab_profile( handle );
+ DWORD i, count;
icTag tag;
- TRACE( "( %p, 0x%08x, %d, %p, %p )\n", profile, type, offset, size, buffer );
+ TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer );
- if (!iccprofile || !size || !buffer) return FALSE;
- if (!(access & PROFILE_READWRITE)) return FALSE;
+ if (!profile) return FALSE;
- count = MSCMS_get_tag_count( iccprofile );
+ if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ count = MSCMS_get_tag_count( profile->iccprofile );
for (i = 0; i < count; i++)
{
- MSCMS_get_tag_by_index( iccprofile, i, &tag );
+ MSCMS_get_tag_by_index( profile->iccprofile, i, &tag );
if (tag.sig == type)
{
- if (offset > tag.size) return FALSE;
+ if (offset > tag.size)
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ MSCMS_set_tag_data( profile->iccprofile, &tag, offset, buffer );
- MSCMS_set_tag_data( iccprofile, &tag, offset, buffer );
+ release_profile( profile );
return TRUE;
}
}
+ release_profile( profile );
#endif /* HAVE_LCMS */
return ret;
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
+BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
{
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
- DWORD access = MSCMS_hprofile2access( profile );
+ struct profile *profile = grab_profile( handle );
- TRACE( "( %p, %p )\n", profile, header );
+ TRACE( "( %p, %p )\n", handle, header );
- if (!iccprofile || !header) return FALSE;
- if (!(access & PROFILE_READWRITE)) return FALSE;
+ if (!profile) return FALSE;
- MSCMS_set_profile_header( iccprofile, header );
+ if (!header || !(profile->access & PROFILE_READWRITE))
+ {
+ release_profile( profile );
+ return FALSE;
+ }
+ MSCMS_set_profile_header( profile->iccprofile, header );
+
+ release_profile( profile );
return TRUE;
#else
}
if (cmsprofile)
- return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile, access );
+ {
+ struct profile profile;
+
+ profile.file = handle;
+ profile.access = access;
+ profile.iccprofile = iccprofile;
+ profile.cmsprofile = cmsprofile;
+
+ return create_profile( &profile );
+ }
#endif /* HAVE_LCMS */
return NULL;
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
- HANDLE file = MSCMS_hprofile2handle( profile );
- DWORD access = MSCMS_hprofile2access( profile );
TRACE( "( %p )\n", profile );
-
- if (file != INVALID_HANDLE_VALUE)
- {
- if (access & PROFILE_READWRITE)
- {
- DWORD written, size = MSCMS_get_profile_size( iccprofile );
-
- if (SetFilePointer( file, 0, NULL, FILE_BEGIN ) ||
- !WriteFile( file, iccprofile, size, &written, NULL ) || written != size)
- {
- ERR( "Unable to write color profile\n" );
- }
- }
- CloseHandle( file );
- }
- ret = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
- HeapFree( GetProcessHeap(), 0, iccprofile );
-
- MSCMS_destroy_hprofile_handle( profile );
+ ret = close_profile( profile );
#endif /* HAVE_LCMS */
return ret;
{
HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS
- cmsHTRANSFORM cmstransform;
+ struct transform transform;
+ struct profile *dst, *tgt = NULL;
cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL;
DWORD in_format, out_format, proofing = 0;
int intent;
TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags );
- if (!space || !dest) return FALSE;
+ if (!space || !(dst = grab_profile( dest ))) return FALSE;
+ if (target && !(tgt = grab_profile( target )))
+ {
+ release_profile( dst );
+ return FALSE;
+ }
intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
TRACE( "lcsIntent: %x\n", space->lcsIntent );
if (target)
{
proofing = cmsFLAGS_SOFTPROOFING;
- cmstarget = MSCMS_hprofile2cmsprofile( target );
+ cmstarget = tgt->cmsprofile;
}
- cmsoutput = MSCMS_hprofile2cmsprofile( dest );
- cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
- intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
+ cmsoutput = dst->cmsprofile;
+ transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget,
+ intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing);
- ret = MSCMS_create_htransform_handle( cmstransform );
+ ret = create_transform( &transform );
+
+ if (tgt) release_profile( tgt );
+ release_profile( dst );
#endif /* HAVE_LCMS */
return ret;
HTRANSFORM ret = NULL;
#ifdef HAVE_LCMS
cmsHPROFILE *cmsprofiles, cmsconvert = NULL;
- cmsHTRANSFORM cmstransform;
+ struct transform transform;
+ struct profile *profile0, *profile1;
DWORD in_format, out_format;
TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n",
return NULL;
}
+ profile0 = grab_profile( profiles[0] );
+ if (!profile0) return NULL;
+ profile1 = grab_profile( profiles[1] );
+ if (!profile1)
+ {
+ release_profile( profile0 );
+ return NULL;
+ }
in_format = from_profile( profiles[0] );
out_format = from_profile( profiles[nprofiles - 1] );
cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) );
if (cmsprofiles)
{
- cmsprofiles[0] = MSCMS_hprofile2cmsprofile( profiles[0] );
+ cmsprofiles[0] = profile0->cmsprofile;
if (cmsconvert)
{
cmsprofiles[1] = cmsconvert;
- cmsprofiles[2] = MSCMS_hprofile2cmsprofile( profiles[1] );
+ cmsprofiles[2] = profile1->cmsprofile;
nprofiles++;
}
else
{
- cmsprofiles[1] = MSCMS_hprofile2cmsprofile( profiles[1] );
+ cmsprofiles[1] = profile1->cmsprofile;
}
- cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
+ transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 );
HeapFree( GetProcessHeap(), 0, cmsprofiles );
- ret = MSCMS_create_htransform_handle( cmstransform );
+ ret = create_transform( &transform );
}
+ release_profile( profile0 );
+ release_profile( profile1 );
+
#endif /* HAVE_LCMS */
return ret;
}
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI DeleteColorTransform( HTRANSFORM transform )
+BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- cmsHTRANSFORM cmstransform;
- TRACE( "( %p )\n", transform );
+ TRACE( "( %p )\n", handle );
- cmstransform = MSCMS_htransform2cmstransform( transform );
- cmsDeleteTransform( cmstransform );
-
- MSCMS_destroy_htransform_handle( transform );
- ret = TRUE;
+ ret = close_transform( handle );
#endif /* HAVE_LCMS */
return ret;
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI TranslateBitmapBits( HTRANSFORM transform, PVOID srcbits, BMFORMAT input,
+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 )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- cmsHTRANSFORM cmstransform;
+ 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",
- transform, srcbits, input, width, height, inputstride, destbits, output,
+ handle, srcbits, input, width, height, inputstride, destbits, output,
outputstride, callback, data );
- cmstransform = MSCMS_htransform2cmstransform( transform );
- cmsChangeBuffersFormat( cmstransform, from_bmformat(input), from_bmformat(output) );
+ if (!transform) return FALSE;
+ cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
- cmsDoTransform( cmstransform, srcbits, destbits, width * height );
+ cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
+ release_transform( transform );
ret = TRUE;
#endif /* HAVE_LCMS */
* Success: TRUE
* Failure: FALSE
*/
-BOOL WINAPI TranslateColors( HTRANSFORM transform, PCOLOR in, DWORD count,
+BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
COLORTYPE input_type, PCOLOR out, COLORTYPE output_type )
{
BOOL ret = FALSE;
#ifdef HAVE_LCMS
- cmsHTRANSFORM xfrm = MSCMS_htransform2cmstransform( transform );
+ struct transform *transform = grab_transform( handle );
+ cmsHTRANSFORM xfrm;
unsigned int i;
- TRACE( "( %p, %p, %d, %d, %p, %d )\n", transform, 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;
+ xfrm = transform->cmstransform;
cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) );
switch (input_type)
FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type);
break;
}
+ release_transform( transform );
#endif /* HAVE_LCMS */
return ret;