Infrastructure for handling ICC profiles.
Always load color profiles into memory. Implement and test GetColorProfileElement and GetColorProfileHeader. Implement GetColorProfileFromHandle and SetColorProfileHeader.
This commit is contained in:
parent
880bc9ce9f
commit
7c98f01159
|
@ -41,15 +41,16 @@ static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug =
|
|||
};
|
||||
static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 };
|
||||
|
||||
/* A simple structure to tie together Windows file handles and lcms color
|
||||
* profile handles. Windows color profile handles are built from indexes
|
||||
* into an array of these structures. The 'file' field is set to NULL in
|
||||
* case of a memory based profile
|
||||
/* 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 NULL.
|
||||
*/
|
||||
|
||||
struct handlemap
|
||||
{
|
||||
HANDLE file;
|
||||
icProfile *iccprofile;
|
||||
cmsHPROFILE cmsprofile;
|
||||
};
|
||||
|
||||
|
@ -57,12 +58,50 @@ struct handlemap
|
|||
|
||||
static struct handlemap handlemaptable[CMSMAXHANDLES];
|
||||
|
||||
HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
|
||||
HPROFILE MSCMS_handle2hprofile( HANDLE file )
|
||||
{
|
||||
HPROFILE ret = NULL;
|
||||
HPROFILE profile = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (!cmsprofile) return ret;
|
||||
if (!file) return NULL;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
||||
{
|
||||
if (handlemaptable[i].file == file)
|
||||
{
|
||||
profile = (HPROFILE)(i + 1); goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
|
||||
{
|
||||
HANDLE file;
|
||||
unsigned int i;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
i = (unsigned int)profile - 1;
|
||||
file = handlemaptable[i].file;
|
||||
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
|
||||
{
|
||||
HPROFILE profile = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (!cmsprofile) return NULL;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
|
@ -70,70 +109,94 @@ HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile )
|
|||
{
|
||||
if (handlemaptable[i].cmsprofile == cmsprofile)
|
||||
{
|
||||
ret = (HPROFILE)(i + 1); goto out;
|
||||
profile = (HPROFILE)(i + 1); goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return ret;
|
||||
return profile;
|
||||
}
|
||||
|
||||
cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile )
|
||||
{
|
||||
HANDLE ret;
|
||||
cmsHPROFILE cmshprofile;
|
||||
unsigned int i;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
i = (unsigned int)profile - 1;
|
||||
ret = handlemaptable[i].cmsprofile;
|
||||
cmshprofile = handlemaptable[i].cmsprofile;
|
||||
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return ret;
|
||||
return cmshprofile;
|
||||
}
|
||||
|
||||
HANDLE MSCMS_hprofile2handle( HPROFILE profile )
|
||||
HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile )
|
||||
{
|
||||
HANDLE ret;
|
||||
HPROFILE profile = NULL;
|
||||
unsigned int i;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
i = (unsigned int)profile - 1;
|
||||
ret = handlemaptable[i].file;
|
||||
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, cmsHPROFILE cmsprofile )
|
||||
{
|
||||
HPROFILE ret = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (!cmsprofile) return ret;
|
||||
if (!iccprofile) return NULL;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
||||
{
|
||||
if (handlemaptable[i].cmsprofile == 0)
|
||||
if (handlemaptable[i].iccprofile == iccprofile)
|
||||
{
|
||||
handlemaptable[i].file = file;
|
||||
handlemaptable[i].cmsprofile = cmsprofile;
|
||||
|
||||
ret = (HPROFILE)(i + 1); goto out;
|
||||
profile = (HPROFILE)(i + 1); goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return ret;
|
||||
return profile;
|
||||
}
|
||||
|
||||
icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile )
|
||||
{
|
||||
icProfile *iccprofile;
|
||||
unsigned int i;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
i = (unsigned int)profile - 1;
|
||||
iccprofile = handlemaptable[i].iccprofile;
|
||||
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return iccprofile;
|
||||
}
|
||||
|
||||
HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile )
|
||||
{
|
||||
HPROFILE profile = NULL;
|
||||
unsigned int i;
|
||||
|
||||
if (!cmsprofile || !iccprofile) return NULL;
|
||||
|
||||
EnterCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
for (i = 0; i <= CMSMAXHANDLES; i++)
|
||||
{
|
||||
if (handlemaptable[i].iccprofile == 0)
|
||||
{
|
||||
handlemaptable[i].file = file;
|
||||
handlemaptable[i].iccprofile = iccprofile;
|
||||
handlemaptable[i].cmsprofile = cmsprofile;
|
||||
|
||||
profile = (HPROFILE)(i + 1); goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
LeaveCriticalSection( &MSCMS_handle_cs );
|
||||
|
||||
return profile;
|
||||
}
|
||||
|
||||
void MSCMS_destroy_hprofile_handle( HPROFILE profile )
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
@ stub GetCMMInfo
|
||||
@ stdcall GetColorDirectoryA(ptr ptr long)
|
||||
@ stdcall GetColorDirectoryW(ptr ptr long)
|
||||
@ stub GetColorProfileElement
|
||||
@ stdcall GetColorProfileElement(ptr long long ptr ptr ptr)
|
||||
@ stdcall GetColorProfileElementTag(ptr long ptr)
|
||||
@ stub GetColorProfileFromHandle
|
||||
@ stub GetColorProfileHeader
|
||||
@ stdcall GetColorProfileFromHandle(ptr ptr ptr)
|
||||
@ stdcall GetColorProfileHeader(ptr ptr)
|
||||
@ stdcall GetCountColorProfileElements(ptr long)
|
||||
@ stub GetNamedProfileInfo
|
||||
@ stub GetPS2ColorRenderingDictionary
|
||||
|
@ -49,7 +49,7 @@
|
|||
@ stub SetColorProfileElement
|
||||
@ stub SetColorProfileElementReference
|
||||
@ stub SetColorProfileElementSize
|
||||
@ stub SetColorProfileHeader
|
||||
@ stdcall SetColorProfileHeader(ptr ptr)
|
||||
@ stub SetStandardColorSpaceProfileA
|
||||
@ stub SetStandardColorSpaceProfileW
|
||||
@ stub SpoolerCopyFileEvent
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifdef HAVE_LCMS_H
|
||||
|
||||
/* These basic Windows types are defined in lcms.h when compiling on
|
||||
* a non-Windows platforms (why?), so they would normally not conflict
|
||||
* a non-Windows platform (why?), so they would normally not conflict
|
||||
* with anything included earlier. But since we are building Wine they
|
||||
* most certainly will have been defined before we include lcms.h.
|
||||
* The preprocessor comes to the rescue.
|
||||
|
@ -68,11 +68,14 @@
|
|||
#define DWORD DWORD
|
||||
#define LPDWORD LPDWORD
|
||||
|
||||
extern HPROFILE MSCMS_handle2hprofile( HANDLE file );
|
||||
extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile );
|
||||
extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile );
|
||||
extern HPROFILE MSCMS_iccprofile2hprofile( 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, cmsHPROFILE cmsprofile );
|
||||
extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile );
|
||||
extern void MSCMS_destroy_hprofile_handle( HPROFILE profile );
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
|
|
|
@ -44,6 +44,144 @@ static void MSCMS_basename( LPCWSTR path, LPWSTR name )
|
|||
lstrcpyW( name, &path[i] );
|
||||
}
|
||||
|
||||
#ifdef HAVE_LCMS_H
|
||||
static BOOL MSCMS_cpu_is_little_endian()
|
||||
{
|
||||
long l = 1;
|
||||
void *p = &l;
|
||||
char b = *(char *)p;
|
||||
|
||||
return b ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static void MSCMS_endian_swap16( BYTE *byte )
|
||||
{
|
||||
BYTE tmp;
|
||||
|
||||
tmp = byte[0];
|
||||
byte[0] = byte[1];
|
||||
byte[1] = tmp;
|
||||
}
|
||||
|
||||
static void MSCMS_endian_swap32( BYTE *byte )
|
||||
{
|
||||
BYTE tmp1, tmp2;
|
||||
|
||||
tmp1 = *byte++;
|
||||
tmp2 = *byte++;
|
||||
|
||||
*(byte - 1) = *byte;
|
||||
*byte++ = tmp2;
|
||||
*(byte - 3) = *byte;
|
||||
*byte = tmp1;
|
||||
}
|
||||
|
||||
static void MSCMS_adjust_endianess32( BYTE *byte )
|
||||
{
|
||||
if (MSCMS_cpu_is_little_endian())
|
||||
MSCMS_endian_swap32( byte );
|
||||
}
|
||||
|
||||
static void MSCMS_get_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
|
||||
{
|
||||
memcpy( header, iccprofile, sizeof(PROFILEHEADER) );
|
||||
|
||||
/* ICC format is big-endian, swap bytes if necessary */
|
||||
|
||||
if (MSCMS_cpu_is_little_endian())
|
||||
{
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phSize );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phCMMType );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phVersion );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phClass );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phDataColorSpace );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phConnectionSpace );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[0] );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[1] );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phDateTime[2] );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phSignature );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phPlatform );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phProfileFlags );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phManufacturer );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phModel );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phAttributes[0] );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phAttributes[1] );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phRenderingIntent );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phIlluminant );
|
||||
MSCMS_endian_swap32( (BYTE *)&header->phCreator );
|
||||
}
|
||||
}
|
||||
|
||||
static void MSCMS_set_profile_header( icProfile *iccprofile, PROFILEHEADER *header )
|
||||
{
|
||||
icHeader *iccheader = (icHeader *)iccprofile;
|
||||
|
||||
memcpy( iccprofile, header, sizeof(PROFILEHEADER) );
|
||||
|
||||
/* ICC format is big-endian, swap bytes if necessary */
|
||||
|
||||
if (MSCMS_cpu_is_little_endian())
|
||||
{
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->size );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->cmmId );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->version );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->deviceClass );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->colorSpace );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->pcs );
|
||||
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.year );
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.month );
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.day );
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.hours );
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.minutes );
|
||||
MSCMS_endian_swap16( (BYTE *)&iccheader->date.seconds );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->magic );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->platform );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->flags );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->manufacturer );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->model );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->attributes[0] );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->attributes[1] );
|
||||
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->renderingIntent );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->illuminant );
|
||||
MSCMS_endian_swap32( (BYTE *)&iccheader->creator );
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD MSCMS_get_tag_count( icProfile *iccprofile )
|
||||
{
|
||||
DWORD count = iccprofile->count;
|
||||
|
||||
MSCMS_adjust_endianess32( (BYTE *)&count );
|
||||
return count;
|
||||
}
|
||||
|
||||
static void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag )
|
||||
{
|
||||
icTag *tmp = (icTag *)&iccprofile->data + (index * sizeof(icTag));
|
||||
|
||||
tag->sig = tmp->sig;
|
||||
tag->offset = tmp->offset;
|
||||
tag->size = tmp->size;
|
||||
|
||||
MSCMS_adjust_endianess32( (BYTE *)&tag->sig );
|
||||
MSCMS_adjust_endianess32( (BYTE *)&tag->offset );
|
||||
MSCMS_adjust_endianess32( (BYTE *)&tag->size );
|
||||
}
|
||||
|
||||
static void MSCMS_get_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, void *buffer )
|
||||
{
|
||||
memcpy( buffer, (char *)iccprofile + tag->offset + offset, tag->size - offset );
|
||||
}
|
||||
#endif /* HAVE_LCMS_H */
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mscms);
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -117,6 +255,43 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset, PDWORD size,
|
||||
PVOID buffer, PBOOL ref )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
DWORD i, count;
|
||||
icTag tag;
|
||||
|
||||
TRACE( "( %p, 0x%08lx, %ld, %p, %p, %p )\n", profile, type, offset, size, buffer, ref );
|
||||
|
||||
if (!iccprofile || !ref) return FALSE;
|
||||
count = MSCMS_get_tag_count( iccprofile );
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
MSCMS_get_tag_by_index( iccprofile, i, &tag );
|
||||
|
||||
if (tag.sig == type)
|
||||
{
|
||||
if ((tag.size - offset) > *size || !buffer)
|
||||
{
|
||||
*size = (tag.size - offset);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MSCMS_get_tag_data( iccprofile, &tag, offset, buffer );
|
||||
|
||||
*ref = FALSE; /* FIXME: calculate properly */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* GetColorProfileElementTag [MSCMS.@]
|
||||
*
|
||||
|
@ -135,20 +310,69 @@ BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size )
|
|||
* The tag table index starts at 1.
|
||||
* Use GetCountColorProfileElements to retrieve a count of tagged elements.
|
||||
*/
|
||||
BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE tag )
|
||||
BOOL WINAPI GetColorProfileElementTag( HPROFILE profile, DWORD index, PTAGTYPE type )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
LCMSICCPROFILE *cmsprofile = (LCMSICCPROFILE *)MSCMS_hprofile2cmsprofile( profile );
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
DWORD count;
|
||||
icTag tag;
|
||||
|
||||
TRACE( "( %p, %ld, %p )\n", profile, index, tag );
|
||||
TRACE( "( %p, %ld, %p )\n", profile, index, type );
|
||||
|
||||
if (cmsprofile)
|
||||
if (!iccprofile) return FALSE;
|
||||
|
||||
count = MSCMS_get_tag_count( iccprofile );
|
||||
if (index > count) return FALSE;
|
||||
|
||||
MSCMS_get_tag_by_index( iccprofile, index - 1, &tag );
|
||||
*type = tag.sig;
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetColorProfileFromHandle( HPROFILE profile, PBYTE buffer, PDWORD size )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
PROFILEHEADER header;
|
||||
|
||||
TRACE( "( %p, %p, %p )\n", profile, buffer, size );
|
||||
|
||||
if (!iccprofile) return FALSE;
|
||||
MSCMS_get_profile_header( profile, &header );
|
||||
|
||||
if (!buffer || header.phSize > *size)
|
||||
{
|
||||
*tag = cmsprofile->TagNames[index - 1];
|
||||
ret = TRUE;
|
||||
*size = header.phSize;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIXME: no endian conversion */
|
||||
memcpy( buffer, iccprofile, header.phSize );
|
||||
ret = TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI GetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
|
||||
TRACE( "( %p, %p )\n", profile, header );
|
||||
|
||||
if (!iccprofile || !header) return FALSE;
|
||||
|
||||
MSCMS_get_profile_header( iccprofile, header );
|
||||
return TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
@ -171,15 +395,13 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE profile, PDWORD count )
|
|||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
LCMSICCPROFILE *cmsprofile = (LCMSICCPROFILE *)MSCMS_hprofile2cmsprofile( profile );
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
|
||||
TRACE( "( %p, %p )\n", profile, count );
|
||||
|
||||
if (cmsprofile)
|
||||
{
|
||||
*count = cmsprofile->TagCount;
|
||||
ret = TRUE;
|
||||
}
|
||||
if (!count) return FALSE;
|
||||
*count = MSCMS_get_tag_count( iccprofile );
|
||||
ret = TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
|
@ -307,6 +529,8 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE tag, PBOOL prese
|
|||
|
||||
TRACE( "( %p, 0x%08lx, %p )\n", profile, tag, present );
|
||||
|
||||
if (!present) return FALSE;
|
||||
|
||||
#ifdef HAVE_LCMS_H
|
||||
ret = cmsIsTag( MSCMS_hprofile2cmsprofile( profile ), tag );
|
||||
|
||||
|
@ -330,9 +554,34 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE profile, TAGTYPE tag, PBOOL prese
|
|||
*/
|
||||
BOOL WINAPI IsColorProfileValid( HPROFILE profile, PBOOL valid )
|
||||
{
|
||||
FIXME( "( %p, %p ) stub\n", profile, valid );
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
|
||||
return *valid = TRUE;
|
||||
TRACE( "( %p, %p )\n", profile, valid );
|
||||
|
||||
if (!valid) return FALSE;
|
||||
if (iccprofile) return *valid = TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header )
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
#ifdef HAVE_LCMS_H
|
||||
icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile );
|
||||
|
||||
TRACE( "( %p, %p )\n", profile, header );
|
||||
|
||||
if (!iccprofile || !header) return FALSE;
|
||||
|
||||
MSCMS_set_profile_header( iccprofile, header );
|
||||
return TRUE;
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -385,8 +634,7 @@ BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete
|
|||
|
||||
if (machine || !profile) return FALSE;
|
||||
|
||||
if (delete)
|
||||
return DeleteFileW( profile );
|
||||
if (delete) return DeleteFileW( profile );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -450,12 +698,15 @@ HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing
|
|||
* Values for sharing: 0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE.
|
||||
* Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING,
|
||||
* OPEN_ALWAYS, TRUNCATE_EXISTING.
|
||||
* Sharing and creation flags are ignored for memory based profiles.
|
||||
*/
|
||||
HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation )
|
||||
{
|
||||
#ifdef HAVE_LCMS_H
|
||||
cmsHPROFILE cmsprofile = NULL;
|
||||
icProfile *iccprofile = NULL;
|
||||
HANDLE handle = NULL;
|
||||
DWORD size;
|
||||
|
||||
TRACE( "( %p, 0x%08lx, 0x%08lx, 0x%08lx )\n", profile, access, sharing, creation );
|
||||
|
||||
|
@ -463,15 +714,19 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
|||
|
||||
if (profile->dwType & PROFILE_MEMBUFFER)
|
||||
{
|
||||
FIXME( "Memory based profile not yet supported.\n" ); return NULL;
|
||||
FIXME( "access flags not implemented for memory based profiles\n" );
|
||||
|
||||
iccprofile = profile->pProfileData;
|
||||
size = profile->cbDataSize;
|
||||
|
||||
cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
|
||||
}
|
||||
|
||||
if (profile->dwType & PROFILE_FILENAME)
|
||||
{
|
||||
char *unixname;
|
||||
DWORD flags = 0;
|
||||
DWORD read, flags = 0;
|
||||
|
||||
TRACE("profile file: %s\n", debugstr_w( (WCHAR *)profile->pProfileData ));
|
||||
TRACE( "profile file: %s\n", debugstr_w( (WCHAR *)profile->pProfileData ) );
|
||||
|
||||
if (access & PROFILE_READ) flags = GENERIC_READ;
|
||||
if (access & PROFILE_READWRITE) flags = GENERIC_READ|GENERIC_WRITE;
|
||||
|
@ -479,18 +734,41 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
|||
if (!flags) return NULL;
|
||||
|
||||
handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL );
|
||||
if (handle == INVALID_HANDLE_VALUE) return NULL;
|
||||
|
||||
unixname = wine_get_unix_file_name( (WCHAR *)profile->pProfileData );
|
||||
|
||||
if (unixname)
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
cmsprofile = cmsOpenProfileFromFile( unixname, flags & GENERIC_READ ? "r" : "w" );
|
||||
HeapFree( GetProcessHeap(), 0, unixname );
|
||||
WARN( "Unable to open color profile\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE)
|
||||
{
|
||||
ERR( "Unable to retrieve size of color profile\n" );
|
||||
CloseHandle( handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iccprofile = (icProfile *)HeapAlloc( GetProcessHeap(), 0, size );
|
||||
if (!iccprofile)
|
||||
{
|
||||
ERR( "Unable to allocate memory for color profile\n" );
|
||||
CloseHandle( handle );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ReadFile( handle, iccprofile, size, &read, NULL ) || read != size)
|
||||
{
|
||||
ERR( "Unable to read color profile\n" );
|
||||
|
||||
CloseHandle( handle );
|
||||
HeapFree( GetProcessHeap, 0, iccprofile );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cmsprofile = cmsOpenProfileFromMem( iccprofile, size );
|
||||
}
|
||||
|
||||
if (cmsprofile) return MSCMS_create_hprofile_handle( handle, cmsprofile );
|
||||
if (cmsprofile)
|
||||
return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile );
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return NULL;
|
||||
|
@ -510,16 +788,18 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing
|
|||
*/
|
||||
BOOL WINAPI CloseColorProfile( HPROFILE profile )
|
||||
{
|
||||
BOOL ret1, ret2 = FALSE;
|
||||
BOOL ret = FALSE;
|
||||
|
||||
TRACE( "( %p )\n", profile );
|
||||
|
||||
#ifdef HAVE_LCMS_H
|
||||
ret1 = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
|
||||
ret2 = CloseHandle( MSCMS_hprofile2handle( profile ) );
|
||||
ret = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, MSCMS_hprofile2iccprofile( profile ) );
|
||||
CloseHandle( MSCMS_hprofile2handle( profile ) );
|
||||
|
||||
MSCMS_destroy_hprofile_handle( profile );
|
||||
|
||||
#endif /* HAVE_LCMS_H */
|
||||
return ret1 && ret2;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -144,6 +144,46 @@ static void test_GetColorDirectoryW()
|
|||
ok( ret, "GetColorDirectoryW() failed (%ld)\n", GetLastError() );
|
||||
}
|
||||
|
||||
static void test_GetColorProfileElement()
|
||||
{
|
||||
if (standardprofile)
|
||||
{
|
||||
PROFILE profile;
|
||||
HPROFILE handle;
|
||||
BOOL ret, ref;
|
||||
DWORD size;
|
||||
TAGTYPE tag = 0x63707274; /* 'cprt' */
|
||||
static char buffer[51];
|
||||
static char expect[] =
|
||||
{ 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6f, 0x70,
|
||||
0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20,
|
||||
0x31, 0x39, 0x39, 0x38, 0x20, 0x48, 0x65, 0x77, 0x6c, 0x65, 0x74,
|
||||
0x74, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x72, 0x64, 0x20, 0x43,
|
||||
0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x00 };
|
||||
|
||||
profile.dwType = PROFILE_FILENAME;
|
||||
profile.pProfileData = standardprofile;
|
||||
profile.cbDataSize = strlen(standardprofile);
|
||||
|
||||
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
|
||||
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
|
||||
|
||||
size = 0;
|
||||
|
||||
ret = GetColorProfileElement( handle, tag, 0, &size, NULL, &ref );
|
||||
ok( !ret, "GetColorProfileElement() succeeded (%ld)\n", GetLastError() );
|
||||
|
||||
size = sizeof(buffer);
|
||||
|
||||
ret = GetColorProfileElement( handle, tag, 0, &size, buffer, &ref );
|
||||
ok( ret, "GetColorProfileElement() failed (%ld)\n", GetLastError() );
|
||||
|
||||
ok( !memcmp( buffer, expect, sizeof(expect) ), "Unexpected tag data\n" );
|
||||
|
||||
CloseColorProfile( handle );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_GetColorProfileElementTag()
|
||||
{
|
||||
if (standardprofile)
|
||||
|
@ -162,7 +202,39 @@ static void test_GetColorProfileElementTag()
|
|||
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
|
||||
|
||||
ret = GetColorProfileElementTag( handle, index, &tag );
|
||||
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld)\n", GetLastError() );
|
||||
ok( ret && tag == expect, "GetColorProfileElementTag() failed (%ld) 0x%08lx\n",
|
||||
GetLastError(), tag );
|
||||
|
||||
CloseColorProfile( handle );
|
||||
}
|
||||
}
|
||||
|
||||
static void test_GetColorProfileHeader()
|
||||
{
|
||||
if (testprofile)
|
||||
{
|
||||
PROFILE profile;
|
||||
HPROFILE handle;
|
||||
BOOL ret;
|
||||
static PROFILEHEADER header;
|
||||
static PROFILEHEADER expect =
|
||||
{ 0x00000c48, 0x4c696e6f, 0x02100000, 0x6d6e7472, 0x52474220, 0x58595a20,
|
||||
{ 0x07ce0002, 0x00090006, 0x61637370 }, 0x61637370, 0x4d534654, 0x00000000,
|
||||
0x49454320, 0x73524742, { 0x00000000, 0x00000000 }, 0x00000000, { 0x0000f6d6,
|
||||
0x00000100, 0x2dd30000 }, 0x48502020 };
|
||||
|
||||
profile.dwType = PROFILE_FILENAME;
|
||||
profile.pProfileData = testprofile;
|
||||
profile.cbDataSize = strlen(testprofile);
|
||||
|
||||
handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING );
|
||||
ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() );
|
||||
|
||||
ret = GetColorProfileHeader( handle, &header );
|
||||
ok( ret, "GetColorProfileHeader() failed (%ld)\n", GetLastError() );
|
||||
|
||||
ok( memcmp( &header, &expect, FIELD_OFFSET(PROFILEHEADER, phReserved) ),
|
||||
"Unexpected header data\n" );
|
||||
|
||||
CloseColorProfile( handle );
|
||||
}
|
||||
|
@ -549,7 +621,10 @@ START_TEST(profile)
|
|||
test_GetColorDirectoryA();
|
||||
test_GetColorDirectoryW();
|
||||
|
||||
test_GetColorProfileElement();
|
||||
test_GetColorProfileElementTag();
|
||||
|
||||
test_GetColorProfileHeader();
|
||||
test_GetCountColorProfileElements();
|
||||
|
||||
test_InstallColorProfileA();
|
||||
|
|
|
@ -87,7 +87,7 @@ typedef struct tagPROFILEHEADER
|
|||
DWORD phProfileFlags;
|
||||
DWORD phManufacturer;
|
||||
DWORD phModel;
|
||||
DWORD phAttributes;
|
||||
DWORD phAttributes[2];
|
||||
DWORD phRenderingIntent;
|
||||
CIEXYZ phIlluminant;
|
||||
DWORD phCreator;
|
||||
|
@ -160,6 +160,7 @@ BOOL WINAPI GetColorDirectoryW(PCWSTR,PWSTR,PDWORD);
|
|||
#define GetColorDirectory WINELIB_NAME_AW(GetColorDirectory)
|
||||
BOOL WINAPI GetColorProfileElement(HPROFILE,TAGTYPE,DWORD,PDWORD,PVOID,PBOOL);
|
||||
BOOL WINAPI GetColorProfileElementTag(HPROFILE,DWORD,PTAGTYPE);
|
||||
BOOL WINAPI GetColorProfileHeader(HPROFILE,PPROFILEHEADER);
|
||||
BOOL WINAPI GetCountColorProfileElements(HPROFILE,PDWORD);
|
||||
BOOL WINAPI GetStandardColorSpaceProfileA(PCSTR,DWORD,PSTR,PDWORD);
|
||||
BOOL WINAPI GetStandardColorSpaceProfileW(PCWSTR,DWORD,PWSTR,PDWORD);
|
||||
|
@ -172,6 +173,7 @@ BOOL WINAPI IsColorProfileValid(HPROFILE,PBOOL);
|
|||
HPROFILE WINAPI OpenColorProfileA(PPROFILE,DWORD,DWORD,DWORD);
|
||||
HPROFILE WINAPI OpenColorProfileW(PPROFILE,DWORD,DWORD,DWORD);
|
||||
#define OpenColorProfile WINELIB_NAME_AW(OpenColorProfile)
|
||||
BOOL WINAPI SetColorProfileHeader(HPROFILE,PPROFILEHEADER);
|
||||
BOOL WINAPI SetupColorMatchingA(PCOLORMATCHSETUPA);
|
||||
BOOL WINAPI SetupColorMatchingW(PCOLORMATCHSETUPW);
|
||||
#define SetupColorMatching WINELIB_NAME_AW(SetupColorMatching)
|
||||
|
|
Loading…
Reference in New Issue