mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-06 09:17:14 +00:00
mscms: Merge the profile and transform handle tables.
This commit is contained in:
parent
8a56c4dbba
commit
ebcb18d418
|
@ -30,6 +30,8 @@
|
||||||
|
|
||||||
#include "mscms_priv.h"
|
#include "mscms_priv.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
||||||
|
|
||||||
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 =
|
||||||
{
|
{
|
||||||
|
@ -40,209 +42,107 @@ static CRITICAL_SECTION_DEBUG mscms_handle_cs_debug =
|
||||||
};
|
};
|
||||||
static CRITICAL_SECTION mscms_handle_cs = { &mscms_handle_cs_debug, -1, 0, 0, 0, 0 };
|
static CRITICAL_SECTION mscms_handle_cs = { &mscms_handle_cs_debug, -1, 0, 0, 0, 0 };
|
||||||
|
|
||||||
static struct profile *profiletable;
|
static struct object **handle_table;
|
||||||
static cmsHTRANSFORM *transformtable;
|
static ULONG_PTR next_handle;
|
||||||
|
static ULONG_PTR max_handles;
|
||||||
|
|
||||||
static unsigned int num_profile_handles;
|
struct object *grab_object( HANDLE handle, enum object_type type )
|
||||||
static unsigned int num_transform_handles;
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
|
||||||
|
|
||||||
void free_handle_tables( void )
|
|
||||||
{
|
{
|
||||||
free( profiletable );
|
struct object *obj = NULL;
|
||||||
profiletable = NULL;
|
ULONG_PTR index = (ULONG_PTR)handle;
|
||||||
num_profile_handles = 0;
|
|
||||||
|
|
||||||
free( transformtable );
|
|
||||||
transformtable = NULL;
|
|
||||||
num_transform_handles = 0;
|
|
||||||
|
|
||||||
DeleteCriticalSection( &mscms_handle_cs );
|
|
||||||
}
|
|
||||||
|
|
||||||
struct profile *grab_profile( HPROFILE handle )
|
|
||||||
{
|
|
||||||
DWORD_PTR index;
|
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
EnterCriticalSection( &mscms_handle_cs );
|
||||||
|
if (index > 0 && index <= max_handles)
|
||||||
index = (DWORD_PTR)handle - 1;
|
|
||||||
if (index > num_profile_handles)
|
|
||||||
{
|
{
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
index--;
|
||||||
return NULL;
|
if (handle_table[index] && handle_table[index]->type == type)
|
||||||
}
|
|
||||||
return &profiletable[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void release_profile( struct profile *profile )
|
|
||||||
{
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
|
||||||
}
|
|
||||||
|
|
||||||
cmsHTRANSFORM grab_transform( HTRANSFORM handle )
|
|
||||||
{
|
|
||||||
DWORD_PTR index;
|
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
|
||||||
|
|
||||||
index = (DWORD_PTR)handle - 1;
|
|
||||||
if (index > num_transform_handles)
|
|
||||||
{
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return transformtable[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void release_transform( cmsHTRANSFORM transform )
|
|
||||||
{
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
|
||||||
}
|
|
||||||
|
|
||||||
static HPROFILE alloc_profile_handle( void )
|
|
||||||
{
|
|
||||||
DWORD_PTR index;
|
|
||||||
struct profile *p;
|
|
||||||
unsigned int count = 128;
|
|
||||||
|
|
||||||
for (index = 0; index < num_profile_handles; index++)
|
|
||||||
{
|
|
||||||
if (!profiletable[index].data) return (HPROFILE)(index + 1);
|
|
||||||
}
|
|
||||||
if (!profiletable)
|
|
||||||
{
|
|
||||||
p = calloc( count, sizeof(*p) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count = num_profile_handles * 2;
|
|
||||||
p = realloc( profiletable, count * sizeof(*p) );
|
|
||||||
if (p) memset( p + num_profile_handles, 0, num_profile_handles * sizeof(*p) );
|
|
||||||
}
|
|
||||||
if (!p) return NULL;
|
|
||||||
|
|
||||||
profiletable = p;
|
|
||||||
num_profile_handles = count;
|
|
||||||
|
|
||||||
return (HPROFILE)(index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
HPROFILE create_profile( struct profile *profile )
|
|
||||||
{
|
|
||||||
HPROFILE handle;
|
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
|
||||||
|
|
||||||
if ((handle = alloc_profile_handle()))
|
|
||||||
{
|
|
||||||
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
|
||||||
profiletable[index] = *profile;
|
|
||||||
}
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
|
||||||
return handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL close_profile( HPROFILE handle )
|
|
||||||
{
|
|
||||||
DWORD_PTR index;
|
|
||||||
struct profile *profile;
|
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
|
||||||
|
|
||||||
index = (DWORD_PTR)handle - 1;
|
|
||||||
if (index > num_profile_handles)
|
|
||||||
{
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
profile = &profiletable[index];
|
|
||||||
|
|
||||||
if (profile->file != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
if (profile->access & PROFILE_READWRITE)
|
|
||||||
{
|
{
|
||||||
DWORD written;
|
obj = handle_table[index];
|
||||||
|
InterlockedIncrement( &obj->refs );
|
||||||
if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) ||
|
|
||||||
!WriteFile( profile->file, profile->data, profile->size, &written, NULL ) ||
|
|
||||||
written != profile->size)
|
|
||||||
{
|
|
||||||
ERR( "Unable to write color profile\n" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
CloseHandle( profile->file );
|
|
||||||
}
|
}
|
||||||
if (profile->cmsprofile) cmsCloseProfile( profile->cmsprofile );
|
|
||||||
free( profile->data );
|
|
||||||
|
|
||||||
memset( profile, 0, sizeof(struct profile) );
|
|
||||||
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
return TRUE;
|
|
||||||
|
TRACE( "handle %p -> %p\n", handle, obj );
|
||||||
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HTRANSFORM alloc_transform_handle( void )
|
void release_object( struct object *obj )
|
||||||
{
|
{
|
||||||
DWORD_PTR index;
|
ULONG refs = InterlockedDecrement( &obj->refs );
|
||||||
cmsHTRANSFORM *p;
|
if (!refs)
|
||||||
unsigned int count = 128;
|
|
||||||
|
|
||||||
for (index = 0; index < num_transform_handles; index++)
|
|
||||||
{
|
{
|
||||||
if (!transformtable[index]) return (HTRANSFORM)(index + 1);
|
if (obj->close) obj->close( obj );
|
||||||
|
TRACE( "destroying object %p\n", obj );
|
||||||
|
free( obj );
|
||||||
}
|
}
|
||||||
if (!transformtable)
|
|
||||||
{
|
|
||||||
p = calloc( count, sizeof(*p) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count = num_transform_handles * 2;
|
|
||||||
p = realloc( transformtable, count * sizeof(*p) );
|
|
||||||
if (p) memset( p + num_transform_handles, 0, num_transform_handles * sizeof(*p) );
|
|
||||||
}
|
|
||||||
if (!p) return NULL;
|
|
||||||
|
|
||||||
transformtable = p;
|
|
||||||
num_transform_handles = count;
|
|
||||||
|
|
||||||
return (HTRANSFORM)(index + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HTRANSFORM create_transform( cmsHTRANSFORM transform )
|
#define HANDLE_TABLE_SIZE 4
|
||||||
|
HANDLE alloc_handle( struct object *obj )
|
||||||
{
|
{
|
||||||
HTRANSFORM handle;
|
struct object **ptr;
|
||||||
|
ULONG_PTR index, count;
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
EnterCriticalSection( &mscms_handle_cs );
|
||||||
|
if (!max_handles)
|
||||||
if ((handle = alloc_transform_handle()))
|
|
||||||
{
|
{
|
||||||
DWORD_PTR index = (DWORD_PTR)handle - 1;
|
count = HANDLE_TABLE_SIZE;
|
||||||
transformtable[index] = transform;
|
if (!(ptr = calloc( 1, sizeof(*ptr) * count )))
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
handle_table = ptr;
|
||||||
|
max_handles = count;
|
||||||
}
|
}
|
||||||
|
if (max_handles == next_handle)
|
||||||
|
{
|
||||||
|
size_t new_size, old_size = max_handles * sizeof(*ptr);
|
||||||
|
count = max_handles * 2;
|
||||||
|
new_size = count * sizeof(*ptr);
|
||||||
|
if (!(ptr = realloc( handle_table, new_size )))
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset( (char *)ptr + old_size, 0, new_size - old_size );
|
||||||
|
handle_table = ptr;
|
||||||
|
max_handles = count;
|
||||||
|
}
|
||||||
|
index = next_handle;
|
||||||
|
if (handle_table[index]) ERR( "handle isn't free but should be\n" );
|
||||||
|
|
||||||
|
handle_table[index] = obj;
|
||||||
|
InterlockedIncrement( &obj->refs );
|
||||||
|
while (next_handle < max_handles && handle_table[next_handle]) next_handle++;
|
||||||
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
return handle;
|
TRACE( "object %p -> %Ix\n", obj, index + 1 );
|
||||||
|
return (HANDLE)(index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL close_transform( HTRANSFORM handle )
|
void free_handle( HANDLE handle )
|
||||||
{
|
{
|
||||||
DWORD_PTR index;
|
struct object *obj = NULL;
|
||||||
cmsHTRANSFORM transform;
|
ULONG_PTR index = (ULONG_PTR)handle;
|
||||||
|
|
||||||
EnterCriticalSection( &mscms_handle_cs );
|
EnterCriticalSection( &mscms_handle_cs );
|
||||||
|
if (index > 0 && index <= max_handles)
|
||||||
index = (DWORD_PTR)handle - 1;
|
|
||||||
if (index > num_transform_handles)
|
|
||||||
{
|
{
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
index--;
|
||||||
return FALSE;
|
if (handle_table[index])
|
||||||
|
{
|
||||||
|
obj = handle_table[index];
|
||||||
|
TRACE( "destroying handle %p for object %p\n", handle, obj );
|
||||||
|
handle_table[index] = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
transform = transformtable[index];
|
|
||||||
transformtable[index] = 0;
|
|
||||||
cmsDeleteTransform( transform );
|
|
||||||
|
|
||||||
LeaveCriticalSection( &mscms_handle_cs );
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
return TRUE;
|
|
||||||
|
if (obj) release_object( obj );
|
||||||
|
|
||||||
|
EnterCriticalSection( &mscms_handle_cs );
|
||||||
|
if (next_handle > index && !handle_table[index]) next_handle = index;
|
||||||
|
LeaveCriticalSection( &mscms_handle_cs );
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, void *reserved )
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
if (reserved) break;
|
if (reserved) break;
|
||||||
free_handle_tables();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
|
@ -27,28 +27,40 @@
|
||||||
|
|
||||||
#include <lcms2.h>
|
#include <lcms2.h>
|
||||||
|
|
||||||
struct profile
|
enum object_type
|
||||||
{
|
{
|
||||||
HANDLE file;
|
OBJECT_TYPE_PROFILE,
|
||||||
DWORD access;
|
OBJECT_TYPE_TRANSFORM,
|
||||||
char *data;
|
|
||||||
DWORD size;
|
|
||||||
cmsHPROFILE cmsprofile;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern HPROFILE create_profile( struct profile * ) DECLSPEC_HIDDEN;
|
struct object
|
||||||
extern BOOL close_profile( HPROFILE ) DECLSPEC_HIDDEN;
|
{
|
||||||
|
enum object_type type;
|
||||||
|
LONG refs;
|
||||||
|
void (*close)( struct object * );
|
||||||
|
};
|
||||||
|
|
||||||
extern HTRANSFORM create_transform( cmsHTRANSFORM ) DECLSPEC_HIDDEN;
|
struct profile
|
||||||
extern BOOL close_transform( HTRANSFORM ) DECLSPEC_HIDDEN;
|
{
|
||||||
|
struct object hdr;
|
||||||
|
HANDLE file;
|
||||||
|
DWORD access;
|
||||||
|
char *data;
|
||||||
|
DWORD size;
|
||||||
|
cmsHPROFILE cmsprofile;
|
||||||
|
};
|
||||||
|
|
||||||
struct profile *grab_profile( HPROFILE ) DECLSPEC_HIDDEN;
|
struct transform
|
||||||
cmsHTRANSFORM grab_transform( HTRANSFORM ) DECLSPEC_HIDDEN;
|
{
|
||||||
|
struct object hdr;
|
||||||
|
cmsHTRANSFORM cmstransform;
|
||||||
|
};
|
||||||
|
|
||||||
void release_profile( struct profile * ) DECLSPEC_HIDDEN;
|
extern HANDLE alloc_handle( struct object *obj ) DECLSPEC_HIDDEN;
|
||||||
void release_transform( cmsHTRANSFORM ) DECLSPEC_HIDDEN;
|
extern void free_handle( HANDLE ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern void free_handle_tables( void ) DECLSPEC_HIDDEN;
|
struct object *grab_object( HANDLE, enum object_type ) DECLSPEC_HIDDEN;
|
||||||
|
void release_object( struct object * ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
struct tag_entry
|
struct tag_entry
|
||||||
{
|
{
|
||||||
|
|
|
@ -323,7 +323,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
|
||||||
PVOID buffer, PBOOL ref )
|
PVOID buffer, PBOOL ref )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %#lx, %lu, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
|
TRACE( "( %p, %#lx, %lu, %p, %p, %p )\n", handle, type, offset, size, buffer, ref );
|
||||||
|
|
||||||
|
@ -331,11 +331,11 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
|
||||||
|
|
||||||
if (!size || !ref)
|
if (!size || !ref)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ret = get_tag_data( profile, type, offset, buffer, size, ref );
|
ret = get_tag_data( profile, type, offset, buffer, size, ref );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,7 +360,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;
|
BOOL ret;
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
struct tag_entry tag;
|
struct tag_entry tag;
|
||||||
|
|
||||||
TRACE( "( %p, %lu, %p )\n", handle, index, type );
|
TRACE( "( %p, %lu, %p )\n", handle, index, type );
|
||||||
|
@ -369,11 +369,11 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty
|
||||||
|
|
||||||
if (!type)
|
if (!type)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
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_object( &profile->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ 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 )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
PROFILEHEADER header;
|
PROFILEHEADER header;
|
||||||
|
|
||||||
TRACE( "( %p, %p, %p )\n", handle, buffer, size );
|
TRACE( "( %p, %p, %p )\n", handle, buffer, size );
|
||||||
|
@ -406,7 +406,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
|
||||||
|
|
||||||
if (!size)
|
if (!size)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
get_profile_header( profile, &header );
|
get_profile_header( profile, &header );
|
||||||
|
@ -414,7 +414,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
|
||||||
if (!buffer || header.phSize > *size)
|
if (!buffer || header.phSize > *size)
|
||||||
{
|
{
|
||||||
*size = header.phSize;
|
*size = header.phSize;
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,7 +422,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
|
||||||
memcpy( buffer, profile->data, profile->size );
|
memcpy( buffer, profile->data, profile->size );
|
||||||
*size = profile->size;
|
*size = profile->size;
|
||||||
|
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +444,7 @@ BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD siz
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", handle, header );
|
TRACE( "( %p, %p )\n", handle, header );
|
||||||
|
|
||||||
|
@ -452,11 +452,11 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
|
|
||||||
if (!header)
|
if (!header)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
get_profile_header( profile, header );
|
get_profile_header( profile, header );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +476,7 @@ BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
|
BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", handle, count );
|
TRACE( "( %p, %p )\n", handle, count );
|
||||||
|
|
||||||
|
@ -484,11 +484,11 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
|
||||||
|
|
||||||
if (!count)
|
if (!count)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*count = get_tag_count( profile );
|
*count = get_tag_count( profile );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,7 +1058,7 @@ 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 )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
struct tag_entry tag;
|
struct tag_entry tag;
|
||||||
|
|
||||||
TRACE( "( %p, %#lx, %p )\n", handle, type, present );
|
TRACE( "( %p, %#lx, %p )\n", handle, type, present );
|
||||||
|
@ -1067,11 +1067,11 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
|
||||||
|
|
||||||
if (!present)
|
if (!present)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*present = get_adjusted_tag( profile, type, &tag );
|
*present = get_adjusted_tag( profile, type, &tag );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1091,7 +1091,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
|
BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", handle, valid );
|
TRACE( "( %p, %p )\n", handle, valid );
|
||||||
|
|
||||||
|
@ -1099,11 +1099,11 @@ BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid )
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
*valid = !!profile->data;
|
*valid = !!profile->data;
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return *valid;
|
return *valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1128,7 +1128,7 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
|
||||||
PVOID buffer )
|
PVOID buffer )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %#lx, %lu, %p, %p )\n", handle, type, offset, size, buffer );
|
TRACE( "( %p, %#lx, %lu, %p, %p )\n", handle, type, offset, size, buffer );
|
||||||
|
|
||||||
|
@ -1136,11 +1136,11 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
|
||||||
|
|
||||||
if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
|
if (!size || !buffer || !(profile->access & PROFILE_READWRITE))
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ret = set_tag_data( profile, type, offset, buffer, size );
|
ret = set_tag_data( profile, type, offset, buffer, size );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1159,7 +1159,7 @@ BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
{
|
{
|
||||||
struct profile *profile = grab_profile( handle );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
|
|
||||||
TRACE( "( %p, %p )\n", handle, header );
|
TRACE( "( %p, %p )\n", handle, header );
|
||||||
|
|
||||||
|
@ -1167,11 +1167,11 @@ BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header )
|
||||||
|
|
||||||
if (!header || !(profile->access & PROFILE_READWRITE))
|
if (!header || !(profile->access & PROFILE_READWRITE))
|
||||||
{
|
{
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
set_profile_header( profile, header );
|
set_profile_header( profile, header );
|
||||||
release_profile( profile );
|
release_object( &profile->hdr );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1261,6 +1261,28 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close_profile( struct object *obj )
|
||||||
|
{
|
||||||
|
struct profile *profile = (struct profile *)obj;
|
||||||
|
|
||||||
|
if (profile->file != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (profile->access & PROFILE_READWRITE)
|
||||||
|
{
|
||||||
|
DWORD count;
|
||||||
|
if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) ||
|
||||||
|
!WriteFile( profile->file, profile->data, profile->size, &count, NULL ) || count != profile->size)
|
||||||
|
{
|
||||||
|
ERR( "Unable to write color profile\n" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle( profile->file );
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile->cmsprofile) cmsCloseProfile( profile->cmsprofile );
|
||||||
|
free( profile->data );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* OpenColorProfileW [MSCMS.@]
|
* OpenColorProfileW [MSCMS.@]
|
||||||
*
|
*
|
||||||
|
@ -1285,8 +1307,8 @@ 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 )
|
||||||
{
|
{
|
||||||
struct profile prof;
|
struct profile *prof;
|
||||||
HPROFILE hprof;
|
HPROFILE ret;
|
||||||
cmsHPROFILE cmsprofile;
|
cmsHPROFILE cmsprofile;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
|
@ -1377,13 +1399,18 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
prof.file = handle;
|
if ((prof = calloc( 1, sizeof(*prof) )))
|
||||||
prof.access = access;
|
{
|
||||||
prof.data = data;
|
prof->hdr.type = OBJECT_TYPE_PROFILE;
|
||||||
prof.size = size;
|
prof->hdr.close = close_profile;
|
||||||
prof.cmsprofile = cmsprofile;
|
prof->file = handle;
|
||||||
|
prof->access = access;
|
||||||
if ((hprof = create_profile( &prof ))) return hprof;
|
prof->data = data;
|
||||||
|
prof->size = size;
|
||||||
|
prof->cmsprofile = cmsprofile;
|
||||||
|
if ((ret = alloc_handle( &prof->hdr ))) return ret;
|
||||||
|
free( prof );
|
||||||
|
}
|
||||||
|
|
||||||
cmsCloseProfile( cmsprofile );
|
cmsCloseProfile( cmsprofile );
|
||||||
free( data );
|
free( data );
|
||||||
|
@ -1403,10 +1430,16 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
||||||
* Success: TRUE
|
* Success: TRUE
|
||||||
* Failure: FALSE
|
* Failure: FALSE
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI CloseColorProfile( HPROFILE profile )
|
BOOL WINAPI CloseColorProfile( HPROFILE handle )
|
||||||
{
|
{
|
||||||
TRACE( "( %p )\n", profile );
|
struct profile *profile = (struct profile *)grab_object( handle, OBJECT_TYPE_PROFILE );
|
||||||
return close_profile( profile );
|
|
||||||
|
TRACE( "( %p )\n", handle );
|
||||||
|
|
||||||
|
if (!profile) return FALSE;
|
||||||
|
free_handle( handle );
|
||||||
|
release_object( &profile->hdr );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
|
@ -103,6 +104,12 @@ HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest,
|
||||||
return CreateColorTransformW( &spaceW, dest, target, flags );
|
return CreateColorTransformW( &spaceW, dest, target, flags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void close_transform( struct object *obj )
|
||||||
|
{
|
||||||
|
struct transform *transform = (struct transform *)obj;
|
||||||
|
if (transform->cmstransform) cmsDeleteTransform( transform->cmstransform );
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* CreateColorTransformW [MSCMS.@]
|
* CreateColorTransformW [MSCMS.@]
|
||||||
*
|
*
|
||||||
|
@ -121,7 +128,8 @@ HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest,
|
||||||
HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, HPROFILE target, DWORD flags )
|
HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, HPROFILE target, DWORD flags )
|
||||||
{
|
{
|
||||||
HTRANSFORM ret = NULL;
|
HTRANSFORM ret = NULL;
|
||||||
cmsHTRANSFORM transform;
|
struct transform *transform;
|
||||||
|
cmsHTRANSFORM cmstransform;
|
||||||
struct profile *dst, *tgt = NULL;
|
struct profile *dst, *tgt = NULL;
|
||||||
DWORD proofing = 0;
|
DWORD proofing = 0;
|
||||||
cmsHPROFILE input;
|
cmsHPROFILE input;
|
||||||
|
@ -129,11 +137,10 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
|
||||||
|
|
||||||
TRACE( "( %p, %p, %p, %#lx )\n", space, dest, target, flags );
|
TRACE( "( %p, %p, %p, %#lx )\n", space, dest, target, flags );
|
||||||
|
|
||||||
if (!space || !(dst = grab_profile( dest ))) return FALSE;
|
if (!space || !(dst = (struct profile *)grab_object( dest, OBJECT_TYPE_PROFILE ))) return FALSE;
|
||||||
|
if (target && !(tgt = (struct profile *)grab_object( target, OBJECT_TYPE_PROFILE )))
|
||||||
if (target && !(tgt = grab_profile( target )))
|
|
||||||
{
|
{
|
||||||
release_profile( dst );
|
release_object( &dst->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
|
intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent;
|
||||||
|
@ -144,19 +151,25 @@ HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest,
|
||||||
|
|
||||||
input = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
|
input = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */
|
||||||
if (target) proofing = cmsFLAGS_SOFTPROOFING;
|
if (target) proofing = cmsFLAGS_SOFTPROOFING;
|
||||||
transform = cmsCreateProofingTransform( input, 0, dst->cmsprofile, 0, tgt ? tgt->cmsprofile : NULL,
|
cmstransform = cmsCreateProofingTransform( input, 0, dst->cmsprofile, 0, tgt ? tgt->cmsprofile : NULL,
|
||||||
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing );
|
intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing );
|
||||||
if (!transform)
|
if (!cmstransform)
|
||||||
{
|
{
|
||||||
if (tgt) release_profile( tgt );
|
if (tgt) release_object( &tgt->hdr );
|
||||||
release_profile( dst );
|
release_object( &dst->hdr );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = create_transform( transform );
|
if ((transform = calloc( 1, sizeof(*transform) )))
|
||||||
|
{
|
||||||
|
transform->hdr.type = OBJECT_TYPE_TRANSFORM;
|
||||||
|
transform->hdr.close = close_transform;
|
||||||
|
transform->cmstransform = cmstransform;
|
||||||
|
if (!(ret = alloc_handle( &transform->hdr ))) free( transform );
|
||||||
|
}
|
||||||
|
|
||||||
if (tgt) release_profile( tgt );
|
if (tgt) release_object( &tgt->hdr );
|
||||||
release_profile( dst );
|
release_object( &dst->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +194,8 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
{
|
{
|
||||||
HTRANSFORM ret = NULL;
|
HTRANSFORM ret = NULL;
|
||||||
cmsHPROFILE cmsprofiles[2];
|
cmsHPROFILE cmsprofiles[2];
|
||||||
cmsHTRANSFORM transform;
|
cmsHTRANSFORM cmstransform;
|
||||||
|
struct transform *transform;
|
||||||
struct profile *profile0, *profile1;
|
struct profile *profile0, *profile1;
|
||||||
|
|
||||||
TRACE( "( %p, %#lx, %p, %lu, %#lx, %#lx )\n", profiles, nprofiles, intents, nintents, flags, cmm );
|
TRACE( "( %p, %#lx, %p, %lu, %#lx, %#lx )\n", profiles, nprofiles, intents, nintents, flags, cmm );
|
||||||
|
@ -194,23 +208,34 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
profile0 = grab_profile( profiles[0] );
|
profile0 = (struct profile *)grab_object( profiles[0], OBJECT_TYPE_PROFILE );
|
||||||
if (!profile0) return NULL;
|
if (!profile0) return NULL;
|
||||||
profile1 = grab_profile( profiles[1] );
|
profile1 = (struct profile *)grab_object( profiles[1], OBJECT_TYPE_PROFILE );
|
||||||
if (!profile1)
|
if (!profile1)
|
||||||
{
|
{
|
||||||
release_profile( profile0 );
|
release_object( &profile0->hdr );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmsprofiles[0] = profile0->cmsprofile;
|
cmsprofiles[0] = profile0->cmsprofile;
|
||||||
cmsprofiles[1] = profile1->cmsprofile;
|
cmsprofiles[1] = profile1->cmsprofile;
|
||||||
|
if (!(cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, 0, 0, *intents, 0 )))
|
||||||
|
{
|
||||||
|
release_object( &profile0->hdr );
|
||||||
|
release_object( &profile1->hdr );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
transform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, 0, 0, *intents, 0 );
|
if ((transform = calloc( 1, sizeof(*transform) )))
|
||||||
if (transform) ret = create_transform( transform );
|
{
|
||||||
|
transform->hdr.type = OBJECT_TYPE_TRANSFORM;
|
||||||
|
transform->hdr.close = close_transform;
|
||||||
|
transform->cmstransform = cmstransform;
|
||||||
|
if (!(ret = alloc_handle( &transform->hdr ))) free( transform );
|
||||||
|
}
|
||||||
|
|
||||||
release_profile( profile0 );
|
release_object( &profile0->hdr );
|
||||||
release_profile( profile1 );
|
release_object( &profile1->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,9 +253,14 @@ HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofil
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
|
BOOL WINAPI DeleteColorTransform( HTRANSFORM handle )
|
||||||
{
|
{
|
||||||
|
struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM );
|
||||||
|
|
||||||
TRACE( "( %p )\n", handle );
|
TRACE( "( %p )\n", handle );
|
||||||
|
|
||||||
return close_transform( handle );
|
if (!transform) return FALSE;
|
||||||
|
free_handle( handle );
|
||||||
|
release_object( &transform->hdr );
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -260,16 +290,16 @@ BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT inpu
|
||||||
DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
|
DWORD outputstride, PBMCALLBACKFN callback, ULONG data )
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
cmsHTRANSFORM transform = grab_transform( handle );
|
struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM );
|
||||||
|
|
||||||
TRACE( "( %p, %p, %#x, %lu, %lu, %lu, %p, %#x, %lu, %p, %#lx )\n",
|
TRACE( "( %p, %p, %#x, %lu, %lu, %lu, %p, %#x, %lu, %p, %#lx )\n",
|
||||||
handle, srcbits, input, width, height, inputstride, destbits, output,
|
handle, srcbits, input, width, height, inputstride, destbits, output,
|
||||||
outputstride, callback, data );
|
outputstride, callback, data );
|
||||||
|
|
||||||
if (!transform) return FALSE;
|
if (!transform) return FALSE;
|
||||||
ret = cmsChangeBuffersFormat( transform, from_bmformat(input), from_bmformat(output) );
|
ret = cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) );
|
||||||
if (ret) cmsDoTransform( transform, srcbits, destbits, width * height );
|
if (ret) cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height );
|
||||||
release_transform( transform );
|
release_object( &transform->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,16 +325,16 @@ BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count,
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
cmsHTRANSFORM transform = grab_transform( handle );
|
struct transform *transform = (struct transform *)grab_object( handle, OBJECT_TYPE_TRANSFORM );
|
||||||
|
|
||||||
TRACE( "( %p, %p, %lu, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
|
TRACE( "( %p, %p, %lu, %d, %p, %d )\n", handle, in, count, input_type, out, output_type );
|
||||||
|
|
||||||
if (!transform) return FALSE;
|
if (!transform) return FALSE;
|
||||||
|
|
||||||
ret = cmsChangeBuffersFormat( transform, from_type(input_type), from_type(output_type) );
|
ret = cmsChangeBuffersFormat( transform->cmstransform, from_type(input_type), from_type(output_type) );
|
||||||
if (ret)
|
if (ret)
|
||||||
for (i = 0; i < count; i++) cmsDoTransform( transform, &in[i], &out[i], 1 );
|
for (i = 0; i < count; i++) cmsDoTransform( transform->cmstransform, &in[i], &out[i], 1 );
|
||||||
|
|
||||||
release_transform( transform );
|
release_object( &transform->hdr );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue