From 89de92ef26755d30541aa52a88248cfb8bd3d658 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 14 Feb 2005 20:53:59 +0000 Subject: [PATCH] Implement and test access flags for color profiles. Write the color profile back to disk when it was opened for writing. --- dlls/mscms/handle.c | 24 +++++++++++++++++++++--- dlls/mscms/icc.c | 10 +++++++++- dlls/mscms/mscms_priv.h | 7 +++++-- dlls/mscms/profile.c | 27 +++++++++++++++++++++------ dlls/mscms/tests/profile.c | 12 +++--------- 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/dlls/mscms/handle.c b/dlls/mscms/handle.c index 8cbce6f12c0..3ef8955e72f 100644 --- a/dlls/mscms/handle.c +++ b/dlls/mscms/handle.c @@ -44,12 +44,15 @@ static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, /* A simple structure to tie together a pointer to an icc profile, an lcms * color profile handle and a Windows file handle. Windows color profile * handles are built from indexes into an array of these structures. If - * the profile is memory based the file handle field is NULL. + * the profile is memory based the file handle field is NULL. The 'access' + * field records the access parameter supplied to an OpenColorProfile() + * call, i.e. PROFILE_READ or PROFILE_READWRITE. */ struct handlemap { HANDLE file; + DWORD access; icProfile *iccprofile; cmsHPROFILE cmsprofile; }; @@ -96,6 +99,20 @@ HANDLE MSCMS_hprofile2handle( HPROFILE profile ) return file; } +DWORD MSCMS_hprofile2access( HPROFILE profile ) +{ + DWORD access; + unsigned int i; + + EnterCriticalSection( &MSCMS_handle_cs ); + + i = (unsigned int)profile - 1; + access = handlemaptable[i].access; + + LeaveCriticalSection( &MSCMS_handle_cs ); + return access; +} + HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile ) { HPROFILE profile = NULL; @@ -172,7 +189,8 @@ icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile ) return iccprofile; } -HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile ) +HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, + cmsHPROFILE cmsprofile, DWORD access ) { HPROFILE profile = NULL; unsigned int i; @@ -186,6 +204,7 @@ HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHP if (handlemaptable[i].iccprofile == 0) { handlemaptable[i].file = file; + handlemaptable[i].access = access; handlemaptable[i].iccprofile = iccprofile; handlemaptable[i].cmsprofile = cmsprofile; @@ -195,7 +214,6 @@ HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHP out: LeaveCriticalSection( &MSCMS_handle_cs ); - return profile; } diff --git a/dlls/mscms/icc.c b/dlls/mscms/icc.c index c6edb585f14..fcbe8eb2732 100644 --- a/dlls/mscms/icc.c +++ b/dlls/mscms/icc.c @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * 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 @@ -101,4 +101,12 @@ void MSCMS_set_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, void * memcpy( (char *)iccprofile + tag->offset + offset, buffer, tag->size - offset ); } +DWORD MSCMS_get_profile_size( icProfile *iccprofile ) +{ + DWORD size = ((icHeader *)iccprofile)->size; + + MSCMS_adjust_endianess32( (ULONG *)&size ); + return size; +} + #endif /* HAVE_LCMS_H */ diff --git a/dlls/mscms/mscms_priv.h b/dlls/mscms/mscms_priv.h index bb5155121c9..ece47fb6824 100644 --- a/dlls/mscms/mscms_priv.h +++ b/dlls/mscms/mscms_priv.h @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * 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 @@ -68,6 +68,7 @@ #define DWORD DWORD #define LPDWORD LPDWORD +extern DWORD MSCMS_hprofile2access( HPROFILE ); extern HPROFILE MSCMS_handle2hprofile( HANDLE file ); extern HPROFILE MSCMS_cmsprofile2hprofile( cmsHPROFILE cmsprofile ); extern HPROFILE MSCMS_iccprofile2hprofile( icProfile *iccprofile ); @@ -75,7 +76,8 @@ extern HANDLE MSCMS_hprofile2handle( HPROFILE profile ); extern cmsHPROFILE MSCMS_hprofile2cmsprofile( HPROFILE profile ); extern icProfile *MSCMS_hprofile2iccprofile( HPROFILE profile ); -extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, cmsHPROFILE cmsprofile ); +extern HPROFILE MSCMS_create_hprofile_handle( HANDLE file, icProfile *iccprofile, + cmsHPROFILE cmsprofile, DWORD access ); extern void MSCMS_destroy_hprofile_handle( HPROFILE profile ); extern DWORD MSCMS_get_tag_count( icProfile *iccprofile ); @@ -84,5 +86,6 @@ extern void MSCMS_get_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, extern void MSCMS_set_tag_data( icProfile *iccprofile, icTag *tag, DWORD offset, void *buffer ); extern void MSCMS_get_profile_header( icProfile *iccprofile, PROFILEHEADER *header ); extern void MSCMS_set_profile_header( icProfile *iccprofile, PROFILEHEADER *header ); +extern DWORD MSCMS_get_profile_size( icProfile *iccprofile ); #endif /* HAVE_LCMS_H */ diff --git a/dlls/mscms/profile.c b/dlls/mscms/profile.c index 3f751f80814..45620f7ecf6 100644 --- a/dlls/mscms/profile.c +++ b/dlls/mscms/profile.c @@ -1,7 +1,7 @@ /* * MSCMS - Color Management System for Wine * - * Copyright 2004 Hans Leidekker + * 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 @@ -554,12 +554,14 @@ BOOL WINAPI SetColorProfileElement( HPROFILE profile, TAGTYPE type, DWORD offset BOOL ret = FALSE; #ifdef HAVE_LCMS_H icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile ); - DWORD i, count; + DWORD i, count, access = MSCMS_hprofile2access( profile ); icTag tag; TRACE( "( %p, 0x%08lx, %ld, %p, %p )\n", profile, type, offset, size, buffer ); if (!iccprofile || !size || !buffer) return FALSE; + if (!(access & PROFILE_READWRITE)) return FALSE; + count = MSCMS_get_tag_count( iccprofile ); for (i = 0; i < count; i++) @@ -584,10 +586,12 @@ BOOL WINAPI SetColorProfileHeader( HPROFILE profile, PPROFILEHEADER header ) BOOL ret = FALSE; #ifdef HAVE_LCMS_H icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile ); + DWORD access = MSCMS_hprofile2access( profile ); TRACE( "( %p, %p )\n", profile, header ); if (!iccprofile || !header) return FALSE; + if (!(access & PROFILE_READWRITE)) return FALSE; MSCMS_set_profile_header( iccprofile, header ); return TRUE; @@ -794,7 +798,7 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing } if (cmsprofile) - return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile ); + return MSCMS_create_hprofile_handle( handle, iccprofile, cmsprofile, access ); #endif /* HAVE_LCMS_H */ return NULL; @@ -815,15 +819,26 @@ HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing BOOL WINAPI CloseColorProfile( HPROFILE profile ) { BOOL ret = FALSE; +#ifdef HAVE_LCMS_H + icProfile *iccprofile = MSCMS_hprofile2iccprofile( profile ); + HANDLE file = MSCMS_hprofile2handle( profile ); + DWORD access = MSCMS_hprofile2access( profile ); TRACE( "( %p )\n", profile ); -#ifdef HAVE_LCMS_H + if (file && (access & PROFILE_READWRITE)) + { + DWORD written, size = MSCMS_get_profile_size( iccprofile ); + + if (SetFilePointer( file, 0, NULL, FILE_BEGIN ) || + !WriteFile( file, iccprofile, size, &written, NULL ) || written != size) + ERR( "Unable to write color profile\n" ); + } + ret = cmsCloseProfile( MSCMS_hprofile2cmsprofile( profile ) ); - HeapFree( GetProcessHeap(), 0, MSCMS_hprofile2iccprofile( profile ) ); - CloseHandle( MSCMS_hprofile2handle( profile ) ); + CloseHandle( MSCMS_hprofile2handle( profile ) ); MSCMS_destroy_hprofile_handle( profile ); #endif /* HAVE_LCMS_H */ diff --git a/dlls/mscms/tests/profile.c b/dlls/mscms/tests/profile.c index ceeb8dca075..2da748c6688 100644 --- a/dlls/mscms/tests/profile.c +++ b/dlls/mscms/tests/profile.c @@ -1,7 +1,7 @@ /* * Tests for color profile functions * - * Copyright 2004 Hans Leidekker + * 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 @@ -743,22 +743,19 @@ static void test_SetColorProfileElement() profile.pProfileData = testprofile; profile.cbDataSize = strlen(testprofile); + /* Parameter checks */ + handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() ); - todo_wine - { ret = SetColorProfileElement( handle, tag, 0, &size, data ); ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() ); - } CloseColorProfile( handle ); handle = OpenColorProfileA( &profile, PROFILE_READWRITE, 0, OPEN_EXISTING ); ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() ); - /* Parameter checks */ - ret = SetColorProfileElement( NULL, 0, 0, NULL, NULL ); ok( !ret, "SetColorProfileElement() succeeded (%ld)\n", GetLastError() ); @@ -827,11 +824,8 @@ static void test_SetColorProfileHeader() handle = OpenColorProfileA( &profile, PROFILE_READ, 0, OPEN_EXISTING ); ok( handle != NULL, "OpenColorProfileA() failed (%ld)\n", GetLastError() ); - todo_wine - { ret = SetColorProfileHeader( handle, &header ); ok( !ret, "SetColorProfileHeader() succeeded (%ld)\n", GetLastError() ); - } CloseColorProfile( handle );