Commit 881dad65 authored by Alexandre Julliard's avatar Alexandre Julliard

mscms: Implement profile tag functions without relying on liblcms2.

parent dd51cd8d
...@@ -40,6 +40,11 @@ static inline void adjust_endianness32( ULONG *ptr ) ...@@ -40,6 +40,11 @@ static inline void adjust_endianness32( ULONG *ptr )
#endif #endif
} }
static const struct tag_entry *first_tag( const struct profile *profile )
{
return (const struct tag_entry *)(profile->data + sizeof(PROFILEHEADER) + sizeof(DWORD));
}
void get_profile_header( const struct profile *profile, PROFILEHEADER *header ) void get_profile_header( const struct profile *profile, PROFILEHEADER *header )
{ {
unsigned int i; unsigned int i;
...@@ -62,34 +67,77 @@ void set_profile_header( const struct profile *profile, const PROFILEHEADER *hea ...@@ -62,34 +67,77 @@ void set_profile_header( const struct profile *profile, const PROFILEHEADER *hea
adjust_endianness32( (ULONG *)profile->data + i ); adjust_endianness32( (ULONG *)profile->data + i );
} }
static BOOL get_adjusted_tag( const struct profile *profile, TAGTYPE type, cmsTagEntry *tag ) DWORD get_tag_count( const struct profile *profile )
{ {
DWORD i, num_tags = *(DWORD *)(profile->data + sizeof(cmsICCHeader)); DWORD num_tags = *(DWORD *)(profile->data + sizeof(PROFILEHEADER));
cmsTagEntry *entry;
ULONG sig;
adjust_endianness32( &num_tags ); adjust_endianness32( &num_tags );
for (i = 0; i < num_tags; i++) if ((const BYTE *)(first_tag( profile ) + num_tags) > (const BYTE *)profile->data + profile->size)
return 0;
return num_tags;
}
BOOL get_tag_entry( const struct profile *profile, DWORD index, struct tag_entry *tag )
{
const struct tag_entry *entry = first_tag( profile );
if (index < 1 || index > get_tag_count( profile )) return FALSE;
*tag = entry[index - 1];
adjust_endianness32( &tag->sig );
adjust_endianness32( &tag->offset );
adjust_endianness32( &tag->size );
if (tag->offset > profile->size || tag->size > profile->size - tag->offset) return FALSE;
return TRUE;
}
BOOL get_adjusted_tag( const struct profile *profile, TAGTYPE type, struct tag_entry *tag )
{
const struct tag_entry *entry = first_tag( profile );
DWORD sig, i;
for (i = get_tag_count(profile); i > 0; i--, entry++)
{ {
entry = (cmsTagEntry *)(profile->data + sizeof(cmsICCHeader) + sizeof(DWORD) + i * sizeof(*tag));
sig = entry->sig; sig = entry->sig;
adjust_endianness32( &sig ); adjust_endianness32( &sig );
if (sig == type) if (sig == type)
{ {
tag->sig = sig; *tag = *entry;
tag->offset = entry->offset; adjust_endianness32( &tag->sig );
tag->size = entry->size;
adjust_endianness32( &tag->offset ); adjust_endianness32( &tag->offset );
adjust_endianness32( &tag->size ); adjust_endianness32( &tag->size );
if (tag->offset > profile->size || tag->size > profile->size - tag->offset) return FALSE;
return TRUE;
}
}
return FALSE;
}
static BOOL get_linked_tag( const struct profile *profile, struct tag_entry *ret )
{
const struct tag_entry *entry = first_tag( profile );
DWORD sig, offset, size, i;
for (i = get_tag_count(profile); i > 0; i--, entry++)
{
sig = entry->sig;
adjust_endianness32( &sig );
if (sig == ret->sig) continue;
offset = entry->offset;
size = entry->size;
adjust_endianness32( &offset );
adjust_endianness32( &size );
if (size == ret->size && offset == ret->offset)
{
ret->sig = sig;
return TRUE; return TRUE;
} }
} }
return FALSE; return FALSE;
} }
BOOL get_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, void *buffer, DWORD *len ) BOOL get_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, void *buffer,
DWORD *len, BOOL *linked )
{ {
cmsTagEntry tag; struct tag_entry tag;
if (!get_adjusted_tag( profile, type, &tag )) return FALSE; if (!get_adjusted_tag( profile, type, &tag )) return FALSE;
...@@ -102,12 +150,13 @@ BOOL get_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, vo ...@@ -102,12 +150,13 @@ BOOL get_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, vo
} }
memcpy( buffer, profile->data + tag.offset + offset, tag.size - offset ); memcpy( buffer, profile->data + tag.offset + offset, tag.size - offset );
*len = tag.size - offset; *len = tag.size - offset;
if (linked) *linked = get_linked_tag( profile, &tag );
return TRUE; return TRUE;
} }
BOOL set_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, const void *buffer, DWORD *len ) BOOL set_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, const void *buffer, DWORD *len )
{ {
cmsTagEntry tag; struct tag_entry tag;
if (!get_adjusted_tag( profile, type, &tag )) return FALSE; if (!get_adjusted_tag( profile, type, &tag )) return FALSE;
......
...@@ -56,7 +56,17 @@ void release_transform( struct transform * ) DECLSPEC_HIDDEN; ...@@ -56,7 +56,17 @@ void release_transform( struct transform * ) DECLSPEC_HIDDEN;
extern void free_handle_tables( void ) DECLSPEC_HIDDEN; extern void free_handle_tables( void ) DECLSPEC_HIDDEN;
extern BOOL get_tag_data( const struct profile *, TAGTYPE, DWORD, void *, DWORD * ) DECLSPEC_HIDDEN; struct tag_entry
{
DWORD sig;
DWORD offset;
DWORD size;
};
extern DWORD get_tag_count( const struct profile * ) DECLSPEC_HIDDEN;
extern BOOL get_tag_entry( const struct profile *, DWORD, struct tag_entry * ) DECLSPEC_HIDDEN;
extern BOOL get_adjusted_tag( const struct profile *, TAGTYPE, struct tag_entry * ) DECLSPEC_HIDDEN;
extern BOOL get_tag_data( const struct profile *, TAGTYPE, DWORD, void *, DWORD *, BOOL * ) DECLSPEC_HIDDEN;
extern BOOL set_tag_data( const struct profile *, TAGTYPE, DWORD, const void *, DWORD * ) DECLSPEC_HIDDEN; extern BOOL set_tag_data( const struct profile *, TAGTYPE, DWORD, const void *, DWORD * ) DECLSPEC_HIDDEN;
extern void get_profile_header( const struct profile *, PROFILEHEADER * ) DECLSPEC_HIDDEN; extern void get_profile_header( const struct profile *, PROFILEHEADER * ) DECLSPEC_HIDDEN;
extern void set_profile_header( const struct profile *, const PROFILEHEADER * ) DECLSPEC_HIDDEN; extern void set_profile_header( const struct profile *, const PROFILEHEADER * ) DECLSPEC_HIDDEN;
......
...@@ -347,13 +347,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, ...@@ -347,13 +347,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset,
release_profile( profile ); release_profile( profile );
return FALSE; return FALSE;
} }
if (!get_tag_data( profile, type, offset, buffer, size )) ret = get_tag_data( profile, type, offset, buffer, size, ref );
{
release_profile( profile );
return FALSE;
}
ret = get_tag_data( profile, type, offset, buffer, size );
*ref = cmsTagLinkedTo( profile->cmsprofile, type ) != 0;
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */ #endif /* HAVE_LCMS2 */
return ret; return ret;
...@@ -382,8 +376,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty ...@@ -382,8 +376,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty
BOOL ret = FALSE; BOOL ret = FALSE;
#ifdef HAVE_LCMS2 #ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
cmsInt32Number num_tags; struct tag_entry tag;
cmsTagSignature sig;
TRACE( "( %p, %d, %p )\n", handle, index, type ); TRACE( "( %p, %d, %p )\n", handle, index, type );
...@@ -394,17 +387,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty ...@@ -394,17 +387,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty
release_profile( profile ); release_profile( profile );
return FALSE; return FALSE;
} }
num_tags = cmsGetTagCount( profile->cmsprofile ); if ((ret = get_tag_entry( profile, index, &tag ))) *type = tag.sig;
if (num_tags < 0 || index > num_tags || index < 1)
{
release_profile( profile );
return FALSE;
}
if ((sig = cmsGetTagSignature( profile->cmsprofile, index - 1 )))
{
*type = sig;
ret = TRUE;
}
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */ #endif /* HAVE_LCMS2 */
...@@ -523,7 +506,6 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) ...@@ -523,7 +506,6 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
BOOL ret = FALSE; BOOL ret = FALSE;
#ifdef HAVE_LCMS2 #ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
cmsInt32Number num_tags;
TRACE( "( %p, %p )\n", handle, count ); TRACE( "( %p, %p )\n", handle, count );
...@@ -534,11 +516,7 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) ...@@ -534,11 +516,7 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count )
release_profile( profile ); release_profile( profile );
return FALSE; return FALSE;
} }
if ((num_tags = cmsGetTagCount( profile->cmsprofile )) >= 0) *count = get_tag_count( profile );
{
*count = num_tags;
ret = TRUE;
}
release_profile( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */ #endif /* HAVE_LCMS2 */
...@@ -1151,6 +1129,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese ...@@ -1151,6 +1129,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
BOOL ret = FALSE; BOOL ret = FALSE;
#ifdef HAVE_LCMS2 #ifdef HAVE_LCMS2
struct profile *profile = grab_profile( handle ); struct profile *profile = grab_profile( handle );
struct tag_entry tag;
TRACE( "( %p, 0x%08x, %p )\n", handle, type, present ); TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
...@@ -1161,7 +1140,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese ...@@ -1161,7 +1140,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese
release_profile( profile ); release_profile( profile );
return FALSE; return FALSE;
} }
*present = (cmsIsTag( profile->cmsprofile, type ) != 0); *present = get_adjusted_tag( profile, type, &tag );
release_profile( profile ); release_profile( profile );
ret = TRUE; ret = TRUE;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment