| /* | |
| * 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 */ |