| /* |
| * MSCMS - Color Management System for Wine |
| * |
| * Copyright 2004, 2005 Hans Leidekker |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| |
| #include <stdarg.h> |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winternl.h" |
| #include "icm.h" |
| |
| #include "mscms_priv.h" |
| |
| #ifdef HAVE_LCMS2 |
| |
| static inline void adjust_endianness32( ULONG *ptr ) |
| { |
| #ifndef WORDS_BIGENDIAN |
| *ptr = RtlUlongByteSwap(*ptr); |
| #endif |
| } |
| |
| void get_profile_header( const struct profile *profile, PROFILEHEADER *header ) |
| { |
| unsigned int i; |
| |
| memcpy( header, profile->data, sizeof(PROFILEHEADER) ); |
| |
| /* ICC format is big-endian, swap bytes if necessary */ |
| for (i = 0; i < sizeof(PROFILEHEADER) / sizeof(ULONG); i++) |
| adjust_endianness32( (ULONG *)header + i ); |
| } |
| |
| void set_profile_header( const struct profile *profile, const PROFILEHEADER *header ) |
| { |
| unsigned int i; |
| |
| memcpy( profile->data, header, sizeof(PROFILEHEADER) ); |
| |
| /* ICC format is big-endian, swap bytes if necessary */ |
| for (i = 0; i < sizeof(PROFILEHEADER) / sizeof(ULONG); i++) |
| adjust_endianness32( (ULONG *)profile->data + i ); |
| } |
| |
| static BOOL get_adjusted_tag( const struct profile *profile, TAGTYPE type, cmsTagEntry *tag ) |
| { |
| DWORD i, num_tags = *(DWORD *)(profile->data + sizeof(cmsICCHeader)); |
| cmsTagEntry *entry; |
| ULONG sig; |
| |
| adjust_endianness32( &num_tags ); |
| for (i = 0; i < num_tags; i++) |
| { |
| 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; |
| adjust_endianness32( &tag->offset ); |
| adjust_endianness32( &tag->size ); |
| return TRUE; |
| } |
| } |
| return FALSE; |
| } |
| |
| BOOL get_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, void *buffer, DWORD *len ) |
| { |
| cmsTagEntry tag; |
| |
| if (!get_adjusted_tag( profile, type, &tag )) return FALSE; |
| |
| if (!buffer) offset = 0; |
| if (offset > tag.size) return FALSE; |
| if (*len < tag.size - offset || !buffer) |
| { |
| *len = tag.size - offset; |
| return FALSE; |
| } |
| memcpy( buffer, profile->data + tag.offset + offset, tag.size - offset ); |
| *len = tag.size - offset; |
| return TRUE; |
| } |
| |
| BOOL set_tag_data( const struct profile *profile, TAGTYPE type, DWORD offset, const void *buffer, DWORD *len ) |
| { |
| cmsTagEntry tag; |
| |
| if (!get_adjusted_tag( profile, type, &tag )) return FALSE; |
| |
| if (offset > tag.size) return FALSE; |
| *len = min( tag.size - offset, *len ); |
| memcpy( profile->data + tag.offset + offset, buffer, *len ); |
| return TRUE; |
| } |
| |
| #endif /* HAVE_LCMS2 */ |