Module: wine Branch: master Commit: 881dad65035b5453184c9421dbb9685179a8366e URL: https://source.winehq.org/git/wine.git/?a=commit;h=881dad65035b5453184c9421d...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Nov 10 12:40:09 2020 +0100
mscms: Implement profile tag functions without relying on liblcms2.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/mscms/icc.c | 75 ++++++++++++++++++++++++++++++++++++++++--------- dlls/mscms/mscms_priv.h | 12 +++++++- dlls/mscms/profile.c | 33 ++++------------------ 3 files changed, 79 insertions(+), 41 deletions(-)
diff --git a/dlls/mscms/icc.c b/dlls/mscms/icc.c index 3b1c718b174..0476d805547 100644 --- a/dlls/mscms/icc.c +++ b/dlls/mscms/icc.c @@ -40,6 +40,11 @@ static inline void adjust_endianness32( ULONG *ptr ) #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 ) { unsigned int i; @@ -62,34 +67,77 @@ void set_profile_header( const struct profile *profile, const PROFILEHEADER *hea 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)); - cmsTagEntry *entry; - ULONG sig; - + DWORD num_tags = *(DWORD *)(profile->data + sizeof(PROFILEHEADER)); 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; adjust_endianness32( &sig ); if (sig == type) { - tag->sig = sig; - tag->offset = entry->offset; - tag->size = entry->size; + *tag = *entry; + 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; + } + } + 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 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;
@@ -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 ); *len = tag.size - offset; + if (linked) *linked = get_linked_tag( profile, &tag ); return TRUE; }
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;
diff --git a/dlls/mscms/mscms_priv.h b/dlls/mscms/mscms_priv.h index ffa2cb4b4c9..f085c5bfbd6 100644 --- a/dlls/mscms/mscms_priv.h +++ b/dlls/mscms/mscms_priv.h @@ -56,7 +56,17 @@ void release_transform( struct transform * ) 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 void get_profile_header( const struct profile *, PROFILEHEADER * ) DECLSPEC_HIDDEN; extern void set_profile_header( const struct profile *, const PROFILEHEADER * ) DECLSPEC_HIDDEN; diff --git a/dlls/mscms/profile.c b/dlls/mscms/profile.c index ed0ed53158a..0f31ae91155 100644 --- a/dlls/mscms/profile.c +++ b/dlls/mscms/profile.c @@ -347,13 +347,7 @@ BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, release_profile( profile ); return FALSE; } - if (!get_tag_data( profile, type, offset, buffer, size )) - { - release_profile( profile ); - return FALSE; - } - ret = get_tag_data( profile, type, offset, buffer, size ); - *ref = cmsTagLinkedTo( profile->cmsprofile, type ) != 0; + ret = get_tag_data( profile, type, offset, buffer, size, ref ); release_profile( profile ); #endif /* HAVE_LCMS2 */ return ret; @@ -382,8 +376,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty BOOL ret = FALSE; #ifdef HAVE_LCMS2 struct profile *profile = grab_profile( handle ); - cmsInt32Number num_tags; - cmsTagSignature sig; + struct tag_entry tag;
TRACE( "( %p, %d, %p )\n", handle, index, type );
@@ -394,17 +387,7 @@ BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE ty release_profile( profile ); return FALSE; } - num_tags = cmsGetTagCount( profile->cmsprofile ); - 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; - } + if ((ret = get_tag_entry( profile, index, &tag ))) *type = tag.sig; release_profile( profile );
#endif /* HAVE_LCMS2 */ @@ -523,7 +506,6 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) BOOL ret = FALSE; #ifdef HAVE_LCMS2 struct profile *profile = grab_profile( handle ); - cmsInt32Number num_tags;
TRACE( "( %p, %p )\n", handle, count );
@@ -534,11 +516,7 @@ BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) release_profile( profile ); return FALSE; } - if ((num_tags = cmsGetTagCount( profile->cmsprofile )) >= 0) - { - *count = num_tags; - ret = TRUE; - } + *count = get_tag_count( profile ); release_profile( profile );
#endif /* HAVE_LCMS2 */ @@ -1151,6 +1129,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese BOOL ret = FALSE; #ifdef HAVE_LCMS2 struct profile *profile = grab_profile( handle ); + struct tag_entry tag;
TRACE( "( %p, 0x%08x, %p )\n", handle, type, present );
@@ -1161,7 +1140,7 @@ BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL prese release_profile( profile ); return FALSE; } - *present = (cmsIsTag( profile->cmsprofile, type ) != 0); + *present = get_adjusted_tag( profile, type, &tag ); release_profile( profile ); ret = TRUE;