Alexandre Julliard : mscms: Implement profile tag functions without relying on liblcms2.

Alexandre Julliard julliard at winehq.org
Tue Nov 10 15:30:24 CST 2020


Module: wine
Branch: master
Commit: 881dad65035b5453184c9421dbb9685179a8366e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=881dad65035b5453184c9421dbb9685179a8366e

Author: Alexandre Julliard <julliard at 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 at 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;
 




More information about the wine-cvs mailing list