diff --git a/reactos/baseaddress.rbuild b/reactos/baseaddress.rbuild index 76c98778079..04965b3a154 100644 --- a/reactos/baseaddress.rbuild +++ b/reactos/baseaddress.rbuild @@ -13,6 +13,7 @@ + @@ -116,8 +117,10 @@ + + diff --git a/reactos/boot/bootdata/packages/reactos.dff b/reactos/boot/bootdata/packages/reactos.dff index b95007eae58..726c508bd76 100644 --- a/reactos/boot/bootdata/packages/reactos.dff +++ b/reactos/boot/bootdata/packages/reactos.dff @@ -298,13 +298,16 @@ dll\win32\mprapi\mprapi.dll 1 dll\win32\msacm32\msacm32.dll 1 dll\win32\msafd\msafd.dll 1 dll\win32\mscat32\mscat32.dll 1 +dll\win32\mscms\mscms.dll 1 dll\win32\mscoree\mscoree.dll 1 +dll\win32\msftedit\msftedit.dll 1 dll\win32\msgina\msgina.dll 1 dll\win32\mshtml\mshtml.dll 1 dll\win32\mshtml.tlb\mshtml.tlb 1 dll\win32\msi\msi.dll 1 dll\win32\msimg32\msimg32.dll 1 dll\win32\msimtf\msimtf.dll 1 +dll\win32\msrle32\msrle32.dll 1 dll\win32\mstask\mstask.dll 1 dll\win32\msvcrt\msvcrt.dll 1 dll\win32\msvcrt20\msvcrt20.dll 1 diff --git a/reactos/dll/win32/mscms/handle.c b/reactos/dll/win32/mscms/handle.c new file mode 100644 index 00000000000..84f1d8ba30f --- /dev/null +++ b/reactos/dll/win32/mscms/handle.c @@ -0,0 +1,250 @@ +/* + * MSCMS - Color Management System for Wine + * + * Copyright 2004, 2005, 2008 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 "wine/debug.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "icm.h" + +#include "mscms_priv.h" + +#ifdef HAVE_LCMS + +static CRITICAL_SECTION MSCMS_handle_cs; +static CRITICAL_SECTION_DEBUG MSCMS_handle_cs_debug = +{ + 0, 0, &MSCMS_handle_cs, + { &MSCMS_handle_cs_debug.ProcessLocksList, + &MSCMS_handle_cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": MSCMS_handle_cs") } +}; +static CRITICAL_SECTION MSCMS_handle_cs = { &MSCMS_handle_cs_debug, -1, 0, 0, 0, 0 }; + +static struct profile *profiletable; +static struct transform *transformtable; + +static unsigned int num_profile_handles; +static unsigned int num_transform_handles; + +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + +void free_handle_tables( void ) +{ + HeapFree( GetProcessHeap(), 0, profiletable ); + profiletable = NULL; + num_profile_handles = 0; + + HeapFree( GetProcessHeap(), 0, transformtable ); + transformtable = NULL; + num_transform_handles = 0; +} + +struct profile *grab_profile( HPROFILE handle ) +{ + DWORD_PTR index; + + EnterCriticalSection( &MSCMS_handle_cs ); + + index = (DWORD_PTR)handle - 1; + if (index > num_profile_handles) + { + LeaveCriticalSection( &MSCMS_handle_cs ); + return NULL; + } + return &profiletable[index]; +} + +void release_profile( struct profile *profile ) +{ + LeaveCriticalSection( &MSCMS_handle_cs ); +} + +struct transform *grab_transform( HTRANSFORM handle ) +{ + DWORD_PTR index; + + EnterCriticalSection( &MSCMS_handle_cs ); + + index = (DWORD_PTR)handle - 1; + if (index > num_transform_handles) + { + LeaveCriticalSection( &MSCMS_handle_cs ); + return NULL; + } + return &transformtable[index]; +} + +void release_transform( struct transform *transform ) +{ + LeaveCriticalSection( &MSCMS_handle_cs ); +} + +static HPROFILE alloc_profile_handle( void ) +{ + DWORD_PTR index; + struct profile *p; + unsigned int count = 128; + + for (index = 0; index < num_profile_handles; index++) + { + if (!profiletable[index].iccprofile) return (HPROFILE)(index + 1); + } + if (!profiletable) + { + p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct profile) ); + } + else + { + count = num_profile_handles * 2; + p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, profiletable, count * sizeof(struct profile) ); + } + if (!p) return NULL; + + profiletable = p; + num_profile_handles = count; + + return (HPROFILE)(index + 1); +} + +HPROFILE create_profile( struct profile *profile ) +{ + HPROFILE handle; + + EnterCriticalSection( &MSCMS_handle_cs ); + + if ((handle = alloc_profile_handle())) + { + DWORD_PTR index = (DWORD_PTR)handle - 1; + memcpy( &profiletable[index], profile, sizeof(struct profile) ); + } + LeaveCriticalSection( &MSCMS_handle_cs ); + return handle; +} + +BOOL close_profile( HPROFILE handle ) +{ + DWORD_PTR index; + struct profile *profile; + + EnterCriticalSection( &MSCMS_handle_cs ); + + index = (DWORD_PTR)handle - 1; + if (index > num_profile_handles) + { + LeaveCriticalSection( &MSCMS_handle_cs ); + return FALSE; + } + profile = &profiletable[index]; + + if (profile->file != INVALID_HANDLE_VALUE) + { + if (profile->access & PROFILE_READWRITE) + { + DWORD written, size = MSCMS_get_profile_size( profile->iccprofile ); + + if (SetFilePointer( profile->file, 0, NULL, FILE_BEGIN ) || + !WriteFile( profile->file, profile->iccprofile, size, &written, NULL ) || + written != size) + { + ERR( "Unable to write color profile\n" ); + } + } + CloseHandle( profile->file ); + } + cmsCloseProfile( profile->cmsprofile ); + HeapFree( GetProcessHeap(), 0, profile->iccprofile ); + + memset( profile, 0, sizeof(struct profile) ); + + LeaveCriticalSection( &MSCMS_handle_cs ); + return TRUE; +} + +static HTRANSFORM alloc_transform_handle( void ) +{ + DWORD_PTR index; + struct transform *p; + unsigned int count = 128; + + for (index = 0; index < num_transform_handles; index++) + { + if (!transformtable[index].cmstransform) return (HTRANSFORM)(index + 1); + } + if (!transformtable) + { + p = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, count * sizeof(struct transform) ); + } + else + { + count = num_transform_handles * 2; + p = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, transformtable, count * sizeof(struct transform) ); + } + if (!p) return NULL; + + transformtable = p; + num_transform_handles = count; + + return (HTRANSFORM)(index + 1); +} + +HTRANSFORM create_transform( struct transform *transform ) +{ + HTRANSFORM handle; + + EnterCriticalSection( &MSCMS_handle_cs ); + + if ((handle = alloc_transform_handle())) + { + DWORD_PTR index = (DWORD_PTR)handle - 1; + memcpy( &transformtable[index], transform, sizeof(struct transform) ); + } + LeaveCriticalSection( &MSCMS_handle_cs ); + return handle; +} + +BOOL close_transform( HTRANSFORM handle ) +{ + DWORD_PTR index; + struct transform *transform; + + EnterCriticalSection( &MSCMS_handle_cs ); + + index = (DWORD_PTR)handle - 1; + if (index > num_transform_handles) + { + LeaveCriticalSection( &MSCMS_handle_cs ); + return FALSE; + } + transform = &transformtable[index]; + + cmsDeleteTransform( transform->cmstransform ); + memset( transform, 0, sizeof(struct transform) ); + + LeaveCriticalSection( &MSCMS_handle_cs ); + return TRUE; +} + +#endif /* HAVE_LCMS */ diff --git a/reactos/dll/win32/mscms/icc.c b/reactos/dll/win32/mscms/icc.c new file mode 100644 index 00000000000..67b65ed6643 --- /dev/null +++ b/reactos/dll/win32/mscms/icc.c @@ -0,0 +1,105 @@ +/* + * 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 + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winternl.h" +#include "icm.h" + +#include "mscms_priv.h" + +#ifdef HAVE_LCMS + +static inline void MSCMS_adjust_endianess32( ULONG *ptr ) +{ +#ifndef WORDS_BIGENDIAN + *ptr = RtlUlongByteSwap(*ptr); +#endif +} + +void MSCMS_get_profile_header( const icProfile *iccprofile, PROFILEHEADER *header ) +{ + unsigned int i; + + memcpy( header, iccprofile, sizeof(PROFILEHEADER) ); + + /* ICC format is big-endian, swap bytes if necessary */ + for (i = 0; i < sizeof(PROFILEHEADER) / sizeof(ULONG); i++) + MSCMS_adjust_endianess32( (ULONG *)header + i ); +} + +void MSCMS_set_profile_header( icProfile *iccprofile, const PROFILEHEADER *header ) +{ + unsigned int i; + icHeader *iccheader = (icHeader *)iccprofile; + + memcpy( iccheader, header, sizeof(icHeader) ); + + /* ICC format is big-endian, swap bytes if necessary */ + for (i = 0; i < sizeof(icHeader) / sizeof(ULONG); i++) + MSCMS_adjust_endianess32( (ULONG *)iccheader + i ); +} + +DWORD MSCMS_get_tag_count( const icProfile *iccprofile ) +{ + ULONG count = iccprofile->count; + + MSCMS_adjust_endianess32( &count ); + return count; +} + +void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag ) +{ + icTag *tmp = (icTag *)((char *)iccprofile->data + index * sizeof(icTag)); + + tag->sig = tmp->sig; + tag->offset = tmp->offset; + tag->size = tmp->size; + + MSCMS_adjust_endianess32( &tag->sig ); + MSCMS_adjust_endianess32( &tag->offset ); + MSCMS_adjust_endianess32( &tag->size ); +} + +void MSCMS_get_tag_data( const icProfile *iccprofile, const icTag *tag, DWORD offset, void *buffer ) +{ + memcpy( buffer, (const char *)iccprofile + tag->offset + offset, tag->size - offset ); +} + +void MSCMS_set_tag_data( icProfile *iccprofile, const icTag *tag, DWORD offset, const void *buffer ) +{ + memcpy( (char *)iccprofile + tag->offset + offset, buffer, tag->size - offset ); +} + +DWORD MSCMS_get_profile_size( const icProfile *iccprofile ) +{ + DWORD size = ((const icHeader *)iccprofile)->size; + + MSCMS_adjust_endianess32( &size ); + return size; +} + +#endif /* HAVE_LCMS */ diff --git a/reactos/dll/win32/mscms/mscms.rbuild b/reactos/dll/win32/mscms/mscms.rbuild new file mode 100644 index 00000000000..49e3866d165 --- /dev/null +++ b/reactos/dll/win32/mscms/mscms.rbuild @@ -0,0 +1,17 @@ + + + . + include/reactos/wine + + handle.c + icc.c + mscms_main.c + profile.c + stub.c + transform.c + version.rc + wine + advapi32 + kernel32 + ntdll + diff --git a/reactos/dll/win32/mscms/mscms.spec b/reactos/dll/win32/mscms/mscms.spec new file mode 100644 index 00000000000..f728c7950bf --- /dev/null +++ b/reactos/dll/win32/mscms/mscms.spec @@ -0,0 +1,61 @@ +@ stdcall AssociateColorProfileWithDeviceA(ptr ptr ptr) +@ stdcall AssociateColorProfileWithDeviceW(ptr ptr ptr) +@ stdcall CheckBitmapBits(ptr ptr ptr long long long ptr ptr long) +@ stdcall CheckColors(ptr ptr long long ptr) +@ stdcall CloseColorProfile(ptr) +@ stdcall ConvertColorNameToIndex(ptr ptr ptr long) +@ stdcall ConvertIndexToColorName(ptr ptr ptr long) +@ stdcall CreateColorTransformA(ptr ptr ptr long) +@ stdcall CreateColorTransformW(ptr ptr ptr long) +@ stdcall CreateDeviceLinkProfile(ptr long ptr long long ptr long) +@ stdcall CreateMultiProfileTransform(ptr long ptr long long long) +@ stdcall CreateProfileFromLogColorSpaceA(ptr ptr) +@ stdcall CreateProfileFromLogColorSpaceW(ptr ptr) +@ stdcall DeleteColorTransform(ptr) +@ stdcall DisassociateColorProfileFromDeviceA(ptr ptr ptr) +@ stdcall DisassociateColorProfileFromDeviceW(ptr ptr ptr) +@ stdcall EnumColorProfilesA(ptr ptr ptr ptr ptr) +@ stdcall EnumColorProfilesW(ptr ptr ptr ptr ptr) +@ stdcall GenerateCopyFilePaths(wstr wstr ptr long ptr ptr ptr ptr long) +@ stdcall GetCMMInfo(ptr long) +@ stdcall GetColorDirectoryA(ptr ptr long) +@ stdcall GetColorDirectoryW(ptr ptr long) +@ stdcall GetColorProfileElement(ptr long long ptr ptr ptr) +@ stdcall GetColorProfileElementTag(ptr long ptr) +@ stdcall GetColorProfileFromHandle(ptr ptr ptr) +@ stdcall GetColorProfileHeader(ptr ptr) +@ stdcall GetCountColorProfileElements(ptr long) +@ stdcall GetNamedProfileInfo(ptr ptr) +@ stdcall GetPS2ColorRenderingDictionary(ptr long ptr ptr ptr) +@ stdcall GetPS2ColorRenderingIntent(ptr long ptr ptr) +@ stdcall GetPS2ColorSpaceArray(ptr long long ptr ptr ptr) +@ stdcall GetStandardColorSpaceProfileA(ptr long ptr ptr) +@ stdcall GetStandardColorSpaceProfileW(ptr long ptr ptr) +@ stdcall InstallColorProfileA(ptr ptr) +@ stdcall InstallColorProfileW(ptr ptr) +@ stub InternalGetDeviceConfig +@ stub InternalGetPS2CSAFromLCS +@ stub InternalGetPS2ColorRenderingDictionary +@ stub InternalGetPS2ColorSpaceArray +@ stub InternalGetPS2PreviewCRD +@ stub InternalSetDeviceConfig +@ stdcall IsColorProfileTagPresent(ptr long ptr) +@ stdcall IsColorProfileValid(ptr long) +@ stdcall OpenColorProfileA(ptr long long long) +@ stdcall OpenColorProfileW(ptr long long long) +@ stdcall RegisterCMMA(ptr long ptr) +@ stdcall RegisterCMMW(ptr long ptr) +@ stdcall SelectCMM(long) +@ stdcall SetColorProfileElement(ptr long long ptr ptr) +@ stdcall SetColorProfileElementReference(ptr long long) +@ stdcall SetColorProfileElementSize(ptr long long) +@ stdcall SetColorProfileHeader(ptr ptr) +@ stdcall SetStandardColorSpaceProfileA(ptr long ptr) +@ stdcall SetStandardColorSpaceProfileW(ptr long ptr) +@ stdcall SpoolerCopyFileEvent(wstr wstr long) +@ stdcall TranslateBitmapBits(ptr ptr long long long long ptr long long ptr long) +@ stdcall TranslateColors(ptr ptr long long ptr long) +@ stdcall UninstallColorProfileA(ptr ptr long) +@ stdcall UninstallColorProfileW(ptr ptr long) +@ stdcall UnregisterCMMA(ptr long) +@ stdcall UnregisterCMMW(ptr long) diff --git a/reactos/dll/win32/mscms/mscms_main.c b/reactos/dll/win32/mscms/mscms_main.c new file mode 100644 index 00000000000..00e2a753e87 --- /dev/null +++ b/reactos/dll/win32/mscms/mscms_main.c @@ -0,0 +1,55 @@ +/* + * 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 "wine/port.h" +#include "wine/debug.h" +#include "wine/library.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "icm.h" + +#include "mscms_priv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) +{ + TRACE( "(%p, %d, %p)\n", hinst, reason, reserved ); + + switch (reason) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls( hinst ); + break; + case DLL_PROCESS_DETACH: +#ifdef HAVE_LCMS + free_handle_tables(); +#endif + break; + } + return TRUE; +} diff --git a/reactos/dll/win32/mscms/mscms_priv.h b/reactos/dll/win32/mscms/mscms_priv.h new file mode 100644 index 00000000000..479148bee80 --- /dev/null +++ b/reactos/dll/win32/mscms/mscms_priv.h @@ -0,0 +1,114 @@ +/* + * 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 + */ + +#ifdef HAVE_LCMS + +/* These basic Windows types are defined in lcms.h when compiling on + * a non-Windows platform (why?), so they would normally not conflict + * with anything included earlier. But since we are building Wine they + * most certainly will have been defined before we include lcms.h. + * The preprocessor comes to the rescue. + */ + +#define BYTE LCMS_BYTE +#define LPBYTE LCMS_LPBYTE +#define WORD LCMS_WORD +#define LPWORD LCMS_LPWORD +#define DWORD LCMS_DWORD +#define LPDWORD LCMS_LPDWORD +#define BOOL LCMS_BOOL +#define LPSTR LCMS_LPSTR +#define LPVOID LCMS_LPVOID + +#undef cdecl +#undef FAR + +#undef ZeroMemory +#undef CopyMemory + +#undef LOWORD +#undef HIWORD +#undef MAX_PATH + +#ifdef HAVE_LCMS_LCMS_H +#include +#else +#include +#endif + +/* Funny thing is lcms.h defines DWORD as an 'unsigned long' whereas Wine + * defines it as an 'unsigned int'. To avoid compiler warnings we use a + * preprocessor define for DWORD and LPDWORD to get back Wine's original + * (typedef) definitions. + */ + +#undef BOOL +#undef DWORD +#undef LPDWORD + +#define BOOL BOOL +#define DWORD DWORD +#define LPDWORD LPDWORD + +/* A simple structure to tie together a pointer to an icc profile, an lcms + * color profile handle and a Windows file handle. If the profile is memory + * based the file handle field is set to INVALID_HANDLE_VALUE. The 'access' + * field records the access parameter supplied to an OpenColorProfile() + * call, i.e. PROFILE_READ or PROFILE_READWRITE. + */ + +struct profile +{ + HANDLE file; + DWORD access; + icProfile *iccprofile; + cmsHPROFILE cmsprofile; +}; + +struct transform +{ + cmsHTRANSFORM cmstransform; +}; + +extern HPROFILE create_profile( struct profile * ); +extern BOOL close_profile( HPROFILE ); + +extern HTRANSFORM create_transform( struct transform * ); +extern BOOL close_transform( HTRANSFORM ); + +struct profile *grab_profile( HPROFILE ); +struct transform *grab_transform( HTRANSFORM ); + +void release_profile( struct profile * ); +void release_transform( struct transform * ); + +extern void free_handle_tables( void ); + +extern DWORD MSCMS_get_tag_count( const icProfile *iccprofile ); +extern void MSCMS_get_tag_by_index( icProfile *iccprofile, DWORD index, icTag *tag ); +extern void MSCMS_get_tag_data( const icProfile *iccprofile, const icTag *tag, DWORD offset, void *buffer ); +extern void MSCMS_set_tag_data( icProfile *iccprofile, const icTag *tag, DWORD offset, const void *buffer ); +extern void MSCMS_get_profile_header( const icProfile *iccprofile, PROFILEHEADER *header ); +extern void MSCMS_set_profile_header( icProfile *iccprofile, const PROFILEHEADER *header ); +extern DWORD MSCMS_get_profile_size( const icProfile *iccprofile ); + +extern const char *MSCMS_dbgstr_tag(DWORD); + +#endif /* HAVE_LCMS */ diff --git a/reactos/dll/win32/mscms/profile.c b/reactos/dll/win32/mscms/profile.c new file mode 100644 index 00000000000..1c6811e0689 --- /dev/null +++ b/reactos/dll/win32/mscms/profile.c @@ -0,0 +1,1549 @@ +/* + * MSCMS - Color Management System for Wine + * + * Copyright 2004, 2005, 2006, 2008 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 "wine/debug.h" +#include "wine/unicode.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "icm.h" + +#include "mscms_priv.h" + +#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/') + +static void MSCMS_basename( LPCWSTR path, LPWSTR name ) +{ + INT i = lstrlenW( path ); + + while (i > 0 && !IS_SEPARATOR(path[i - 1])) i--; + lstrcpyW( name, &path[i] ); +} + +static inline LPWSTR MSCMS_strdupW( LPCSTR str ) +{ + LPWSTR ret = NULL; + if (str) + { + DWORD len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + if ((ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + MultiByteToWideChar( CP_ACP, 0, str, -1, ret, len ); + } + return ret; +} + +const char *MSCMS_dbgstr_tag( DWORD tag ) +{ + return wine_dbg_sprintf( "'%c%c%c%c'", + (char)(tag >> 24), (char)(tag >> 16), (char)(tag >> 8), (char)(tag) ); +} + +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + +/****************************************************************************** + * AssociateColorProfileWithDeviceA [MSCMS.@] + */ +BOOL WINAPI AssociateColorProfileWithDeviceA( PCSTR machine, PCSTR profile, PCSTR device ) +{ + int len; + BOOL ret = FALSE; + WCHAR *profileW, *deviceW; + + TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) ); + + if (!profile || !device) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 ); + if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE; + + MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len ); + + len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 ); + if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + { + MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len ); + ret = AssociateColorProfileWithDeviceW( NULL, profileW, deviceW ); + } + + HeapFree( GetProcessHeap(), 0, profileW ); + HeapFree( GetProcessHeap(), 0, deviceW ); + return ret; +} + +static BOOL set_profile_device_key( PCWSTR file, const BYTE *value, DWORD size ) +{ + static const WCHAR fmtW[] = {'%','c','%','c','%','c','%','c',0}; + static const WCHAR icmW[] = {'S','o','f','t','w','a','r','e','\\', + 'M','i','c','r','o','s','o','f','t','\\', + 'W','i','n','d','o','w','s',' ','N','T','\\', + 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', + 'I','C','M',0}; + PROFILEHEADER header; + PROFILE profile; + HPROFILE handle; + HKEY icm_key, class_key; + WCHAR basenameW[MAX_PATH], classW[5]; + + profile.dwType = PROFILE_FILENAME; + profile.pProfileData = (PVOID)file; + profile.cbDataSize = (lstrlenW( file ) + 1) * sizeof(WCHAR); + + /* FIXME is the profile installed? */ + if (!(handle = OpenColorProfileW( &profile, PROFILE_READ, 0, OPEN_EXISTING ))) + { + SetLastError( ERROR_INVALID_PROFILE ); + return FALSE; + } + if (!GetColorProfileHeader( handle, &header )) + { + CloseColorProfile( handle ); + SetLastError( ERROR_INVALID_PROFILE ); + return FALSE; + } + RegCreateKeyExW( HKEY_LOCAL_MACHINE, icmW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &icm_key, NULL ); + + MSCMS_basename( file, basenameW ); + sprintfW( classW, fmtW, (header.phClass >> 24) & 0xff, (header.phClass >> 16) & 0xff, + (header.phClass >> 8) & 0xff, header.phClass & 0xff ); + + RegCreateKeyExW( icm_key, classW, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &class_key, NULL ); + if (value) RegSetValueExW( class_key, basenameW, 0, REG_BINARY, value, size ); + else RegDeleteValueW( class_key, basenameW ); + + RegCloseKey( class_key ); + RegCloseKey( icm_key ); + CloseColorProfile( handle ); + return TRUE; +} + +/****************************************************************************** + * AssociateColorProfileWithDeviceW [MSCMS.@] + */ +BOOL WINAPI AssociateColorProfileWithDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device ) +{ + static const BYTE dummy_value[12]; + + TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) ); + + if (!profile || !device) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + return set_profile_device_key( profile, dummy_value, sizeof(dummy_value) ); +} + +/****************************************************************************** + * DisassociateColorProfileFromDeviceA [MSCMS.@] + */ +BOOL WINAPI DisassociateColorProfileFromDeviceA( PCSTR machine, PCSTR profile, PCSTR device ) +{ + int len; + BOOL ret = FALSE; + WCHAR *profileW, *deviceW; + + TRACE( "( %s, %s, %s )\n", debugstr_a(machine), debugstr_a(profile), debugstr_a(device) ); + + if (!profile || !device) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 ); + if (!(profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE; + + MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len ); + + len = MultiByteToWideChar( CP_ACP, 0, device, -1, NULL, 0 ); + if ((deviceW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) + { + MultiByteToWideChar( CP_ACP, 0, device, -1, deviceW, len ); + ret = DisassociateColorProfileFromDeviceW( NULL, profileW, deviceW ); + } + + HeapFree( GetProcessHeap(), 0, profileW ); + HeapFree( GetProcessHeap(), 0, deviceW ); + return ret; +} + +/****************************************************************************** + * DisassociateColorProfileFromDeviceW [MSCMS.@] + */ +BOOL WINAPI DisassociateColorProfileFromDeviceW( PCWSTR machine, PCWSTR profile, PCWSTR device ) +{ + TRACE( "( %s, %s, %s )\n", debugstr_w(machine), debugstr_w(profile), debugstr_w(device) ); + + if (!profile || !device) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + return set_profile_device_key( profile, NULL, 0 ); +} + +/****************************************************************************** + * GetColorDirectoryA [MSCMS.@] + * + * See GetColorDirectoryW. + */ +BOOL WINAPI GetColorDirectoryA( PCSTR machine, PSTR buffer, PDWORD size ) +{ + INT len; + LPWSTR bufferW; + BOOL ret = FALSE; + DWORD sizeW; + + TRACE( "( %p, %p )\n", buffer, size ); + + if (machine || !size) return FALSE; + + if (!buffer) + { + ret = GetColorDirectoryW( NULL, NULL, &sizeW ); + *size = sizeW / sizeof(WCHAR); + return FALSE; + } + + sizeW = *size * sizeof(WCHAR); + + bufferW = HeapAlloc( GetProcessHeap(), 0, sizeW ); + + if (bufferW) + { + if ((ret = GetColorDirectoryW( NULL, bufferW, &sizeW ))) + { + *size = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL ); + len = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, buffer, *size, NULL, NULL ); + if (!len) ret = FALSE; + } + else *size = sizeW / sizeof(WCHAR); + + HeapFree( GetProcessHeap(), 0, bufferW ); + } + return ret; +} + +/****************************************************************************** + * GetColorDirectoryW [MSCMS.@] + * + * Get the directory where color profiles are stored. + * + * PARAMS + * machine [I] Name of the machine for which to get the color directory. + * Must be NULL, which indicates the local machine. + * buffer [I] Buffer to receive the path name. + * size [I/O] Size of the buffer in bytes. On return the variable holds + * the number of bytes actually needed. + */ +BOOL WINAPI GetColorDirectoryW( PCWSTR machine, PWSTR buffer, PDWORD size ) +{ + WCHAR colordir[MAX_PATH]; + static const WCHAR colorsubdir[] = + {'\\','s','p','o','o','l','\\','d','r','i','v','e','r','s','\\','c','o','l','o','r',0}; + DWORD len; + + TRACE( "( %p, %p )\n", buffer, size ); + + if (machine || !size) return FALSE; + + GetSystemDirectoryW( colordir, sizeof(colordir) / sizeof(WCHAR) ); + lstrcatW( colordir, colorsubdir ); + + len = lstrlenW( colordir ) * sizeof(WCHAR); + + if (buffer && len <= *size) + { + lstrcpyW( buffer, colordir ); + *size = len; + return TRUE; + } + + SetLastError( ERROR_MORE_DATA ); + *size = len; + return FALSE; +} + +/****************************************************************************** + * GetColorProfileElement [MSCMS.@] + * + * Retrieve data for a specified tag type. + * + * PARAMS + * profile [I] Handle to a color profile. + * type [I] ICC tag type. + * offset [I] Offset in bytes to start copying from. + * size [I/O] Size of the buffer in bytes. On return the variable holds + * the number of bytes actually needed. + * buffer [O] Buffer to receive the tag data. + * ref [O] Pointer to a BOOL that specifies whether more than one tag + * references the data. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI GetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, + PVOID buffer, PBOOL ref ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + DWORD i, count; + icTag tag; + + TRACE( "( %p, 0x%08x, %d, %p, %p, %p )\n", handle, type, offset, size, buffer, ref ); + + if (!profile) return FALSE; + + if (!size || !ref) + { + release_profile( profile ); + return FALSE; + } + count = MSCMS_get_tag_count( profile->iccprofile ); + + for (i = 0; i < count; i++) + { + MSCMS_get_tag_by_index( profile->iccprofile, i, &tag ); + + if (tag.sig == type) + { + if ((tag.size - offset) > *size || !buffer) + { + *size = (tag.size - offset); + release_profile( profile ); + return FALSE; + } + MSCMS_get_tag_data( profile->iccprofile, &tag, offset, buffer ); + + *ref = FALSE; /* FIXME: calculate properly */ + release_profile( profile ); + return TRUE; + } + } + release_profile( profile ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * GetColorProfileElementTag [MSCMS.@] + * + * Get the tag type from a color profile by index. + * + * PARAMS + * profile [I] Handle to a color profile. + * index [I] Index into the tag table of the color profile. + * type [O] Pointer to a variable that holds the ICC tag type on return. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * The tag table index starts at 1. + * Use GetCountColorProfileElements to retrieve a count of tagged elements. + */ +BOOL WINAPI GetColorProfileElementTag( HPROFILE handle, DWORD index, PTAGTYPE type ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + DWORD count; + icTag tag; + + TRACE( "( %p, %d, %p )\n", handle, index, type ); + + if (!profile) return FALSE; + + if (!type) + { + release_profile( profile ); + return FALSE; + } + count = MSCMS_get_tag_count( profile->iccprofile ); + if (index > count || index < 1) + { + release_profile( profile ); + return FALSE; + } + MSCMS_get_tag_by_index( profile->iccprofile, index - 1, &tag ); + *type = tag.sig; + + release_profile( profile ); + ret = TRUE; + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * GetColorProfileFromHandle [MSCMS.@] + * + * Retrieve an ICC color profile by handle. + * + * PARAMS + * profile [I] Handle to a color profile. + * buffer [O] Buffer to receive the ICC profile. + * size [I/O] Size of the buffer in bytes. On return the variable holds the + * number of bytes actually needed. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * The profile returned will be in big-endian format. + */ +BOOL WINAPI GetColorProfileFromHandle( HPROFILE handle, PBYTE buffer, PDWORD size ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + PROFILEHEADER header; + + TRACE( "( %p, %p, %p )\n", handle, buffer, size ); + + if (!profile) return FALSE; + + if (!size) + { + release_profile( profile ); + return FALSE; + } + MSCMS_get_profile_header( profile->iccprofile, &header ); + + if (!buffer || header.phSize > *size) + { + *size = header.phSize; + release_profile( profile ); + return FALSE; + } + + /* No endian conversion needed */ + memcpy( buffer, profile->iccprofile, header.phSize ); + *size = header.phSize; + + release_profile( profile ); + ret = TRUE; + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * GetColorProfileHeader [MSCMS.@] + * + * Retrieve a color profile header by handle. + * + * PARAMS + * profile [I] Handle to a color profile. + * header [O] Buffer to receive the ICC profile header. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + * NOTES + * The profile header returned will be adjusted for endianess. + */ +BOOL WINAPI GetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) +{ +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + + TRACE( "( %p, %p )\n", handle, header ); + + if (!profile) return FALSE; + + if (!header) + { + release_profile( profile ); + return FALSE; + } + MSCMS_get_profile_header( profile->iccprofile, header ); + + release_profile( profile ); + return TRUE; + +#else + return FALSE; +#endif /* HAVE_LCMS */ +} + +/****************************************************************************** + * GetCountColorProfileElements [MSCMS.@] + * + * Retrieve the number of elements in a color profile. + * + * PARAMS + * profile [I] Handle to a color profile. + * count [O] Pointer to a variable which is set to the number of elements + * in the color profile. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI GetCountColorProfileElements( HPROFILE handle, PDWORD count ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + + TRACE( "( %p, %p )\n", handle, count ); + + if (!profile) return FALSE; + + if (!count) + { + release_profile( profile ); + return FALSE; + } + *count = MSCMS_get_tag_count( profile->iccprofile ); + + release_profile( profile ); + ret = TRUE; + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * GetStandardColorSpaceProfileA [MSCMS.@] + * + * See GetStandardColorSpaceProfileW. + */ +BOOL WINAPI GetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile, PDWORD size ) +{ + INT len; + LPWSTR profileW; + BOOL ret = FALSE; + DWORD sizeW; + + TRACE( "( 0x%08x, %p, %p )\n", id, profile, size ); + + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + if (!size) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + sizeW = *size * sizeof(WCHAR); + + if (!profile) + { + ret = GetStandardColorSpaceProfileW( NULL, id, NULL, &sizeW ); + *size = sizeW / sizeof(WCHAR); + return FALSE; + } + + profileW = HeapAlloc( GetProcessHeap(), 0, sizeW ); + + if (profileW) + { + if ((ret = GetStandardColorSpaceProfileW( NULL, id, profileW, &sizeW ))) + { + *size = WideCharToMultiByte( CP_ACP, 0, profileW, -1, NULL, 0, NULL, NULL ); + len = WideCharToMultiByte( CP_ACP, 0, profileW, -1, profile, *size, NULL, NULL ); + if (!len) ret = FALSE; + } + else *size = sizeW / sizeof(WCHAR); + + HeapFree( GetProcessHeap(), 0, profileW ); + } + return ret; +} + +/****************************************************************************** + * GetStandardColorSpaceProfileW [MSCMS.@] + * + * Retrieve the profile filename for a given standard color space id. + * + * PARAMS + * machine [I] Name of the machine for which to get the standard color space. + * Must be NULL, which indicates the local machine. + * id [I] Id of a standard color space. + * profile [O] Buffer to receive the profile filename. + * size [I/O] Size of the filename buffer in bytes. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI GetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile, PDWORD size ) +{ + static const WCHAR rgbprofilefile[] = + { '\\','s','r','g','b',' ','c','o','l','o','r',' ', + 's','p','a','c','e',' ','p','r','o','f','i','l','e','.','i','c','m',0 }; + WCHAR rgbprofile[MAX_PATH]; + DWORD len = sizeof(rgbprofile); + + TRACE( "( 0x%08x, %p, %p )\n", id, profile, size ); + + if (machine) + { + SetLastError( ERROR_NOT_SUPPORTED ); + return FALSE; + } + + if (!size) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (!profile) + { + SetLastError( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + + GetColorDirectoryW( machine, rgbprofile, &len ); + + switch (id) + { + case SPACE_RGB: /* 'RGB ' */ + lstrcatW( rgbprofile, rgbprofilefile ); + len = lstrlenW( rgbprofile ) * sizeof(WCHAR); + + if (*size < len || !profile) + { + *size = len; + SetLastError( ERROR_MORE_DATA ); + return FALSE; + } + + lstrcpyW( profile, rgbprofile ); + break; + + default: + SetLastError( ERROR_FILE_NOT_FOUND ); + return FALSE; + } + return TRUE; +} + +static BOOL MSCMS_header_from_file( LPCWSTR file, PPROFILEHEADER header ) +{ + BOOL ret; + PROFILE profile; + WCHAR path[MAX_PATH], slash[] = {'\\',0}; + DWORD size = sizeof(path); + HANDLE handle; + + ret = GetColorDirectoryW( NULL, path, &size ); + if (!ret) + { + WARN( "Can't retrieve color directory\n" ); + return FALSE; + } + if (size + sizeof(slash) + sizeof(WCHAR) * lstrlenW( file ) > sizeof(path)) + { + WARN( "Filename too long\n" ); + return FALSE; + } + + lstrcatW( path, slash ); + lstrcatW( path, file ); + + profile.dwType = PROFILE_FILENAME; + profile.pProfileData = path; + profile.cbDataSize = lstrlenW( path ) + 1; + + handle = OpenColorProfileW( &profile, PROFILE_READ, FILE_SHARE_READ, OPEN_EXISTING ); + if (!handle) + { + WARN( "Can't open color profile\n" ); + return FALSE; + } + + ret = GetColorProfileHeader( handle, header ); + if (!ret) + WARN( "Can't retrieve color profile header\n" ); + + CloseColorProfile( handle ); + return ret; +} + +static BOOL MSCMS_match_profile( PENUMTYPEW rec, PPROFILEHEADER hdr ) +{ + if (rec->dwFields & ET_DEVICENAME) + { + FIXME( "ET_DEVICENAME: %s\n", debugstr_w(rec->pDeviceName) ); + } + if (rec->dwFields & ET_MEDIATYPE) + { + FIXME( "ET_MEDIATYPE: 0x%08x\n", rec->dwMediaType ); + } + if (rec->dwFields & ET_DITHERMODE) + { + FIXME( "ET_DITHERMODE: 0x%08x\n", rec->dwDitheringMode ); + } + if (rec->dwFields & ET_RESOLUTION) + { + FIXME( "ET_RESOLUTION: 0x%08x, 0x%08x\n", + rec->dwResolution[0], rec->dwResolution[1] ); + } + if (rec->dwFields & ET_DEVICECLASS) + { + FIXME( "ET_DEVICECLASS: %s\n", MSCMS_dbgstr_tag(rec->dwMediaType) ); + } + if (rec->dwFields & ET_CMMTYPE) + { + TRACE( "ET_CMMTYPE: %s\n", MSCMS_dbgstr_tag(rec->dwCMMType) ); + if (rec->dwCMMType != hdr->phCMMType) return FALSE; + } + if (rec->dwFields & ET_CLASS) + { + TRACE( "ET_CLASS: %s\n", MSCMS_dbgstr_tag(rec->dwClass) ); + if (rec->dwClass != hdr->phClass) return FALSE; + } + if (rec->dwFields & ET_DATACOLORSPACE) + { + TRACE( "ET_DATACOLORSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwDataColorSpace) ); + if (rec->dwDataColorSpace != hdr->phDataColorSpace) return FALSE; + } + if (rec->dwFields & ET_CONNECTIONSPACE) + { + TRACE( "ET_CONNECTIONSPACE: %s\n", MSCMS_dbgstr_tag(rec->dwConnectionSpace) ); + if (rec->dwConnectionSpace != hdr->phConnectionSpace) return FALSE; + } + if (rec->dwFields & ET_SIGNATURE) + { + TRACE( "ET_SIGNATURE: %s\n", MSCMS_dbgstr_tag(rec->dwSignature) ); + if (rec->dwSignature != hdr->phSignature) return FALSE; + } + if (rec->dwFields & ET_PLATFORM) + { + TRACE( "ET_PLATFORM: %s\n", MSCMS_dbgstr_tag(rec->dwPlatform) ); + if (rec->dwPlatform != hdr->phPlatform) return FALSE; + } + if (rec->dwFields & ET_PROFILEFLAGS) + { + TRACE( "ET_PROFILEFLAGS: 0x%08x\n", rec->dwProfileFlags ); + if (rec->dwProfileFlags != hdr->phProfileFlags) return FALSE; + } + if (rec->dwFields & ET_MANUFACTURER) + { + TRACE( "ET_MANUFACTURER: %s\n", MSCMS_dbgstr_tag(rec->dwManufacturer) ); + if (rec->dwManufacturer != hdr->phManufacturer) return FALSE; + } + if (rec->dwFields & ET_MODEL) + { + TRACE( "ET_MODEL: %s\n", MSCMS_dbgstr_tag(rec->dwModel) ); + if (rec->dwModel != hdr->phModel) return FALSE; + } + if (rec->dwFields & ET_ATTRIBUTES) + { + TRACE( "ET_ATTRIBUTES: 0x%08x, 0x%08x\n", + rec->dwAttributes[0], rec->dwAttributes[1] ); + if (rec->dwAttributes[0] != hdr->phAttributes[0] || + rec->dwAttributes[1] != hdr->phAttributes[1]) return FALSE; + } + if (rec->dwFields & ET_RENDERINGINTENT) + { + TRACE( "ET_RENDERINGINTENT: 0x%08x\n", rec->dwRenderingIntent ); + if (rec->dwRenderingIntent != hdr->phRenderingIntent) return FALSE; + } + if (rec->dwFields & ET_CREATOR) + { + TRACE( "ET_CREATOR: %s\n", MSCMS_dbgstr_tag(rec->dwCreator) ); + if (rec->dwCreator != hdr->phCreator) return FALSE; + } + return TRUE; +} + +/****************************************************************************** + * EnumColorProfilesA [MSCMS.@] + * + * See EnumColorProfilesW. + */ +BOOL WINAPI EnumColorProfilesA( PCSTR machine, PENUMTYPEA record, PBYTE buffer, + PDWORD size, PDWORD number ) +{ + BOOL match, ret = FALSE; + char spec[] = "\\*.icm"; + char colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL; + DWORD i, len = sizeof(colordir), count = 0, totalsize = 0; + PROFILEHEADER header; + WIN32_FIND_DATAA data; + ENUMTYPEW recordW; + WCHAR *fileW = NULL, *deviceW = NULL; + HANDLE find; + + TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number ); + + if (machine || !record || !size || + record->dwSize != sizeof(ENUMTYPEA) || + record->dwVersion != ENUM_TYPE_VERSION) return FALSE; + + ret = GetColorDirectoryA( machine, colordir, &len ); + if (!ret || len + sizeof(spec) > MAX_PATH) + { + WARN( "can't retrieve color directory\n" ); + return FALSE; + } + + lstrcpyA( glob, colordir ); + lstrcatA( glob, spec ); + + find = FindFirstFileA( glob, &data ); + if (find == INVALID_HANDLE_VALUE) return FALSE; + + profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(char *) + 1 ); + if (!profiles) goto exit; + + memcpy( &recordW, record, sizeof(ENUMTYPEA) ); + if (record->pDeviceName) + { + deviceW = MSCMS_strdupW( record->pDeviceName ); + if (!(recordW.pDeviceName = deviceW)) goto exit; + } + + fileW = MSCMS_strdupW( data.cFileName ); + if (!fileW) goto exit; + + ret = MSCMS_header_from_file( fileW, &header ); + if (ret) + { + match = MSCMS_match_profile( &recordW, &header ); + if (match) + { + len = sizeof(char) * (lstrlenA( data.cFileName ) + 1); + profiles[count] = HeapAlloc( GetProcessHeap(), 0, len ); + + if (!profiles[count]) goto exit; + else + { + TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) ); + lstrcpyA( profiles[count], data.cFileName ); + totalsize += len; + count++; + } + } + } + HeapFree( GetProcessHeap(), 0, fileW ); + fileW = NULL; + + while (FindNextFileA( find, &data )) + { + fileW = MSCMS_strdupW( data.cFileName ); + if (!fileW) goto exit; + + ret = MSCMS_header_from_file( fileW, &header ); + if (!ret) + { + HeapFree( GetProcessHeap(), 0, fileW ); + continue; + } + + match = MSCMS_match_profile( &recordW, &header ); + if (match) + { + char **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + profiles, sizeof(char *) * (count + 1) ); + if (!tmp) goto exit; + else profiles = tmp; + + len = sizeof(char) * (lstrlenA( data.cFileName ) + 1); + profiles[count] = HeapAlloc( GetProcessHeap(), 0, len ); + + if (!profiles[count]) goto exit; + else + { + TRACE( "matching profile: %s\n", debugstr_a(data.cFileName) ); + lstrcpyA( profiles[count], data.cFileName ); + totalsize += len; + count++; + } + } + HeapFree( GetProcessHeap(), 0, fileW ); + fileW = NULL; + } + + totalsize++; + if (buffer && *size >= totalsize) + { + char *p = (char *)buffer; + + for (i = 0; i < count; i++) + { + lstrcpyA( p, profiles[i] ); + p += lstrlenA( profiles[i] ) + 1; + } + *p = 0; + ret = TRUE; + } + else ret = FALSE; + + *size = totalsize; + if (number) *number = count; + +exit: + for (i = 0; i < count; i++) + HeapFree( GetProcessHeap(), 0, profiles[i] ); + HeapFree( GetProcessHeap(), 0, profiles ); + HeapFree( GetProcessHeap(), 0, deviceW ); + HeapFree( GetProcessHeap(), 0, fileW ); + FindClose( find ); + + return ret; +} + +/****************************************************************************** + * EnumColorProfilesW [MSCMS.@] + * + * Enumerate profiles that match given criteria. + * + * PARAMS + * machine [I] Name of the machine for which to enumerate profiles. + * Must be NULL, which indicates the local machine. + * record [I] Record of criteria that a profile must match. + * buffer [O] Buffer to receive a string array of profile filenames. + * size [I/O] Size of the filename buffer in bytes. + * number [O] Number of filenames copied into buffer. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI EnumColorProfilesW( PCWSTR machine, PENUMTYPEW record, PBYTE buffer, + PDWORD size, PDWORD number ) +{ + BOOL match, ret = FALSE; + WCHAR spec[] = {'\\','*','i','c','m',0}; + WCHAR colordir[MAX_PATH], glob[MAX_PATH], **profiles = NULL; + DWORD i, len = sizeof(colordir), count = 0, totalsize = 0; + PROFILEHEADER header; + WIN32_FIND_DATAW data; + HANDLE find; + + TRACE( "( %p, %p, %p, %p, %p )\n", machine, record, buffer, size, number ); + + if (machine || !record || !size || + record->dwSize != sizeof(ENUMTYPEW) || + record->dwVersion != ENUM_TYPE_VERSION) return FALSE; + + ret = GetColorDirectoryW( machine, colordir, &len ); + if (!ret || len + sizeof(spec) > MAX_PATH) + { + WARN( "Can't retrieve color directory\n" ); + return FALSE; + } + + lstrcpyW( glob, colordir ); + lstrcatW( glob, spec ); + + find = FindFirstFileW( glob, &data ); + if (find == INVALID_HANDLE_VALUE) return FALSE; + + profiles = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WCHAR *) + 1 ); + if (!profiles) goto exit; + + ret = MSCMS_header_from_file( data.cFileName, &header ); + if (ret) + { + match = MSCMS_match_profile( record, &header ); + if (match) + { + len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1); + profiles[count] = HeapAlloc( GetProcessHeap(), 0, len ); + + if (!profiles[count]) goto exit; + else + { + TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) ); + lstrcpyW( profiles[count], data.cFileName ); + totalsize += len; + count++; + } + } + } + + while (FindNextFileW( find, &data )) + { + ret = MSCMS_header_from_file( data.cFileName, &header ); + if (!ret) continue; + + match = MSCMS_match_profile( record, &header ); + if (match) + { + WCHAR **tmp = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, + profiles, sizeof(WCHAR *) * (count + 1) ); + if (!tmp) goto exit; + else profiles = tmp; + + len = sizeof(WCHAR) * (lstrlenW( data.cFileName ) + 1); + profiles[count] = HeapAlloc( GetProcessHeap(), 0, len ); + + if (!profiles[count]) goto exit; + else + { + TRACE( "matching profile: %s\n", debugstr_w(data.cFileName) ); + lstrcpyW( profiles[count], data.cFileName ); + totalsize += len; + count++; + } + } + } + + totalsize++; + if (buffer && *size >= totalsize) + { + WCHAR *p = (WCHAR *)buffer; + + for (i = 0; i < count; i++) + { + lstrcpyW( p, profiles[i] ); + p += lstrlenW( profiles[i] ) + 1; + } + *p = 0; + ret = TRUE; + } + else ret = FALSE; + + *size = totalsize; + if (number) *number = count; + +exit: + for (i = 0; i < count; i++) + HeapFree( GetProcessHeap(), 0, profiles[i] ); + HeapFree( GetProcessHeap(), 0, profiles ); + FindClose( find ); + + return ret; +} + +/****************************************************************************** + * InstallColorProfileA [MSCMS.@] + * + * See InstallColorProfileW. + */ +BOOL WINAPI InstallColorProfileA( PCSTR machine, PCSTR profile ) +{ + UINT len; + LPWSTR profileW; + BOOL ret = FALSE; + + TRACE( "( %s )\n", debugstr_a(profile) ); + + if (machine || !profile) return FALSE; + + len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 ); + profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + + if (profileW) + { + MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len ); + + ret = InstallColorProfileW( NULL, profileW ); + HeapFree( GetProcessHeap(), 0, profileW ); + } + return ret; +} + +/****************************************************************************** + * InstallColorProfileW [MSCMS.@] + * + * Install a color profile. + * + * PARAMS + * machine [I] Name of the machine to install the profile on. Must be NULL, + * which indicates the local machine. + * profile [I] Full path name of the profile to install. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI InstallColorProfileW( PCWSTR machine, PCWSTR profile ) +{ + WCHAR dest[MAX_PATH], base[MAX_PATH]; + DWORD size = sizeof(dest); + static const WCHAR slash[] = { '\\', 0 }; + + TRACE( "( %s )\n", debugstr_w(profile) ); + + if (machine || !profile) return FALSE; + + if (!GetColorDirectoryW( machine, dest, &size )) return FALSE; + + MSCMS_basename( profile, base ); + + lstrcatW( dest, slash ); + lstrcatW( dest, base ); + + /* Is source equal to destination? */ + if (!lstrcmpW( profile, dest )) return TRUE; + + return CopyFileW( profile, dest, TRUE ); +} + +/****************************************************************************** + * IsColorProfileTagPresent [MSCMS.@] + * + * Determine if a given ICC tag type is present in a color profile. + * + * PARAMS + * profile [I] Color profile handle. + * tag [I] ICC tag type. + * present [O] Pointer to a BOOL variable. Set to TRUE if tag type is present, + * FALSE otherwise. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI IsColorProfileTagPresent( HPROFILE handle, TAGTYPE type, PBOOL present ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + DWORD i, count; + icTag tag; + + TRACE( "( %p, 0x%08x, %p )\n", handle, type, present ); + + if (!profile) return FALSE; + + if (!present) + { + release_profile( profile ); + return FALSE; + } + count = MSCMS_get_tag_count( profile->iccprofile ); + + for (i = 0; i < count; i++) + { + MSCMS_get_tag_by_index( profile->iccprofile, i, &tag ); + + if (tag.sig == type) + { + *present = ret = TRUE; + break; + } + } + release_profile( profile ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * IsColorProfileValid [MSCMS.@] + * + * Determine if a given color profile is valid. + * + * PARAMS + * profile [I] Color profile handle. + * valid [O] Pointer to a BOOL variable. Set to TRUE if profile is valid, + * FALSE otherwise. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI IsColorProfileValid( HPROFILE handle, PBOOL valid ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + + TRACE( "( %p, %p )\n", handle, valid ); + + if (!profile) return FALSE; + + if (!valid) + { + release_profile( profile ); + return FALSE; + } + if (profile->iccprofile) ret = *valid = TRUE; + release_profile( profile ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * SetColorProfileElement [MSCMS.@] + * + * Set data for a specified tag type. + * + * PARAMS + * profile [I] Handle to a color profile. + * type [I] ICC tag type. + * offset [I] Offset in bytes to start copying to. + * size [I/O] Size of the buffer in bytes. On return the variable holds the + * number of bytes actually needed. + * buffer [O] Buffer holding the tag data. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI SetColorProfileElement( HPROFILE handle, TAGTYPE type, DWORD offset, PDWORD size, + PVOID buffer ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + DWORD i, count; + icTag tag; + + TRACE( "( %p, 0x%08x, %d, %p, %p )\n", handle, type, offset, size, buffer ); + + if (!profile) return FALSE; + + if (!size || !buffer || !(profile->access & PROFILE_READWRITE)) + { + release_profile( profile ); + return FALSE; + } + count = MSCMS_get_tag_count( profile->iccprofile ); + + for (i = 0; i < count; i++) + { + MSCMS_get_tag_by_index( profile->iccprofile, i, &tag ); + + if (tag.sig == type) + { + if (offset > tag.size) + { + release_profile( profile ); + return FALSE; + } + MSCMS_set_tag_data( profile->iccprofile, &tag, offset, buffer ); + + release_profile( profile ); + return TRUE; + } + } + release_profile( profile ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * SetColorProfileHeader [MSCMS.@] + * + * Set header data for a given profile. + * + * PARAMS + * profile [I] Handle to a color profile. + * header [I] Buffer holding the header data. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI SetColorProfileHeader( HPROFILE handle, PPROFILEHEADER header ) +{ +#ifdef HAVE_LCMS + struct profile *profile = grab_profile( handle ); + + TRACE( "( %p, %p )\n", handle, header ); + + if (!profile) return FALSE; + + if (!header || !(profile->access & PROFILE_READWRITE)) + { + release_profile( profile ); + return FALSE; + } + MSCMS_set_profile_header( profile->iccprofile, header ); + + release_profile( profile ); + return TRUE; + +#else + return FALSE; +#endif /* HAVE_LCMS */ +} + +/****************************************************************************** + * UninstallColorProfileA [MSCMS.@] + * + * See UninstallColorProfileW. + */ +BOOL WINAPI UninstallColorProfileA( PCSTR machine, PCSTR profile, BOOL delete ) +{ + UINT len; + LPWSTR profileW; + BOOL ret = FALSE; + + TRACE( "( %s, %x )\n", debugstr_a(profile), delete ); + + if (machine || !profile) return FALSE; + + len = MultiByteToWideChar( CP_ACP, 0, profile, -1, NULL, 0 ); + profileW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + + if (profileW) + { + MultiByteToWideChar( CP_ACP, 0, profile, -1, profileW, len ); + + ret = UninstallColorProfileW( NULL, profileW , delete ); + + HeapFree( GetProcessHeap(), 0, profileW ); + } + return ret; +} + +/****************************************************************************** + * UninstallColorProfileW [MSCMS.@] + * + * Uninstall a color profile. + * + * PARAMS + * machine [I] Name of the machine to uninstall the profile on. Must be NULL, + * which indicates the local machine. + * profile [I] Full path name of the profile to uninstall. + * delete [I] Bool that specifies whether the profile file should be deleted. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI UninstallColorProfileW( PCWSTR machine, PCWSTR profile, BOOL delete ) +{ + TRACE( "( %s, %x )\n", debugstr_w(profile), delete ); + + if (machine || !profile) return FALSE; + + if (delete) return DeleteFileW( profile ); + + return TRUE; +} + +/****************************************************************************** + * OpenColorProfileA [MSCMS.@] + * + * See OpenColorProfileW. + */ +HPROFILE WINAPI OpenColorProfileA( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation ) +{ + HPROFILE handle = NULL; + + TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation ); + + if (!profile || !profile->pProfileData) return NULL; + + /* No AW conversion needed for memory based profiles */ + if (profile->dwType & PROFILE_MEMBUFFER) + return OpenColorProfileW( profile, access, sharing, creation ); + + if (profile->dwType & PROFILE_FILENAME) + { + UINT len; + PROFILE profileW; + + profileW.dwType = profile->dwType; + + len = MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, NULL, 0 ); + profileW.pProfileData = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); + + if (profileW.pProfileData) + { + profileW.cbDataSize = len * sizeof(WCHAR); + MultiByteToWideChar( CP_ACP, 0, profile->pProfileData, -1, profileW.pProfileData, len ); + + handle = OpenColorProfileW( &profileW, access, sharing, creation ); + HeapFree( GetProcessHeap(), 0, profileW.pProfileData ); + } + } + return handle; +} + +/****************************************************************************** + * OpenColorProfileW [MSCMS.@] + * + * Open a color profile. + * + * PARAMS + * profile [I] Pointer to a color profile structure. + * access [I] Desired access. + * sharing [I] Sharing mode. + * creation [I] Creation mode. + * + * RETURNS + * Success: Handle to the opened profile. + * Failure: NULL + * + * NOTES + * Values for access: PROFILE_READ or PROFILE_READWRITE. + * Values for sharing: 0 (no sharing), FILE_SHARE_READ and/or FILE_SHARE_WRITE. + * Values for creation: one of CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, + * OPEN_ALWAYS, TRUNCATE_EXISTING. + * Sharing and creation flags are ignored for memory based profiles. + */ +HPROFILE WINAPI OpenColorProfileW( PPROFILE profile, DWORD access, DWORD sharing, DWORD creation ) +{ +#ifdef HAVE_LCMS + cmsHPROFILE cmsprofile = NULL; + icProfile *iccprofile = NULL; + HANDLE handle = INVALID_HANDLE_VALUE; + + TRACE( "( %p, 0x%08x, 0x%08x, 0x%08x )\n", profile, access, sharing, creation ); + + if (!profile || !profile->pProfileData) return NULL; + + if (profile->dwType == PROFILE_MEMBUFFER) + { + /* FIXME: access flags not implemented for memory based profiles */ + + if (!(iccprofile = HeapAlloc( GetProcessHeap(), 0, profile->cbDataSize ))) return NULL; + memcpy( iccprofile, profile->pProfileData, profile->cbDataSize ); + + cmsprofile = cmsOpenProfileFromMem( iccprofile, profile->cbDataSize ); + } + else if (profile->dwType == PROFILE_FILENAME) + { + DWORD size, read, flags = 0; + + TRACE( "profile file: %s\n", debugstr_w( profile->pProfileData ) ); + + if (access & PROFILE_READ) flags = GENERIC_READ; + if (access & PROFILE_READWRITE) flags = GENERIC_READ|GENERIC_WRITE; + + if (!flags) return NULL; + if (!sharing) sharing = FILE_SHARE_READ; + + handle = CreateFileW( profile->pProfileData, flags, sharing, NULL, creation, 0, NULL ); + if (handle == INVALID_HANDLE_VALUE) + { + WARN( "Unable to open color profile %u\n", GetLastError() ); + return NULL; + } + + if ((size = GetFileSize( handle, NULL )) == INVALID_FILE_SIZE) + { + ERR( "Unable to retrieve size of color profile\n" ); + CloseHandle( handle ); + return NULL; + } + + iccprofile = HeapAlloc( GetProcessHeap(), 0, size ); + if (!iccprofile) + { + ERR( "Unable to allocate memory for color profile\n" ); + CloseHandle( handle ); + return NULL; + } + + if (!ReadFile( handle, iccprofile, size, &read, NULL ) || read != size) + { + ERR( "Unable to read color profile\n" ); + + CloseHandle( handle ); + HeapFree( GetProcessHeap(), 0, iccprofile ); + return NULL; + } + + cmsprofile = cmsOpenProfileFromMem( iccprofile, size ); + } + else + { + ERR( "Invalid profile type %u\n", profile->dwType ); + return NULL; + } + + if (cmsprofile) + { + struct profile profile; + + profile.file = handle; + profile.access = access; + profile.iccprofile = iccprofile; + profile.cmsprofile = cmsprofile; + + return create_profile( &profile ); + } + +#endif /* HAVE_LCMS */ + return NULL; +} + +/****************************************************************************** + * CloseColorProfile [MSCMS.@] + * + * Close a color profile. + * + * PARAMS + * profile [I] Handle to the profile. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI CloseColorProfile( HPROFILE profile ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + + TRACE( "( %p )\n", profile ); + ret = close_profile( profile ); + +#endif /* HAVE_LCMS */ + return ret; +} diff --git a/reactos/dll/win32/mscms/stub.c b/reactos/dll/win32/mscms/stub.c new file mode 100644 index 00000000000..d7e6877f7fd --- /dev/null +++ b/reactos/dll/win32/mscms/stub.c @@ -0,0 +1,203 @@ +/* + * 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 "wine/debug.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "icm.h" + +#include "mscms_priv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + +BOOL WINAPI CheckBitmapBits( HTRANSFORM transform, PVOID srcbits, BMFORMAT format, DWORD width, + DWORD height, DWORD stride, PBYTE result, PBMCALLBACKFN callback, + LPARAM data ) +{ + FIXME( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, %p, 0x%08lx ) stub\n", + transform, srcbits, format, width, height, stride, result, callback, data ); + + return FALSE; +} + +BOOL WINAPI CheckColors( HTRANSFORM transform, PCOLOR colors, DWORD number, COLORTYPE type, + PBYTE result ) +{ + FIXME( "( %p, %p, 0x%08x, 0x%08x, %p ) stub\n", transform, colors, number, type, result ); + + return FALSE; +} + +BOOL WINAPI ConvertColorNameToIndex( HPROFILE profile, PCOLOR_NAME name, PDWORD index, DWORD count ) +{ + FIXME( "( %p, %p, %p, 0x%08x ) stub\n", profile, name, index, count ); + + return FALSE; +} + +BOOL WINAPI ConvertIndexToColorName( HPROFILE profile, PDWORD index, PCOLOR_NAME name, DWORD count ) +{ + FIXME( "( %p, %p, %p, 0x%08x ) stub\n", profile, index, name, count ); + + return FALSE; +} + +BOOL WINAPI CreateDeviceLinkProfile( PHPROFILE profiles, DWORD nprofiles, PDWORD intents, + DWORD nintents, DWORD flags, PBYTE *data, DWORD index ) +{ + FIXME( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x ) stub\n", + profiles, nprofiles, intents, nintents, flags, data, index ); + + return FALSE; +} + +BOOL WINAPI CreateProfileFromLogColorSpaceA( LPLOGCOLORSPACEA space, PBYTE *buffer ) +{ + FIXME( "( %p, %p ) stub\n", space, buffer ); + + return FALSE; +} + +BOOL WINAPI CreateProfileFromLogColorSpaceW( LPLOGCOLORSPACEW space, PBYTE *buffer ) +{ + FIXME( "( %p, %p ) stub\n", space, buffer ); + + return FALSE; +} + +DWORD WINAPI GenerateCopyFilePaths( LPCWSTR printer, LPCWSTR directory, LPBYTE clientinfo, + DWORD level, LPWSTR sourcedir, LPDWORD sourcedirsize, + LPWSTR targetdir, LPDWORD targetdirsize, DWORD flags ) +{ + FIXME( "( %s, %s, %p, 0x%08x, %p, %p, %p, %p, 0x%08x ) stub\n", + debugstr_w(printer), debugstr_w(directory), clientinfo, level, sourcedir, + sourcedirsize, targetdir, targetdirsize, flags ); + return ERROR_SUCCESS; +} + +DWORD WINAPI GetCMMInfo( HTRANSFORM transform, DWORD info ) +{ + FIXME( "( %p, 0x%08x ) stub\n", transform, info ); + + return 0; +} + +BOOL WINAPI GetNamedProfileInfo( HPROFILE profile, PNAMED_PROFILE_INFO info ) +{ + FIXME( "( %p, %p ) stub\n", profile, info ); + + return FALSE; +} + +BOOL WINAPI GetPS2ColorRenderingDictionary( HPROFILE profile, DWORD intent, PBYTE buffer, + PDWORD size, PBOOL binary ) +{ + FIXME( "( %p, 0x%08x, %p, %p, %p ) stub\n", profile, intent, buffer, size, binary ); + + return FALSE; +} + +BOOL WINAPI GetPS2ColorRenderingIntent( HPROFILE profile, DWORD intent, PBYTE buffer, PDWORD size ) +{ + FIXME( "( %p, 0x%08x, %p, %p ) stub\n", profile, intent, buffer, size ); + + return FALSE; +} + +BOOL WINAPI GetPS2ColorSpaceArray( HPROFILE profile, DWORD intent, DWORD type, PBYTE buffer, + PDWORD size, PBOOL binary ) +{ + FIXME( "( %p, 0x%08x, 0x%08x, %p, %p, %p ) stub\n", profile, intent, type, buffer, size, binary ); + + return FALSE; +} + +BOOL WINAPI RegisterCMMA( PCSTR machine, DWORD id, PCSTR dll ) +{ + FIXME( "( %p, 0x%08x, %p ) stub\n", machine, id, dll ); + + return TRUE; +} + +BOOL WINAPI RegisterCMMW( PCWSTR machine, DWORD id, PCWSTR dll ) +{ + FIXME( "( %p, 0x%08x, %p ) stub\n", machine, id, dll ); + + return TRUE; +} + +BOOL WINAPI SelectCMM( DWORD id ) +{ + FIXME( "(%x) stub\n", id ); + + return TRUE; +} + +BOOL WINAPI SetColorProfileElementReference( HPROFILE profile, TAGTYPE type, TAGTYPE ref ) +{ + FIXME( "( %p, 0x%08x, 0x%08x ) stub\n", profile, type, ref ); + + return TRUE; +} + +BOOL WINAPI SetColorProfileElementSize( HPROFILE profile, TAGTYPE type, DWORD size ) +{ + FIXME( "( %p, 0x%08x, 0x%08x ) stub\n", profile, type, size ); + + return FALSE; +} + +BOOL WINAPI SetStandardColorSpaceProfileA( PCSTR machine, DWORD id, PSTR profile ) +{ + FIXME( "( 0x%08x, %p ) stub\n", id, profile ); + return TRUE; +} + +BOOL WINAPI SetStandardColorSpaceProfileW( PCWSTR machine, DWORD id, PWSTR profile ) +{ + FIXME( "( 0x%08x, %p ) stub\n", id, profile ); + return TRUE; +} + +BOOL WINAPI SpoolerCopyFileEvent( LPWSTR printer, LPWSTR key, DWORD event ) +{ + FIXME( "( %s, %s, 0x%08x ) stub\n", debugstr_w(printer), debugstr_w(key), event ); + return TRUE; +} + +BOOL WINAPI UnregisterCMMA( PCSTR machine, DWORD id ) +{ + FIXME( "( %p, 0x%08x ) stub\n", machine, id ); + + return TRUE; +} + +BOOL WINAPI UnregisterCMMW( PCWSTR machine, DWORD id ) +{ + FIXME( "( %p, 0x%08x ) stub\n", machine, id ); + + return TRUE; +} diff --git a/reactos/dll/win32/mscms/transform.c b/reactos/dll/win32/mscms/transform.c new file mode 100644 index 00000000000..a795386d35f --- /dev/null +++ b/reactos/dll/win32/mscms/transform.c @@ -0,0 +1,451 @@ +/* + * MSCMS - Color Management System for Wine + * + * Copyright 2005, 2006, 2008 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 "wine/debug.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "winnls.h" +#include "wingdi.h" +#include "winuser.h" +#include "icm.h" + +#include "mscms_priv.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mscms); + +#ifdef HAVE_LCMS + +static DWORD from_profile( HPROFILE profile ) +{ + PROFILEHEADER header; + + GetColorProfileHeader( profile, &header ); + TRACE( "color space: 0x%08x %s\n", header.phDataColorSpace, MSCMS_dbgstr_tag( header.phDataColorSpace ) ); + + switch (header.phDataColorSpace) + { + case 0x434d594b: return TYPE_CMYK_16; /* 'CMYK' */ + case 0x47524159: return TYPE_GRAY_16; /* 'GRAY' */ + case 0x4c616220: return TYPE_Lab_16; /* 'Lab ' */ + case 0x52474220: return TYPE_RGB_16; /* 'RGB ' */ + case 0x58595a20: return TYPE_XYZ_16; /* 'XYZ ' */ + default: + WARN("unhandled format\n"); + return TYPE_RGB_16; + } +} + +static DWORD from_bmformat( BMFORMAT format ) +{ + static int quietfixme = 0; + TRACE( "bitmap format: 0x%08x\n", format ); + + switch (format) + { + case BM_RGBTRIPLETS: return TYPE_RGB_8; + case BM_BGRTRIPLETS: return TYPE_BGR_8; + case BM_GRAY: return TYPE_GRAY_8; + default: + if (quietfixme == 0) + { + FIXME("unhandled bitmap format 0x%x\n", format); + quietfixme = 1; + } + return TYPE_RGB_8; + } +} + +static DWORD from_type( COLORTYPE type ) +{ + TRACE( "color type: 0x%08x\n", type ); + + switch (type) + { + case COLOR_GRAY: return TYPE_GRAY_16; + case COLOR_RGB: return TYPE_RGB_16; + case COLOR_XYZ: return TYPE_XYZ_16; + case COLOR_Yxy: return TYPE_Yxy_16; + case COLOR_Lab: return TYPE_Lab_16; + case COLOR_CMYK: return TYPE_CMYK_16; + default: + FIXME("unhandled color type\n"); + return TYPE_RGB_16; + } +} + +#endif /* HAVE_LCMS */ + +/****************************************************************************** + * CreateColorTransformA [MSCMS.@] + * + * See CreateColorTransformW. + */ +HTRANSFORM WINAPI CreateColorTransformA( LPLOGCOLORSPACEA space, HPROFILE dest, + HPROFILE target, DWORD flags ) +{ + LOGCOLORSPACEW spaceW; + DWORD len; + + TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags ); + + if (!space || !dest) return FALSE; + + memcpy( &spaceW, space, FIELD_OFFSET(LOGCOLORSPACEA, lcsFilename) ); + spaceW.lcsSize = sizeof(LOGCOLORSPACEW); + + len = MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, NULL, 0 ); + MultiByteToWideChar( CP_ACP, 0, space->lcsFilename, -1, spaceW.lcsFilename, len ); + + return CreateColorTransformW( &spaceW, dest, target, flags ); +} + +/****************************************************************************** + * CreateColorTransformW [MSCMS.@] + * + * Create a color transform. + * + * PARAMS + * space [I] Input color space. + * dest [I] Color profile of destination device. + * target [I] Color profile of target device. + * flags [I] Flags. + * + * RETURNS + * Success: Handle to a transform. + * Failure: NULL + */ +HTRANSFORM WINAPI CreateColorTransformW( LPLOGCOLORSPACEW space, HPROFILE dest, + HPROFILE target, DWORD flags ) +{ + HTRANSFORM ret = NULL; +#ifdef HAVE_LCMS + struct transform transform; + struct profile *dst, *tgt = NULL; + cmsHPROFILE cmsinput, cmsoutput, cmstarget = NULL; + DWORD in_format, out_format, proofing = 0; + int intent; + + TRACE( "( %p, %p, %p, 0x%08x )\n", space, dest, target, flags ); + + if (!space || !(dst = grab_profile( dest ))) return FALSE; + + if (target && !(tgt = grab_profile( target ))) + { + release_profile( dst ); + return FALSE; + } + intent = space->lcsIntent > 3 ? INTENT_PERCEPTUAL : space->lcsIntent; + + TRACE( "lcsIntent: %x\n", space->lcsIntent ); + TRACE( "lcsCSType: %s\n", MSCMS_dbgstr_tag( space->lcsCSType ) ); + TRACE( "lcsFilename: %s\n", debugstr_w( space->lcsFilename ) ); + + in_format = TYPE_RGB_16; + out_format = from_profile( dest ); + + cmsinput = cmsCreate_sRGBProfile(); /* FIXME: create from supplied color space */ + if (target) + { + proofing = cmsFLAGS_SOFTPROOFING; + cmstarget = tgt->cmsprofile; + } + cmsoutput = dst->cmsprofile; + transform.cmstransform = cmsCreateProofingTransform(cmsinput, in_format, cmsoutput, out_format, cmstarget, + intent, INTENT_ABSOLUTE_COLORIMETRIC, proofing); + + ret = create_transform( &transform ); + + if (tgt) release_profile( tgt ); + release_profile( dst ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * CreateMultiProfileTransform [MSCMS.@] + * + * Create a color transform from an array of color profiles. + * + * PARAMS + * profiles [I] Array of color profiles. + * nprofiles [I] Number of color profiles. + * intents [I] Array of rendering intents. + * flags [I] Flags. + * cmm [I] Profile to take the CMM from. + * + * RETURNS + * Success: Handle to a transform. + * Failure: NULL + */ +HTRANSFORM WINAPI CreateMultiProfileTransform( PHPROFILE profiles, DWORD nprofiles, + PDWORD intents, DWORD nintents, DWORD flags, DWORD cmm ) +{ + HTRANSFORM ret = NULL; +#ifdef HAVE_LCMS + cmsHPROFILE *cmsprofiles, cmsconvert = NULL; + struct transform transform; + struct profile *profile0, *profile1; + DWORD in_format, out_format; + + TRACE( "( %p, 0x%08x, %p, 0x%08x, 0x%08x, 0x%08x )\n", + profiles, nprofiles, intents, nintents, flags, cmm ); + + if (!profiles || !nprofiles || !intents) return NULL; + + if (nprofiles > 2) + { + FIXME("more than 2 profiles not supported\n"); + return NULL; + } + + profile0 = grab_profile( profiles[0] ); + if (!profile0) return NULL; + profile1 = grab_profile( profiles[1] ); + if (!profile1) + { + release_profile( profile0 ); + return NULL; + } + in_format = from_profile( profiles[0] ); + out_format = from_profile( profiles[nprofiles - 1] ); + + if (in_format != out_format) + { + /* insert a conversion profile for pairings that lcms doesn't handle */ + if (out_format == TYPE_RGB_16) cmsconvert = cmsCreate_sRGBProfile(); + if (out_format == TYPE_Lab_16) cmsconvert = cmsCreateLabProfile( NULL ); + } + + cmsprofiles = HeapAlloc( GetProcessHeap(), 0, (nprofiles + 1) * sizeof(cmsHPROFILE *) ); + if (cmsprofiles) + { + cmsprofiles[0] = profile0->cmsprofile; + if (cmsconvert) + { + cmsprofiles[1] = cmsconvert; + cmsprofiles[2] = profile1->cmsprofile; + nprofiles++; + } + else + { + cmsprofiles[1] = profile1->cmsprofile; + } + transform.cmstransform = cmsCreateMultiprofileTransform( cmsprofiles, nprofiles, in_format, out_format, *intents, 0 ); + + HeapFree( GetProcessHeap(), 0, cmsprofiles ); + ret = create_transform( &transform ); + } + + release_profile( profile0 ); + release_profile( profile1 ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * DeleteColorTransform [MSCMS.@] + * + * Delete a color transform. + * + * PARAMS + * transform [I] Handle to a color transform. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI DeleteColorTransform( HTRANSFORM handle ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + + TRACE( "( %p )\n", handle ); + + ret = close_transform( handle ); + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * TranslateBitmapBits [MSCMS.@] + * + * Perform color translation. + * + * PARAMS + * transform [I] Handle to a color transform. + * srcbits [I] Source bitmap. + * input [I] Format of the source bitmap. + * width [I] Width of the source bitmap. + * height [I] Height of the source bitmap. + * inputstride [I] Number of bytes in one scanline. + * destbits [I] Destination bitmap. + * output [I] Format of the destination bitmap. + * outputstride [I] Number of bytes in one scanline. + * callback [I] Callback function. + * data [I] Callback data. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI TranslateBitmapBits( HTRANSFORM handle, PVOID srcbits, BMFORMAT input, + DWORD width, DWORD height, DWORD inputstride, PVOID destbits, BMFORMAT output, + DWORD outputstride, PBMCALLBACKFN callback, ULONG data ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct transform *transform = grab_transform( handle ); + + TRACE( "( %p, %p, 0x%08x, 0x%08x, 0x%08x, 0x%08x, %p, 0x%08x, 0x%08x, %p, 0x%08x )\n", + handle, srcbits, input, width, height, inputstride, destbits, output, + outputstride, callback, data ); + + if (!transform) return FALSE; + cmsChangeBuffersFormat( transform->cmstransform, from_bmformat(input), from_bmformat(output) ); + + cmsDoTransform( transform->cmstransform, srcbits, destbits, width * height ); + release_transform( transform ); + ret = TRUE; + +#endif /* HAVE_LCMS */ + return ret; +} + +/****************************************************************************** + * TranslateColors [MSCMS.@] + * + * Perform color translation. + * + * PARAMS + * transform [I] Handle to a color transform. + * input [I] Array of input colors. + * number [I] Number of colors to translate. + * input_type [I] Input color format. + * output [O] Array of output colors. + * output_type [I] Output color format. + * + * RETURNS + * Success: TRUE + * Failure: FALSE + */ +BOOL WINAPI TranslateColors( HTRANSFORM handle, PCOLOR in, DWORD count, + COLORTYPE input_type, PCOLOR out, COLORTYPE output_type ) +{ + BOOL ret = FALSE; +#ifdef HAVE_LCMS + struct transform *transform = grab_transform( handle ); + cmsHTRANSFORM xfrm; + unsigned int i; + + TRACE( "( %p, %p, %d, %d, %p, %d )\n", handle, in, count, input_type, out, output_type ); + + if (!transform) return FALSE; + + xfrm = transform->cmstransform; + cmsChangeBuffersFormat( xfrm, from_type(input_type), from_type(output_type) ); + + switch (input_type) + { + case COLOR_RGB: + { + switch (output_type) + { + case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].rgb, 1 ); return TRUE; + case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].Lab, 1 ); return TRUE; + case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].gray, 1 ); return TRUE; + case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].cmyk, 1 ); return TRUE; + case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].rgb, &out[i].XYZ, 1 ); return TRUE; + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + return FALSE; + } + } + case COLOR_Lab: + { + switch (output_type) + { + case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].rgb, 1 ); return TRUE; + case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].Lab, 1 ); return TRUE; + case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].gray, 1 ); return TRUE; + case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].cmyk, 1 ); return TRUE; + case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].Lab, &out[i].XYZ, 1 ); return TRUE; + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + return FALSE; + } + } + case COLOR_GRAY: + { + switch (output_type) + { + case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].rgb, 1 ); return TRUE; + case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].Lab, 1 ); return TRUE; + case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].gray, 1 ); return TRUE; + case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].cmyk, 1 ); return TRUE; + case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].gray, &out[i].XYZ, 1 ); return TRUE; + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + return FALSE; + } + } + case COLOR_CMYK: + { + switch (output_type) + { + case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].rgb, 1 ); return TRUE; + case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].Lab, 1 ); return TRUE; + case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].gray, 1 ); return TRUE; + case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].cmyk, 1 ); return TRUE; + case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].cmyk, &out[i].XYZ, 1 ); return TRUE; + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + return FALSE; + } + } + case COLOR_XYZ: + { + switch (output_type) + { + case COLOR_RGB: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].rgb, 1 ); return TRUE; + case COLOR_Lab: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].Lab, 1 ); return TRUE; + case COLOR_GRAY: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].gray, 1 ); return TRUE; + case COLOR_CMYK: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].cmyk, 1 ); return TRUE; + case COLOR_XYZ: for (i = 0; i < count; i++) cmsDoTransform( xfrm, &in[i].XYZ, &out[i].XYZ, 1 ); return TRUE; + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + return FALSE; + } + } + default: + FIXME("unhandled input/output pair: %d/%d\n", input_type, output_type); + break; + } + release_transform( transform ); + +#endif /* HAVE_LCMS */ + return ret; +} diff --git a/reactos/dll/win32/mscms/version.rc b/reactos/dll/win32/mscms/version.rc new file mode 100644 index 00000000000..11ebdd64b09 --- /dev/null +++ b/reactos/dll/win32/mscms/version.rc @@ -0,0 +1,24 @@ +/* + * Version information for mscms.dll + * + * Copyright 2004 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 + */ + +#define WINE_FILEDESCRIPTION_STR "Wine Color Management System" +#define WINE_FILENAME_STR "mscms.dll" + +#include diff --git a/reactos/dll/win32/msftedit/msftedit.rbuild b/reactos/dll/win32/msftedit/msftedit.rbuild new file mode 100644 index 00000000000..f9dd7bab417 --- /dev/null +++ b/reactos/dll/win32/msftedit/msftedit.rbuild @@ -0,0 +1,13 @@ + + + . + include/reactos/wine + + msftedit_main.c + version.rc + wine + uuid + riched20 + kernel32 + ntdll + diff --git a/reactos/dll/win32/msftedit/msftedit.spec b/reactos/dll/win32/msftedit/msftedit.spec new file mode 100644 index 00000000000..0dd878d585a --- /dev/null +++ b/reactos/dll/win32/msftedit/msftedit.spec @@ -0,0 +1,14 @@ +2 extern IID_IRichEditOle +3 extern IID_IRichEditOleCallback +4 stdcall CreateTextServices(ptr ptr ptr) riched20.CreateTextServices +5 extern IID_ITextServices +6 extern IID_ITextHost +7 extern IID_ITextHost2 +8 stdcall REExtendedRegisterClass() riched20.REExtendedRegisterClass +9 stdcall RichEdit10ANSIWndProc(ptr long long long) riched20.RichEdit10ANSIWndProc +10 stdcall RichEditANSIWndProc(ptr long long long) riched20.RichEditANSIWndProc +11 stub SetCustomTextOutHandlerEx +12 stdcall -private DllGetVersion(ptr) +13 stub RichEditWndProc +14 stub RichListBoxWndProc +15 stub RichComboBoxWndProc diff --git a/reactos/dll/win32/msftedit/msftedit_main.c b/reactos/dll/win32/msftedit/msftedit_main.c new file mode 100644 index 00000000000..b505999cdad --- /dev/null +++ b/reactos/dll/win32/msftedit/msftedit_main.c @@ -0,0 +1,80 @@ +/* + * msftedit main file + * + * Copyright (C) 2008 Rico Schüller + * + * 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 "wine/port.h" + +#include + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "wingdi.h" +#include "winuser.h" +#include "richedit.h" +#include "imm.h" +#include "shlwapi.h" +#include "oleidl.h" +#include "initguid.h" +#include "textserv.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msftedit); + +/*********************************************************************** + * DllMain. + */ +BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) +{ + static const WCHAR riched20W[] = {'r','i','c','h','e','d','2','0','.','d','l','l',0}; + static HMODULE richedit; + + switch(reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + case DLL_PROCESS_ATTACH: + /* explicitly load riched20 since it creates the window classes at dll attach time */ + richedit = LoadLibraryW( riched20W ); + DisableThreadLibraryCalls(inst); + break; + case DLL_PROCESS_DETACH: + FreeLibrary( richedit ); + break; + } + return TRUE; +} + +/*********************************************************************** + * DllGetVersion (msftedit.@) + */ +HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *info) +{ + if (info->cbSize != sizeof(DLLVERSIONINFO)) FIXME("support DLLVERSIONINFO2\n"); + + /* this is what WINXP SP2 reports */ + info->dwMajorVersion = 41; + info->dwMinorVersion = 15; + info->dwBuildNumber = 1507; + info->dwPlatformID = 1; + return NOERROR; +} diff --git a/reactos/dll/win32/msftedit/version.rc b/reactos/dll/win32/msftedit/version.rc new file mode 100644 index 00000000000..ce5ef0e7b32 --- /dev/null +++ b/reactos/dll/win32/msftedit/version.rc @@ -0,0 +1,26 @@ +/* + * Copyright 2008 Rico Schüller + * + * 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 + */ + +#define WINE_FILEDESCRIPTION_STR "Rich Text Edit Control" +#define WINE_FILENAME_STR "msftedit.dll" +#define WINE_FILEVERSION 5,41,15,1509 +#define WINE_FILEVERSION_STR "5,41,15,1509" +#define WINE_PRODUCTVERSION 5,41,15,1509 +#define WINE_PRODUCTVERSION_STR "5,41,15,1509" + +#include "wine/wine_common_ver.rc" diff --git a/reactos/dll/win32/msrle32/msrle32.c b/reactos/dll/win32/msrle32/msrle32.c new file mode 100644 index 00000000000..b0354b9be2f --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle32.c @@ -0,0 +1,1924 @@ +/* + * Copyright 2002-2003 Michael Günnewig + * + * 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 + */ + +/* TODO: + * - some improvements possible + * - implement DecompressSetPalette? -- do we need it for anything? + */ + +#include + +#include "msrle_private.h" + +#include "winnls.h" +#include "winuser.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msrle32); + +static HINSTANCE MSRLE32_hModule = 0; + +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define SQR(a) ((a) * (a)) + +#define QUALITY_to_DIST(q) (ICQUALITY_HIGH - q) +static inline WORD ColorCmp(WORD clr1, WORD clr2) +{ + register UINT a = (clr1-clr2); + return SQR(a); +} +static inline WORD Intensity(RGBQUAD clr) +{ + return (30 * clr.rgbRed + 59 * clr.rgbGreen + 11 * clr.rgbBlue)/4; +} + +#define GetRawPixel(lpbi,lp,x) \ + ((lpbi)->biBitCount == 1 ? ((lp)[(x)/8] >> (8 - (x)%8)) & 1 : \ + ((lpbi)->biBitCount == 4 ? ((lp)[(x)/2] >> (4 * (1 - (x)%2))) & 15 : lp[x])) + +/*****************************************************************************/ + +/* utility functions */ +static BOOL isSupportedDIB(LPCBITMAPINFOHEADER lpbi); +static BOOL isSupportedMRLE(LPCBITMAPINFOHEADER lpbi); +static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQUAD clr); + +/* compression functions */ +static void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn); +static LONG MSRLE32_GetMaxCompressedSize(LPCBITMAPINFOHEADER lpbi); +static LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, + LPBYTE lpOut, BOOL isKey); +static LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, + LPBYTE lpOut, BOOL isKey); + +/* decompression functions */ +static LRESULT MSRLE32_DecompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LPBYTE lpOut); +static LRESULT MSRLE32_DecompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LPBYTE lpOut); + +/* API functions */ +static LRESULT CompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut); +static LRESULT CompressGetSize(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut); +static LRESULT CompressQuery(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut); +static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut); +static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize); +static LRESULT CompressEnd(CodecInfo *pi); + +static LRESULT DecompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut); +static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut); +static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut); +static LRESULT Decompress(CodecInfo *pi, ICDECOMPRESS *pic, DWORD dwSize); +static LRESULT DecompressEnd(CodecInfo *pi); +static LRESULT DecompressGetPalette(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut); + +/*****************************************************************************/ + +static BOOL isSupportedMRLE(LPCBITMAPINFOHEADER lpbi) +{ + /* pre-conditions */ + assert(lpbi != NULL); + + if (lpbi->biSize < sizeof(BITMAPINFOHEADER) || + lpbi->biPlanes != 1) + return FALSE; + + if (lpbi->biCompression == BI_RLE4) { + if (lpbi->biBitCount != 4 || + (lpbi->biWidth % 2) != 0) + return FALSE; + } else if (lpbi->biCompression == BI_RLE8) { + if (lpbi->biBitCount != 8) + return FALSE; + } else + return FALSE; + + return TRUE; +} + +static BOOL isSupportedDIB(LPCBITMAPINFOHEADER lpbi) +{ + /* pre-conditions */ + assert(lpbi != NULL); + + /* check structure version/planes/compression */ + if (lpbi->biSize < sizeof(BITMAPINFOHEADER) || + lpbi->biPlanes != 1) + return FALSE; + if (lpbi->biCompression != BI_RGB && + lpbi->biCompression != BI_BITFIELDS) + return FALSE; + + /* check bit-depth */ + if (lpbi->biBitCount != 1 && + lpbi->biBitCount != 4 && + lpbi->biBitCount != 8 && + lpbi->biBitCount != 15 && + lpbi->biBitCount != 16 && + lpbi->biBitCount != 24 && + lpbi->biBitCount != 32) + return FALSE; + + /* check for size(s) */ + if (!lpbi->biWidth || !lpbi->biHeight) + return FALSE; /* image with zero size, makes no sense so error ! */ + if (DIBWIDTHBYTES(*lpbi) * (DWORD)lpbi->biHeight >= (1UL << 31) - 1) + return FALSE; /* image too big ! */ + + /* check for nonexistent colortable for hi- and true-color DIB's */ + if (lpbi->biBitCount >= 15 && lpbi->biClrUsed > 0) + return FALSE; + + return TRUE; +} + +static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQUAD clr) +{ + INT diff = 0x00FFFFFF; + UINT i; + UINT idx = 0; + + /* pre-conditions */ + assert(clrs != NULL); + + for (i = 0; i < count; i++) { + int r = ((int)clrs[i].rgbRed - (int)clr.rgbRed); + int g = ((int)clrs[i].rgbGreen - (int)clr.rgbGreen); + int b = ((int)clrs[i].rgbBlue - (int)clr.rgbBlue); + + r = r*r + g*g + b*b; + + if (r < diff) { + idx = i; + diff = r; + if (diff == 0) + break; + } + } + + return idx; +} + +/*****************************************************************************/ + +void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, const BYTE *lpIn) +{ + WORD wIntensityTbl[256]; + DWORD lInLine, lOutLine; + LPWORD lpOut; + UINT i; + LONG y; + + /* pre-conditions */ + assert(pi != NULL && lpbiIn != NULL && lpIn != NULL); + assert(pi->pCurFrame != NULL); + + lInLine = DIBWIDTHBYTES(*lpbiIn); + lOutLine = WIDTHBYTES((WORD)lpbiIn->biWidth * 8u * sizeof(WORD)) / 2u; + lpOut = pi->pCurFrame; + + assert(lpbiIn->biClrUsed != 0); + + { + const RGBQUAD *lp = + (const RGBQUAD *)((const BYTE*)lpbiIn + lpbiIn->biSize); + + for (i = 0; i < lpbiIn->biClrUsed; i++) + wIntensityTbl[i] = Intensity(lp[i]); + } + + for (y = 0; y < lpbiIn->biHeight; y++) { + LONG x; + + switch (lpbiIn->biBitCount) { + case 1: + for (x = 0; x < lpbiIn->biWidth / 8; x++) { + for (i = 0; i < 7; i++) + lpOut[8 * x + i] = wIntensityTbl[(lpIn[x] >> (7 - i)) & 1]; + } + break; + case 4: + for (x = 0; x < lpbiIn->biWidth / 2; x++) { + lpOut[2 * x + 0] = wIntensityTbl[(lpIn[x] >> 4)]; + lpOut[2 * x + 1] = wIntensityTbl[(lpIn[x] & 0x0F)]; + } + break; + case 8: + for (x = 0; x < lpbiIn->biWidth; x++) + lpOut[x] = wIntensityTbl[lpIn[x]]; + break; + } + + lpIn += lInLine; + lpOut += lOutLine; + } +} + +static LONG MSRLE32_GetMaxCompressedSize(LPCBITMAPINFOHEADER lpbi) +{ + LONG a, b, size; + + /* pre-condition */ + assert(lpbi != NULL); + + a = lpbi->biWidth / 255; + b = lpbi->biWidth % 255; + if (lpbi->biBitCount <= 4) { + a /= 2; + b /= 2; + } + + size = (2 + a * (2 + ((a + 2) & ~2)) + b * (2 + ((b + 2) & ~2))); + return size * lpbi->biHeight; +} + +/* lpP => current pos in previous frame + * lpA => previous pos in current frame + * lpB => current pos in current frame + */ +static INT countDiffRLE4(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width) +{ + INT count; + WORD clr1, clr2; + + /* pre-conditions */ + assert(lpA && lpB && lDist >= 0 && width > 0); + + if (pos >= width) + return 0; + if (pos+1 == width) + return 1; + + clr1 = lpB[pos++]; + clr2 = lpB[pos]; + + count = 2; + while (pos + 1 < width) { + WORD clr3, clr4; + + clr3 = lpB[++pos]; + if (pos + 1 >= width) + return count + 1; + + clr4 = lpB[++pos]; + if (ColorCmp(clr1, clr3) <= lDist && + ColorCmp(clr2, clr4) <= lDist) { + /* diff at end? -- look-ahead for at least ?? more encodable pixels */ + if (pos + 2 < width && ColorCmp(clr1,lpB[pos+1]) <= lDist && + ColorCmp(clr2,lpB[pos+2]) <= lDist) { + if (pos + 4 < width && ColorCmp(lpB[pos+1],lpB[pos+3]) <= lDist && + ColorCmp(lpB[pos+2],lpB[pos+4]) <= lDist) + return count - 3; /* followed by at least 4 encodable pixels */ + return count - 2; + } + } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) { + /* 'compare' with previous frame for end of diff */ + INT count2 = 0; + + /* FIXME */ + + if (count2 >= 8) + return count; + + pos -= count2; + } + + count += 2; + clr1 = clr3; + clr2 = clr4; + } + + return count; +} + +/* lpP => current pos in previous frame + * lpA => previous pos in current frame + * lpB => current pos in current frame + */ +static INT countDiffRLE8(const WORD *lpP, const WORD *lpA, const WORD *lpB, INT pos, LONG lDist, LONG width) +{ + INT count; + + for (count = 0; pos < width; pos++, count++) { + if (ColorCmp(lpA[pos], lpB[pos]) <= lDist) { + /* diff at end? -- look-ahead for some more encodable pixel */ + if (pos + 1 < width && ColorCmp(lpB[pos], lpB[pos+1]) <= lDist) + return count - 1; + if (pos + 2 < width && ColorCmp(lpB[pos+1], lpB[pos+2]) <= lDist) + return count - 1; + } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) { + /* 'compare' with previous frame for end of diff */ + INT count2 = 0; + + for (count2 = 0, pos++; pos < width && count2 <= 5; pos++, count2++) { + if (ColorCmp(lpP[pos], lpB[pos]) > lDist) + break; + } + if (count2 > 4) + return count; + + pos -= count2; + } + } + + return count; +} + +static INT MSRLE32_CompressRLE4Line(const CodecInfo *pi, const WORD *lpP, + const WORD *lpC, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LONG lDist, + INT x, LPBYTE *ppOut, + DWORD *lpSizeImage) +{ + LPBYTE lpOut = *ppOut; + INT count, pos; + WORD clr1, clr2; + + /* try to encode as many pixel as possible */ + count = 1; + pos = x; + clr1 = lpC[pos++]; + if (pos < lpbi->biWidth) { + clr2 = lpC[pos]; + for (++count; pos + 1 < lpbi->biWidth; ) { + ++pos; + if (ColorCmp(clr1, lpC[pos]) > lDist) + break; + count++; + if (pos + 1 >= lpbi->biWidth) + break; + ++pos; + if (ColorCmp(clr2, lpC[pos]) > lDist) + break; + count++; + } + } + + if (count < 4) { + /* add some pixel for absoluting if possible */ + count += countDiffRLE4(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth); + + assert(count > 0); + + /* check for near end of line */ + if (x + count > lpbi->biWidth) + count = lpbi->biWidth - x; + + /* absolute pixel(s) in groups of at least 3 and at most 254 pixels */ + while (count > 2) { + INT i; + INT size = min(count, 254); + int bytes = ((size + 1) & (~1)) / 2; + int extra_byte = bytes & 0x01; + + *lpSizeImage += 2 + bytes + extra_byte; + assert(((*lpSizeImage) % 2) == 0); + count -= size; + *lpOut++ = 0; + *lpOut++ = size; + for (i = 0; i < size; i += 2) { + clr1 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + if (i + 1 < size) { + clr2 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + } else + clr2 = 0; + + *lpOut++ = (clr1 << 4) | clr2; + } + if (extra_byte) + *lpOut++ = 0; + } + + if (count > 0) { + /* too little for absoluting so we must encode them */ + assert(count <= 2); + + *lpSizeImage += 2; + clr1 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + if (count == 2) { + clr2 = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + } else + clr2 = 0; + *lpOut++ = count; + *lpOut++ = (clr1 << 4) | clr2; + } + } else { + /* encode count pixel(s) */ + clr1 = ((pi->palette_map[GetRawPixel(lpbi,lpIn,x)] << 4) | + pi->palette_map[GetRawPixel(lpbi,lpIn,x + 1)]); + + x += count; + while (count > 0) { + INT size = min(count, 254); + + *lpSizeImage += 2; + count -= size; + *lpOut++ = size; + *lpOut++ = clr1; + } + } + + *ppOut = lpOut; + + return x; +} + +static INT MSRLE32_CompressRLE8Line(const CodecInfo *pi, const WORD *lpP, + const WORD *lpC, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LONG lDist, + INT x, LPBYTE *ppOut, + DWORD *lpSizeImage) +{ + LPBYTE lpOut = *ppOut; + INT count, pos; + WORD clr; + + assert(lpbi->biBitCount <= 8); + assert(lpbi->biCompression == BI_RGB); + + /* try to encode as much as possible */ + pos = x; + clr = lpC[pos++]; + for (count = 1; pos < lpbi->biWidth; count++) { + if (ColorCmp(clr, lpC[pos++]) > lDist) + break; + } + + if (count < 2) { + /* add some more pixels for absoluting if possible */ + count += countDiffRLE8(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth); + + assert(count > 0); + + /* check for over end of line */ + if (x + count > lpbi->biWidth) + count = lpbi->biWidth - x; + + /* absolute pixel(s) in groups of at least 3 and at most 255 pixels */ + while (count > 2) { + INT i; + INT size = min(count, 255); + int extra_byte = size % 2; + + *lpSizeImage += 2 + size + extra_byte; + count -= size; + *lpOut++ = 0; + *lpOut++ = size; + for (i = 0; i < size; i++) { + *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + } + if (extra_byte) + *lpOut++ = 0; + } + if (count > 0) { + /* too little for absoluting so we must encode them even if it's expensive! */ + assert(count <= 2); + + *lpSizeImage += 2 * count; + *lpOut++ = 1; + *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + + if (count == 2) { + *lpOut++ = 1; + *lpOut++ = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + x++; + } + } + } else { + /* encode count pixel(s) */ + clr = pi->palette_map[GetRawPixel(lpbi,lpIn,x)]; + + /* optimize end of line */ + if (x + count + 1 == lpbi->biWidth) + count++; + + x += count; + while (count > 0) { + INT size = min(count, 255); + + *lpSizeImage += 2; + count -= size; + *lpOut++ = size; + *lpOut++ = clr; + } + } + + *ppOut = lpOut; + + return x; +} + +LRESULT MSRLE32_CompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, + LPBYTE lpOut, BOOL isKey) +{ + LPWORD lpC; + LONG lLine, lInLine, lDist; + LPBYTE lpOutStart = lpOut; + + /* pre-conditions */ + assert(pi != NULL && lpbiOut != NULL); + assert(lpIn != NULL && lpOut != NULL); + assert(pi->pCurFrame != NULL); + + lpC = pi->pCurFrame; + lDist = QUALITY_to_DIST(pi->dwQuality); + lInLine = DIBWIDTHBYTES(*lpbiIn); + lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2; + + lpbiOut->biSizeImage = 0; + if (isKey) { + /* keyframe -- convert internal frame to output format */ + INT x, y; + + for (y = 0; y < lpbiOut->biHeight; y++) { + x = 0; + + do { + x = MSRLE32_CompressRLE4Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x, + &lpOut, &lpbiOut->biSizeImage); + } while (x < lpbiOut->biWidth); + + lpC += lLine; + lpIn += lInLine; + + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *(LPWORD)lpOut = 0; + lpOut += sizeof(WORD); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } + } else { + /* delta-frame -- compute delta between last and this internal frame */ + LPWORD lpP; + INT x, y; + INT jumpx, jumpy; + + assert(pi->pPrevFrame != NULL); + + lpP = pi->pPrevFrame; + jumpy = 0; + jumpx = -1; + + for (y = 0; y < lpbiOut->biHeight; y++) { + x = 0; + + do { + INT count, pos; + + if (jumpx == -1) + jumpx = x; + for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) { + if (ColorCmp(lpP[pos], lpC[pos]) > lDist) + break; + } + + if (pos == lpbiOut->biWidth && count > 8) { + /* (count > 8) secures that we will save space */ + jumpy++; + break; + } else if (jumpy || jumpx != pos) { + /* time to jump */ + assert(jumpx != -1); + + if (pos < jumpx) { + /* can only jump in positive direction -- jump until EOL, EOL */ + INT w = lpbiOut->biWidth - jumpx; + + assert(jumpy > 0); + assert(w >= 4); + + jumpx = 0; + jumpy--; + /* if (w % 255 == 2) then equal costs + * else if (w % 255 < 4 && we could encode all) then 2 bytes too expensive + * else it will be cheaper + */ + while (w > 0) { + lpbiOut->biSizeImage += 4; + *lpOut++ = 0; + *lpOut++ = 2; + *lpOut = min(w, 255); + w -= *lpOut++; + *lpOut++ = 0; + } + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + } + + /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */ + + /* write out real jump(s) */ + while (jumpy || pos != jumpx) { + lpbiOut->biSizeImage += 4; + *lpOut++ = 0; + *lpOut++ = 2; + *lpOut = min(pos - jumpx, 255); + x += *lpOut; + jumpx += *lpOut++; + *lpOut = min(jumpy, 255); + jumpy -= *lpOut++; + } + + jumpy = 0; + } + + jumpx = -1; + + if (x < lpbiOut->biWidth) { + /* skipped the 'same' things corresponding to previous frame */ + x = MSRLE32_CompressRLE4Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x, + &lpOut, &lpbiOut->biSizeImage); + } + } while (x < lpbiOut->biWidth); + + lpP += lLine; + lpC += lLine; + lpIn += lInLine; + + if (jumpy == 0) { + assert(jumpx == -1); + + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + assert(lpOut == lpOutStart + lpbiOut->biSizeImage); + } + } + + /* add EOL -- will be changed to EOI */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + } + + /* change EOL to EOI -- end of image */ + lpOut[-1] = 1; + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + + return ICERR_OK; +} + +LRESULT MSRLE32_CompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + const BYTE *lpIn, LPBITMAPINFOHEADER lpbiOut, + LPBYTE lpOut, BOOL isKey) +{ + LPWORD lpC; + LONG lDist, lInLine, lLine; + LPBYTE lpOutStart = lpOut; + + assert(pi != NULL && lpbiOut != NULL); + assert(lpIn != NULL && lpOut != NULL); + assert(pi->pCurFrame != NULL); + + lpC = pi->pCurFrame; + lDist = QUALITY_to_DIST(pi->dwQuality); + lInLine = DIBWIDTHBYTES(*lpbiIn); + lLine = WIDTHBYTES(lpbiOut->biWidth * 16) / 2; + + lpbiOut->biSizeImage = 0; + if (isKey) { + /* keyframe -- convert internal frame to output format */ + INT x, y; + + for (y = 0; y < lpbiOut->biHeight; y++) { + x = 0; + + do { + x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x, + &lpOut, &lpbiOut->biSizeImage); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } while (x < lpbiOut->biWidth); + + lpC += lLine; + lpIn += lInLine; + + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } + } else { + /* delta-frame -- compute delta between last and this internal frame */ + LPWORD lpP; + INT x, y; + INT jumpx, jumpy; + + assert(pi->pPrevFrame != NULL); + + lpP = pi->pPrevFrame; + jumpx = -1; + jumpy = 0; + + for (y = 0; y < lpbiOut->biHeight; y++) { + x = 0; + + do { + INT count, pos; + + if (jumpx == -1) + jumpx = x; + for (count = 0, pos = x; pos < lpbiOut->biWidth; pos++, count++) { + if (ColorCmp(lpP[pos], lpC[pos]) > lDist) + break; + } + + if (pos == lpbiOut->biWidth && count > 4) { + /* (count > 4) secures that we will save space */ + jumpy++; + break; + } else if (jumpy || jumpx != pos) { + /* time to jump */ + assert(jumpx != -1); + + if (pos < jumpx) { + /* can only jump in positive direction -- do an EOL then jump */ + assert(jumpy > 0); + + jumpx = 0; + jumpy--; + + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } + + /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */ + + /* write out real jump(s) */ + while (jumpy || pos != jumpx) { + lpbiOut->biSizeImage += 4; + *lpOut++ = 0; + *lpOut++ = 2; + *lpOut = min(pos - jumpx, 255); + jumpx += *lpOut++; + *lpOut = min(jumpy, 255); + jumpy -= *lpOut++; + } + x = pos; + + jumpy = 0; + } + + jumpx = -1; + + if (x < lpbiOut->biWidth) { + /* skip the 'same' things corresponding to previous frame */ + x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x, + &lpOut, &lpbiOut->biSizeImage); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } + } while (x < lpbiOut->biWidth); + + lpP += lLine; + lpC += lLine; + lpIn += lInLine; + + if (jumpy == 0) { + /* add EOL -- end of line */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + } + } + + /* add EOL -- will be changed to EOI */ + lpbiOut->biSizeImage += 2; + *((LPWORD)lpOut) = 0; + lpOut += sizeof(WORD); + } + + /* change EOL to EOI -- end of image */ + lpOut[-1] = 1; + assert(lpOut == (lpOutStart + lpbiOut->biSizeImage)); + + return ICERR_OK; +} + +/*****************************************************************************/ + +static LRESULT MSRLE32_DecompressRLE4(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LPBYTE lpOut) +{ + int bytes_per_pixel; + int line_size; + int pixel_ptr = 0; + int i; + BOOL bEndFlag = FALSE; + + assert(pi != NULL); + assert(lpbi != NULL && lpbi->biCompression == BI_RGB); + assert(lpIn != NULL && lpOut != NULL); + + bytes_per_pixel = (lpbi->biBitCount + 1) / 8; + line_size = DIBWIDTHBYTES(*lpbi); + + do { + BYTE code0, code1; + + code0 = *lpIn++; + code1 = *lpIn++; + + if (code0 == 0) { + int extra_byte; + + switch (code1) { + case 0: /* EOL - end of line */ + pixel_ptr = 0; + lpOut += line_size; + break; + case 1: /* EOI - end of image */ + bEndFlag = TRUE; + break; + case 2: /* skip */ + pixel_ptr += *lpIn++ * bytes_per_pixel; + lpOut += *lpIn++ * line_size; + if (pixel_ptr >= lpbi->biWidth * bytes_per_pixel) { + pixel_ptr = 0; + lpOut += line_size; + } + break; + default: /* absolute mode */ + extra_byte = (((code1 + 1) & (~1)) / 2) & 0x01; + + if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth) + return ICERR_ERROR; + + code0 = code1; + for (i = 0; i < code0 / 2; i++) { + if (bytes_per_pixel == 1) { + code1 = lpIn[i]; + lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)]; + if (2 * i + 1 <= code0) + lpOut[pixel_ptr++] = pi->palette_map[(code1 & 0x0F)]; + } else if (bytes_per_pixel == 2) { + code1 = lpIn[i] >> 4; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0]; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1]; + + if (2 * i + 1 <= code0) { + code1 = lpIn[i] & 0x0F; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0]; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1]; + } + } else { + code1 = lpIn[i] >> 4; + lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; + lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; + lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; + pixel_ptr += bytes_per_pixel; + + if (2 * i + 1 <= code0) { + code1 = lpIn[i] & 0x0F; + lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; + lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; + lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; + pixel_ptr += bytes_per_pixel; + } + } + } + if (code0 & 0x01) { + if (bytes_per_pixel == 1) { + code1 = lpIn[i]; + lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)]; + } else if (bytes_per_pixel == 2) { + code1 = lpIn[i] >> 4; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0]; + lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1]; + } else { + code1 = lpIn[i] >> 4; + lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; + lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; + lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; + pixel_ptr += bytes_per_pixel; + } + lpIn++; + } + lpIn += code0 / 2; + + /* if the RLE code is odd, skip a byte in the stream */ + if (extra_byte) + lpIn++; + }; + } else { + /* coded mode */ + if (pixel_ptr/bytes_per_pixel + code0 > lpbi->biWidth) + return ICERR_ERROR; + + if (bytes_per_pixel == 1) { + BYTE c1 = pi->palette_map[(code1 >> 4)]; + BYTE c2 = pi->palette_map[(code1 & 0x0F)]; + + for (i = 0; i < code0; i++) { + if ((i & 1) == 0) + lpOut[pixel_ptr++] = c1; + else + lpOut[pixel_ptr++] = c2; + } + } else if (bytes_per_pixel == 2) { + BYTE hi1 = pi->palette_map[(code1 >> 4) * 2 + 0]; + BYTE lo1 = pi->palette_map[(code1 >> 4) * 2 + 1]; + + BYTE hi2 = pi->palette_map[(code1 & 0x0F) * 2 + 0]; + BYTE lo2 = pi->palette_map[(code1 & 0x0F) * 2 + 1]; + + for (i = 0; i < code0; i++) { + if ((i & 1) == 0) { + lpOut[pixel_ptr++] = hi1; + lpOut[pixel_ptr++] = lo1; + } else { + lpOut[pixel_ptr++] = hi2; + lpOut[pixel_ptr++] = lo2; + } + } + } else { + BYTE b1 = pi->palette_map[(code1 >> 4) * 4 + 0]; + BYTE g1 = pi->palette_map[(code1 >> 4) * 4 + 1]; + BYTE r1 = pi->palette_map[(code1 >> 4) * 4 + 2]; + + BYTE b2 = pi->palette_map[(code1 & 0x0F) * 4 + 0]; + BYTE g2 = pi->palette_map[(code1 & 0x0F) * 4 + 1]; + BYTE r2 = pi->palette_map[(code1 & 0x0F) * 4 + 2]; + + for (i = 0; i < code0; i++) { + if ((i & 1) == 0) { + lpOut[pixel_ptr + 0] = b1; + lpOut[pixel_ptr + 1] = g1; + lpOut[pixel_ptr + 2] = r1; + } else { + lpOut[pixel_ptr + 0] = b2; + lpOut[pixel_ptr + 1] = g2; + lpOut[pixel_ptr + 2] = r2; + } + pixel_ptr += bytes_per_pixel; + } + } + } + } while (! bEndFlag); + + return ICERR_OK; +} + +static LRESULT MSRLE32_DecompressRLE8(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbi, + const BYTE *lpIn, LPBYTE lpOut) +{ + int bytes_per_pixel; + int line_size; + int pixel_ptr = 0; + BOOL bEndFlag = FALSE; + + assert(pi != NULL); + assert(lpbi != NULL && lpbi->biCompression == BI_RGB); + assert(lpIn != NULL && lpOut != NULL); + + bytes_per_pixel = (lpbi->biBitCount + 1) / 8; + line_size = DIBWIDTHBYTES(*lpbi); + + do { + BYTE code0, code1; + + code0 = *lpIn++; + code1 = *lpIn++; + + if (code0 == 0) { + int extra_byte; + + switch (code1) { + case 0: /* EOL - end of line */ + pixel_ptr = 0; + lpOut += line_size; + break; + case 1: /* EOI - end of image */ + bEndFlag = TRUE; + break; + case 2: /* skip */ + pixel_ptr += *lpIn++ * bytes_per_pixel; + lpOut += *lpIn++ * line_size; + if (pixel_ptr >= lpbi->biWidth * bytes_per_pixel) { + pixel_ptr = 0; + lpOut += line_size; + } + break; + default: /* absolute mode */ + if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth) { + WARN("aborted absolute: (%d=%d/%d+%d) > %d\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth); + return ICERR_ERROR; + } + extra_byte = code1 & 0x01; + + code0 = code1; + while (code0--) { + code1 = *lpIn++; + if (bytes_per_pixel == 1) { + lpOut[pixel_ptr] = pi->palette_map[code1]; + } else if (bytes_per_pixel == 2) { + lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 2 + 0]; + lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 2 + 1]; + } else { + lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; + lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; + lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; + } + pixel_ptr += bytes_per_pixel; + } + + /* if the RLE code is odd, skip a byte in the stream */ + if (extra_byte) + lpIn++; + }; + } else { + /* coded mode */ + if (pixel_ptr/bytes_per_pixel + code0 > lpbi->biWidth) { + WARN("aborted coded: (%d=%d/%d+%d) > %d\n",pixel_ptr/bytes_per_pixel + code1,pixel_ptr,bytes_per_pixel,code1,lpbi->biWidth); + return ICERR_ERROR; + } + + if (bytes_per_pixel == 1) { + code1 = pi->palette_map[code1]; + while (code0--) + lpOut[pixel_ptr++] = code1; + } else if (bytes_per_pixel == 2) { + BYTE hi = pi->palette_map[code1 * 2 + 0]; + BYTE lo = pi->palette_map[code1 * 2 + 1]; + + while (code0--) { + lpOut[pixel_ptr + 0] = hi; + lpOut[pixel_ptr + 1] = lo; + pixel_ptr += bytes_per_pixel; + } + } else { + BYTE r = pi->palette_map[code1 * 4 + 2]; + BYTE g = pi->palette_map[code1 * 4 + 1]; + BYTE b = pi->palette_map[code1 * 4 + 0]; + + while (code0--) { + lpOut[pixel_ptr + 0] = b; + lpOut[pixel_ptr + 1] = g; + lpOut[pixel_ptr + 2] = r; + pixel_ptr += bytes_per_pixel; + } + } + } + } while (! bEndFlag); + + return ICERR_OK; +} + +/*****************************************************************************/ + +static CodecInfo* Open(LPICOPEN icinfo) +{ + CodecInfo* pi = NULL; + + if (icinfo == NULL) { + TRACE("(NULL)\n"); + return (LPVOID)0xFFFF0000; + } + + if (icinfo->fccType != ICTYPE_VIDEO) return NULL; + + TRACE("(%p = {%u,0x%08X(%4.4s),0x%08X(%4.4s),0x%X,0x%X,...})\n", icinfo, + icinfo->dwSize, icinfo->fccType, (char*)&icinfo->fccType, + icinfo->fccHandler, (char*)&icinfo->fccHandler, + icinfo->dwVersion,icinfo->dwFlags); + + switch (icinfo->fccHandler) { + case FOURCC_RLE: + case FOURCC_RLE4: + case FOURCC_RLE8: + case FOURCC_MRLE: + break; + case mmioFOURCC('m','r','l','e'): + icinfo->fccHandler = FOURCC_MRLE; + break; + default: + WARN("unknown FOURCC = 0x%08X(%4.4s) !\n", + icinfo->fccHandler,(char*)&icinfo->fccHandler); + return NULL; + } + + pi = LocalAlloc(LPTR, sizeof(CodecInfo)); + + if (pi != NULL) { + pi->fccHandler = icinfo->fccHandler; + + pi->bCompress = FALSE; + pi->dwQuality = MSRLE32_DEFAULTQUALITY; + pi->nPrevFrame = -1; + pi->pPrevFrame = pi->pCurFrame = NULL; + + pi->bDecompress = FALSE; + pi->palette_map = NULL; + } + + icinfo->dwError = (pi != NULL ? ICERR_OK : ICERR_MEMORY); + + return pi; +} + +static LRESULT Close(CodecInfo *pi) +{ + TRACE("(%p)\n", pi); + + /* pre-condition */ + assert(pi != NULL); + + if (pi->pPrevFrame != NULL || pi->pCurFrame != NULL) + CompressEnd(pi); + + LocalFree(pi); + return 1; +} + +static LRESULT GetInfo(const CodecInfo *pi, ICINFO *icinfo, DWORD dwSize) +{ + /* pre-condition */ + assert(pi != NULL); + + /* check parameters */ + if (icinfo == NULL) + return sizeof(ICINFO); + if (dwSize < sizeof(ICINFO)) + return 0; + + icinfo->dwSize = sizeof(ICINFO); + icinfo->fccType = ICTYPE_VIDEO; + icinfo->fccHandler = (pi != NULL ? pi->fccHandler : FOURCC_MRLE); + icinfo->dwFlags = VIDCF_QUALITY | VIDCF_TEMPORAL | VIDCF_CRUNCH | VIDCF_FASTTEMPORALC; + icinfo->dwVersion = ICVERSION; + icinfo->dwVersionICM = ICVERSION; + + LoadStringW(MSRLE32_hModule, IDS_NAME, icinfo->szName, sizeof(icinfo->szName)/sizeof(WCHAR)); + LoadStringW(MSRLE32_hModule, IDS_DESCRIPTION, icinfo->szDescription, sizeof(icinfo->szDescription)/sizeof(WCHAR)); + + return sizeof(ICINFO); +} + +static LRESULT SetQuality(CodecInfo *pi, LONG lQuality) +{ + /* pre-condition */ + assert(pi != NULL); + + if (lQuality == -1) + lQuality = MSRLE32_DEFAULTQUALITY; + else if (ICQUALITY_LOW > lQuality || lQuality > ICQUALITY_HIGH) + return ICERR_BADPARAM; + + pi->dwQuality = (DWORD)lQuality; + + return ICERR_OK; +} + +static LRESULT Configure(const CodecInfo *pi, HWND hWnd) +{ + /* pre-condition */ + assert(pi != NULL); + + /* FIXME */ + return ICERR_OK; +} + +static LRESULT About(CodecInfo *pi, HWND hWnd) +{ + WCHAR szTitle[20]; + WCHAR szAbout[128]; + + /* pre-condition */ + assert(MSRLE32_hModule != 0); + + LoadStringW(MSRLE32_hModule, IDS_NAME, szTitle, sizeof(szTitle)/sizeof(szTitle[0])); + LoadStringW(MSRLE32_hModule, IDS_ABOUT, szAbout, sizeof(szAbout)/sizeof(szAbout[0])); + + MessageBoxW(hWnd, szAbout, szTitle, MB_OK|MB_ICONINFORMATION); + + return ICERR_OK; +} + +static LRESULT CompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut) +{ + LRESULT size; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters -- need at least input format */ + if (lpbiIn == NULL) { + if (lpbiOut != NULL) + return ICERR_BADPARAM; + return 0; + } + + /* handle unsupported input format */ + if (CompressQuery(pi, lpbiIn, NULL) != ICERR_OK) + return (lpbiOut == NULL ? ICERR_BADFORMAT : 0); + + assert(0 < lpbiIn->biBitCount && lpbiIn->biBitCount <= 8); + + switch (pi->fccHandler) { + case FOURCC_RLE4: + size = 1 << 4; + break; + case FOURCC_RLE8: + size = 1 << 8; + break; + case FOURCC_RLE: + case FOURCC_MRLE: + size = (lpbiIn->biBitCount <= 4 ? 1 << 4 : 1 << 8); + break; + default: + return ICERR_ERROR; + } + + if (lpbiIn->biClrUsed != 0) + size = lpbiIn->biClrUsed; + + size = sizeof(BITMAPINFOHEADER) + size * sizeof(RGBQUAD); + + if (lpbiOut != NULL) { + lpbiOut->biSize = sizeof(BITMAPINFOHEADER); + lpbiOut->biWidth = lpbiIn->biWidth; + lpbiOut->biHeight = lpbiIn->biHeight; + lpbiOut->biPlanes = 1; + if (pi->fccHandler == FOURCC_RLE4 || + lpbiIn->biBitCount <= 4) { + lpbiOut->biCompression = BI_RLE4; + lpbiOut->biBitCount = 4; + } else { + lpbiOut->biCompression = BI_RLE8; + lpbiOut->biBitCount = 8; + } + lpbiOut->biSizeImage = MSRLE32_GetMaxCompressedSize(lpbiOut); + lpbiOut->biXPelsPerMeter = lpbiIn->biXPelsPerMeter; + lpbiOut->biYPelsPerMeter = lpbiIn->biYPelsPerMeter; + if (lpbiIn->biClrUsed == 0) + size = 1<biBitCount; + else + size = lpbiIn->biClrUsed; + lpbiOut->biClrUsed = min(size, 1 << lpbiOut->biBitCount); + lpbiOut->biClrImportant = 0; + + memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, + (const BYTE*)lpbiIn + lpbiIn->biSize, lpbiOut->biClrUsed * sizeof(RGBQUAD)); + + return ICERR_OK; + } else + return size; +} + +static LRESULT CompressGetSize(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut) +{ + /* pre-condition */ + assert(pi != NULL); + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* check parameter -- need at least one format */ + if (lpbiIn == NULL && lpbiOut == NULL) + return 0; + /* check if the given format is supported */ + if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) + return 0; + + /* the worst case is coding the complete image in absolute mode. */ + if (lpbiIn) + return MSRLE32_GetMaxCompressedSize(lpbiIn); + else + return MSRLE32_GetMaxCompressedSize(lpbiOut); +} + +static LRESULT CompressQuery(const CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut) +{ + /* pre-condition */ + assert(pi != NULL); + + /* need at least one format */ + if (lpbiIn == NULL && lpbiOut == NULL) + return ICERR_BADPARAM; + + /* check input format if given */ + if (lpbiIn != NULL) { + if (!isSupportedDIB(lpbiIn)) + return ICERR_BADFORMAT; + + /* for 4-bit need an even width */ + if (lpbiIn->biBitCount <= 4 && (lpbiIn->biWidth % 2)) + return ICERR_BADFORMAT; + + if (pi->fccHandler == FOURCC_RLE4 && lpbiIn->biBitCount > 4) + return ICERR_UNSUPPORTED; + else if (lpbiIn->biBitCount > 8) + return ICERR_UNSUPPORTED; + } + + /* check output format if given */ + if (lpbiOut != NULL) { + if (!isSupportedMRLE(lpbiOut)) + return ICERR_BADFORMAT; + + if (lpbiIn != NULL) { + if (lpbiIn->biWidth != lpbiOut->biWidth) + return ICERR_UNSUPPORTED; + if (lpbiIn->biHeight != lpbiOut->biHeight) + return ICERR_UNSUPPORTED; + if (lpbiIn->biBitCount > lpbiOut->biBitCount) + return ICERR_UNSUPPORTED; + } + } + + return ICERR_OK; +} + +static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut) +{ + const RGBQUAD *rgbIn; + const RGBQUAD *rgbOut; + UINT i; + size_t size; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters -- need both formats */ + if (lpbiIn == NULL || lpbiOut == NULL) + return ICERR_BADPARAM; + /* And both must be supported */ + if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) + return ICERR_BADFORMAT; + + /* FIXME: cannot compress and decompress at same time! */ + if (pi->bDecompress) { + FIXME("cannot compress and decompress at same time!\n"); + return ICERR_ERROR; + } + + if (pi->bCompress) + CompressEnd(pi); + + size = WIDTHBYTES(lpbiOut->biWidth * 16) / 2 * lpbiOut->biHeight; + pi->pPrevFrame = GlobalLock(GlobalAlloc(GPTR, size * sizeof(WORD))); + if (pi->pPrevFrame == NULL) + return ICERR_MEMORY; + pi->pCurFrame = GlobalLock(GlobalAlloc(GPTR, size * sizeof(WORD))); + if (pi->pCurFrame == NULL) { + CompressEnd(pi); + return ICERR_MEMORY; + } + pi->nPrevFrame = -1; + pi->bCompress = TRUE; + + rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize); + rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize); + + switch (lpbiOut->biBitCount) { + case 4: + case 8: + pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed); + if (pi->palette_map == NULL) { + CompressEnd(pi); + return ICERR_MEMORY; + } + + for (i = 0; i < lpbiIn->biClrUsed; i++) { + pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]); + } + break; + }; + + return ICERR_OK; +} + +static LRESULT Compress(CodecInfo *pi, ICCOMPRESS* lpic, DWORD dwSize) +{ + int i; + + TRACE("(%p,%p,%u)\n",pi,lpic,dwSize); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters */ + if (lpic == NULL || dwSize < sizeof(ICCOMPRESS)) + return ICERR_BADPARAM; + if (!lpic->lpbiOutput || !lpic->lpOutput || + !lpic->lpbiInput || !lpic->lpInput) + return ICERR_BADPARAM; + + TRACE("lpic={0x%X,%p,%p,%p,%p,%p,%p,%d,%u,%u,%p,%p}\n",lpic->dwFlags,lpic->lpbiOutput,lpic->lpOutput,lpic->lpbiInput,lpic->lpInput,lpic->lpckid,lpic->lpdwFlags,lpic->lFrameNum,lpic->dwFrameSize,lpic->dwQuality,lpic->lpbiPrev,lpic->lpPrev); + + if (! pi->bCompress) { + LRESULT hr = CompressBegin(pi, lpic->lpbiInput, lpic->lpbiOutput); + if (hr != ICERR_OK) + return hr; + } else if (CompressQuery(pi, lpic->lpbiInput, lpic->lpbiOutput) != ICERR_OK) + return ICERR_BADFORMAT; + + if (lpic->lFrameNum >= pi->nPrevFrame + 1) { + /* we continue in the sequence so we need to initialize + * our internal framedata */ + + computeInternalFrame(pi, lpic->lpbiInput, lpic->lpInput); + } else if (lpic->lFrameNum == pi->nPrevFrame) { + /* Oops, compress same frame again ? Okay, as you wish. + * No need to recompute internal framedata, because we only swapped buffers */ + LPWORD pTmp = pi->pPrevFrame; + + pi->pPrevFrame = pi->pCurFrame; + pi->pCurFrame = pTmp; + } else if ((lpic->dwFlags & ICCOMPRESS_KEYFRAME) == 0) { + LPWORD pTmp; + + WARN(": prev=%d cur=%d gone back? -- untested\n",pi->nPrevFrame,lpic->lFrameNum); + if (lpic->lpbiPrev == NULL || lpic->lpPrev == NULL) + return ICERR_GOTOKEYFRAME; /* Need a keyframe if you go back */ + if (CompressQuery(pi, lpic->lpbiPrev, lpic->lpbiOutput) != ICERR_OK) + return ICERR_BADFORMAT; + + WARN(": prev=%d cur=%d compute swapped -- untested\n",pi->nPrevFrame,lpic->lFrameNum); + computeInternalFrame(pi, lpic->lpbiPrev, lpic->lpPrev); + + /* swap buffers for current and previous frame */ + /* Don't free and alloc new -- costs to much time and they are of equal size ! */ + pTmp = pi->pPrevFrame; + pi->pPrevFrame = pi->pCurFrame; + pi->pCurFrame = pTmp; + pi->nPrevFrame = lpic->lFrameNum; + } + + for (i = 0; i < 3; i++) { + SetQuality(pi, lpic->dwQuality); + + lpic->lpbiOutput->biSizeImage = 0; + + if (lpic->lpbiOutput->biBitCount == 4) + MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput, + lpic->lpbiOutput, lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); + else + MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput, + lpic->lpbiOutput, lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0); + + if (lpic->dwFrameSize == 0 || + lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) + break; + + if ((*lpic->lpdwFlags & ICCOMPRESS_KEYFRAME) == 0) { + if (lpic->lpbiOutput->biBitCount == 4) + MSRLE32_CompressRLE4(pi, lpic->lpbiInput, lpic->lpInput, + lpic->lpbiOutput, lpic->lpOutput, TRUE); + else + MSRLE32_CompressRLE8(pi, lpic->lpbiInput, lpic->lpInput, + lpic->lpbiOutput, lpic->lpOutput, TRUE); + + if (lpic->dwFrameSize == 0 || + lpic->lpbiOutput->biSizeImage < lpic->dwFrameSize) { + WARN("switched to keyframe, was small enough!\n"); + *lpic->lpdwFlags |= ICCOMPRESS_KEYFRAME; + *lpic->lpckid = MAKEAVICKID(cktypeDIBbits, + StreamFromFOURCC(*lpic->lpckid)); + break; + } + } + + if (lpic->dwQuality < 1000) + break; + + lpic->dwQuality -= 1000; /* reduce quality by 10% */ + } + + { /* swap buffer for current and previous frame */ + /* Don't free and alloc new -- costs to much time and they are of equal size ! */ + register LPWORD pTmp = pi->pPrevFrame; + + pi->pPrevFrame = pi->pCurFrame; + pi->pCurFrame = pTmp; + pi->nPrevFrame = lpic->lFrameNum; + } + + return ICERR_OK; +} + +static LRESULT CompressEnd(CodecInfo *pi) +{ + TRACE("(%p)\n",pi); + + if (pi != NULL) { + if (pi->pPrevFrame != NULL) + { + GlobalUnlock(GlobalHandle(pi->pPrevFrame)); + GlobalFree(GlobalHandle(pi->pPrevFrame)); + } + if (pi->pCurFrame != NULL) + { + GlobalUnlock(GlobalHandle(pi->pCurFrame)); + GlobalFree(GlobalHandle(pi->pCurFrame)); + } + pi->pPrevFrame = NULL; + pi->pCurFrame = NULL; + pi->nPrevFrame = -1; + pi->bCompress = FALSE; + } + + return ICERR_OK; +} + +static LRESULT DecompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut) +{ + DWORD size; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + if (lpbiIn == NULL) + return (lpbiOut != NULL ? ICERR_BADPARAM : 0); + + if (DecompressQuery(pi, lpbiIn, NULL) != ICERR_OK) + return (lpbiOut != NULL ? ICERR_BADFORMAT : 0); + + size = lpbiIn->biSize; + + if (lpbiIn->biBitCount <= 8) + size += lpbiIn->biClrUsed * sizeof(RGBQUAD); + + if (lpbiOut != NULL) { + memcpy(lpbiOut, lpbiIn, size); + lpbiOut->biCompression = BI_RGB; + lpbiOut->biSizeImage = DIBWIDTHBYTES(*lpbiOut) * lpbiOut->biHeight; + + return ICERR_OK; + } else + return size; +} + +static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut) +{ + LRESULT hr = ICERR_OK; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + /* need at least one format */ + if (lpbiIn == NULL && lpbiOut == NULL) + return ICERR_BADPARAM; + + /* check input format if given */ + if (lpbiIn != NULL) { + if (!isSupportedMRLE(lpbiIn)) + return ICERR_BADFORMAT; + } + + /* check output format if given */ + if (lpbiOut != NULL) { + if (!isSupportedDIB(lpbiOut)) + hr = ICERR_BADFORMAT; + + if (lpbiIn != NULL) { + if (lpbiIn->biWidth != lpbiOut->biWidth) + hr = ICERR_UNSUPPORTED; + if (lpbiIn->biHeight != lpbiOut->biHeight) + hr = ICERR_UNSUPPORTED; + if (lpbiIn->biBitCount > lpbiOut->biBitCount) + hr = ICERR_UNSUPPORTED; + } + } + + return hr; +} + +static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPCBITMAPINFOHEADER lpbiOut) +{ + const RGBQUAD *rgbIn; + const RGBQUAD *rgbOut; + UINT i; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters */ + if (lpbiIn == NULL || lpbiOut == NULL) + return ICERR_BADPARAM; + if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) + return ICERR_BADFORMAT; + + /* FIXME: cannot compress and decompress at a time! */ + if (pi->bCompress) { + FIXME("cannot compress and decompress at same time!\n"); + return ICERR_ERROR; + } + + if (pi->bDecompress) + DecompressEnd(pi); + + rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize); + rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize); + + switch (lpbiOut->biBitCount) { + case 4: + case 8: + pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed); + if (pi->palette_map == NULL) + return ICERR_MEMORY; + + for (i = 0; i < lpbiIn->biClrUsed; i++) { + pi->palette_map[i] = MSRLE32_GetNearestPaletteIndex(lpbiOut->biClrUsed, rgbOut, rgbIn[i]); + } + break; + case 15: + case 16: + pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * 2); + if (pi->palette_map == NULL) + return ICERR_MEMORY; + + for (i = 0; i < lpbiIn->biClrUsed; i++) { + WORD color; + + if (lpbiOut->biBitCount == 15) + color = ((rgbIn[i].rgbRed >> 3) << 10) + | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3); + else + color = ((rgbIn[i].rgbRed >> 3) << 11) + | ((rgbIn[i].rgbGreen >> 3) << 5) | (rgbIn[i].rgbBlue >> 3); + + pi->palette_map[i * 2 + 1] = color >> 8; + pi->palette_map[i * 2 + 0] = color & 0xFF; + }; + break; + case 24: + case 32: + pi->palette_map = LocalAlloc(LPTR, lpbiIn->biClrUsed * sizeof(RGBQUAD)); + if (pi->palette_map == NULL) + return ICERR_MEMORY; + memcpy(pi->palette_map, rgbIn, lpbiIn->biClrUsed * sizeof(RGBQUAD)); + break; + }; + + pi->bDecompress = TRUE; + + return ICERR_OK; +} + +static LRESULT Decompress(CodecInfo *pi, ICDECOMPRESS *pic, DWORD dwSize) +{ + TRACE("(%p,%p,%u)\n",pi,pic,dwSize); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters */ + if (pic == NULL) + return ICERR_BADPARAM; + if (pic->lpbiInput == NULL || pic->lpInput == NULL || + pic->lpbiOutput == NULL || pic->lpOutput == NULL) + return ICERR_BADPARAM; + + /* check formats */ + if (! pi->bDecompress) { + LRESULT hr = DecompressBegin(pi, pic->lpbiInput, pic->lpbiOutput); + if (hr != ICERR_OK) + return hr; + } else if (DecompressQuery(pi, pic->lpbiInput, pic->lpbiOutput) != ICERR_OK) + return ICERR_BADFORMAT; + + assert(pic->lpbiInput->biWidth == pic->lpbiOutput->biWidth); + assert(pic->lpbiInput->biHeight == pic->lpbiOutput->biHeight); + + pic->lpbiOutput->biSizeImage = DIBWIDTHBYTES(*pic->lpbiOutput) * pic->lpbiOutput->biHeight; + if (pic->lpbiInput->biBitCount == 4) + return MSRLE32_DecompressRLE4(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput); + else + return MSRLE32_DecompressRLE8(pi, pic->lpbiOutput, pic->lpInput, pic->lpOutput); +} + +static LRESULT DecompressEnd(CodecInfo *pi) +{ + TRACE("(%p)\n",pi); + + /* pre-condition */ + assert(pi != NULL); + + pi->bDecompress = FALSE; + + if (pi->palette_map != NULL) { + LocalFree(pi->palette_map); + pi->palette_map = NULL; + } + + return ICERR_OK; +} + +static LRESULT DecompressGetPalette(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, + LPBITMAPINFOHEADER lpbiOut) +{ + int size; + + TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); + + /* pre-condition */ + assert(pi != NULL); + + /* check parameters */ + if (lpbiIn == NULL || lpbiOut == NULL) + return ICERR_BADPARAM; + + if (DecompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) + return ICERR_BADFORMAT; + + if (lpbiOut->biBitCount > 8) + return ICERR_ERROR; + + if (lpbiIn->biBitCount <= 8) { + if (lpbiIn->biClrUsed > 0) + size = lpbiIn->biClrUsed; + else + size = (1 << lpbiIn->biBitCount); + + lpbiOut->biClrUsed = size; + + memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (const BYTE*)lpbiIn + lpbiIn->biSize, size * sizeof(RGBQUAD)); + } /* else could never occur ! */ + + return ICERR_OK; +} + +/* DriverProc - entry point for an installable driver */ +LRESULT CALLBACK MSRLE32_DriverProc(DWORD_PTR dwDrvID, HDRVR hDrv, UINT uMsg, + LPARAM lParam1, LPARAM lParam2) +{ + CodecInfo *pi = (CodecInfo*)dwDrvID; + + TRACE("(%lx,%p,0x%04X,0x%08lX,0x%08lX)\n", dwDrvID, hDrv, uMsg, lParam1, lParam2); + + switch (uMsg) { + /* standard driver messages */ + case DRV_LOAD: + return DRVCNF_OK; + case DRV_OPEN: + return (LRESULT)Open((ICOPEN*)lParam2); + case DRV_CLOSE: + if (dwDrvID != 0xFFFF0000 && (LPVOID)dwDrvID != NULL) + Close(pi); + return DRVCNF_OK; + case DRV_ENABLE: + case DRV_DISABLE: + return DRVCNF_OK; + case DRV_FREE: + return DRVCNF_OK; + case DRV_QUERYCONFIGURE: + return DRVCNF_CANCEL; /* FIXME */ + case DRV_CONFIGURE: + return DRVCNF_OK; /* FIXME */ + case DRV_INSTALL: + case DRV_REMOVE: + return DRVCNF_OK; + + /* installable compression manager messages */ + case ICM_CONFIGURE: + FIXME("ICM_CONFIGURE (%ld)\n",lParam1); + if (lParam1 == -1) + return ICERR_UNSUPPORTED; /* FIXME */ + else + return Configure(pi, (HWND)lParam1); + case ICM_ABOUT: + if (lParam1 == -1) + return ICERR_OK; + else + return About(pi, (HWND)lParam1); + case ICM_GETSTATE: + case ICM_SETSTATE: + return 0; /* no state */ + case ICM_GETINFO: + return GetInfo(pi, (ICINFO*)lParam1, (DWORD)lParam2); + case ICM_GETDEFAULTQUALITY: + if ((LPVOID)lParam1 != NULL) { + *((LPDWORD)lParam1) = MSRLE32_DEFAULTQUALITY; + return ICERR_OK; + } + break; + case ICM_GETQUALITY: + if ((LPVOID)lParam1 != NULL) { + *((LPDWORD)lParam1) = pi->dwQuality; + return ICERR_OK; + } + break; + case ICM_SETQUALITY: + return SetQuality(pi, *(LPLONG)lParam1); + case ICM_COMPRESS_GET_FORMAT: + return CompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPBITMAPINFOHEADER)lParam2); + case ICM_COMPRESS_GET_SIZE: + return CompressGetSize(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPCBITMAPINFOHEADER)lParam2); + case ICM_COMPRESS_QUERY: + return CompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPCBITMAPINFOHEADER)lParam2); + case ICM_COMPRESS_BEGIN: + return CompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPCBITMAPINFOHEADER)lParam2); + case ICM_COMPRESS: + return Compress(pi, (ICCOMPRESS*)lParam1, (DWORD)lParam2); + case ICM_COMPRESS_END: + return CompressEnd(pi); + case ICM_DECOMPRESS_GET_FORMAT: + return DecompressGetFormat(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPBITMAPINFOHEADER)lParam2); + case ICM_DECOMPRESS_QUERY: + return DecompressQuery(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPCBITMAPINFOHEADER)lParam2); + case ICM_DECOMPRESS_BEGIN: + return DecompressBegin(pi, (LPCBITMAPINFOHEADER)lParam1, + (LPCBITMAPINFOHEADER)lParam2); + case ICM_DECOMPRESS: + return Decompress(pi, (ICDECOMPRESS*)lParam1, (DWORD)lParam2); + case ICM_DECOMPRESS_END: + return DecompressEnd(pi); + case ICM_DECOMPRESS_SET_PALETTE: + FIXME("(...) -> SetPalette(%p,%p,%p): stub!\n", pi, (LPVOID)lParam1, (LPVOID)lParam2); + return ICERR_UNSUPPORTED; + case ICM_DECOMPRESS_GET_PALETTE: + return DecompressGetPalette(pi, (LPBITMAPINFOHEADER)lParam1, + (LPBITMAPINFOHEADER)lParam2); + case ICM_GETDEFAULTKEYFRAMERATE: + if ((LPVOID)lParam1 != NULL) + *(LPDWORD)lParam1 = 15; + return ICERR_OK; + default: + if (uMsg < DRV_USER) + return DefDriverProc(dwDrvID, hDrv, uMsg, lParam1, lParam2); + else + FIXME("Unknown message uMsg=0x%08X lParam1=0x%08lX lParam2=0x%08lX\n",uMsg,lParam1,lParam2); + }; + + return ICERR_UNSUPPORTED; +} + +/* DllMain - library initialization code */ +BOOL WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved) +{ + TRACE("(%p,%d,%p)\n",hModule,dwReason,lpReserved); + + switch (dwReason) { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hModule); + MSRLE32_hModule = hModule; + break; + + case DLL_PROCESS_DETACH: + break; + } + + return TRUE; +} diff --git a/reactos/dll/win32/msrle32/msrle32.rbuild b/reactos/dll/win32/msrle32/msrle32.rbuild new file mode 100644 index 00000000000..a4db99ae7c7 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle32.rbuild @@ -0,0 +1,13 @@ + + + . + include/reactos/wine + + msrle32.c + rsrc.rc + wine + winmm + user32 + kernel32 + ntdll + diff --git a/reactos/dll/win32/msrle32/msrle32.spec b/reactos/dll/win32/msrle32/msrle32.spec new file mode 100644 index 00000000000..623cfea82bd --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle32.spec @@ -0,0 +1 @@ +@ stdcall -private DriverProc(long long long long long) MSRLE32_DriverProc diff --git a/reactos/dll/win32/msrle32/msrle_Bg.rc b/reactos/dll/win32/msrle32/msrle_Bg.rc new file mode 100644 index 00000000000..7c0d4488a57 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Bg.rc @@ -0,0 +1,28 @@ +/* + * Bulgarian resource file for MS-RLE + * + * Copyright 2005 Milko Krachounov + * + * 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 + */ + +LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE âèäåî êîäåê" + IDS_ABOUT "Wine MS-RLE âèäåî êîäåê\nCopyright 2002 by Michael Gunnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Cs.rc b/reactos/dll/win32/msrle32/msrle_Cs.rc new file mode 100644 index 00000000000..51fb1dfbef8 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Cs.rc @@ -0,0 +1,32 @@ +/* Hey, Emacs, open this file with -*- coding: cp1250 -*- + * + * Czech resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * Copyright 2004 David Kredba + * + * 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 + */ + +LANGUAGE LANG_CZECH, SUBLANG_DEFAULT + +/* Czech strings in CP1250 */ + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE video kodek" + IDS_ABOUT L"Wine MS-RLE video kodek\nCopyright 2002 Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Da.rc b/reactos/dll/win32/msrle32/msrle_Da.rc new file mode 100644 index 00000000000..c3ea57b4f11 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Da.rc @@ -0,0 +1,28 @@ +/* + * Danish language support + * + * Copyright (C) 2008 Jens Albretsen + * + * 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 + */ + +LANGUAGE LANG_DANISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE videokodeks" + IDS_ABOUT "Wine MS-RLE videokodeks\nOphavsret 2002 tilhører Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_De.rc b/reactos/dll/win32/msrle32/msrle_De.rc new file mode 100644 index 00000000000..c5f4954e2ef --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_De.rc @@ -0,0 +1,28 @@ +/* + * German resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * + * 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 + */ + +LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE Videodekoder" + IDS_ABOUT "Wine MS-RLE Videodekoder\nCopyright 2002 by Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_En.rc b/reactos/dll/win32/msrle32/msrle_En.rc new file mode 100644 index 00000000000..030a98a3aa5 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_En.rc @@ -0,0 +1,28 @@ +/* + * English resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * + * 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 + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE video codec" + IDS_ABOUT "Wine MS-RLE video codec\nCopyright 2002 by Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Es.rc b/reactos/dll/win32/msrle32/msrle_Es.rc new file mode 100644 index 00000000000..ca418cb7594 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Es.rc @@ -0,0 +1,28 @@ +/* + * Spanish resource file for MS-RLE + * + * Copyright 2003 José Manuel Ferrer Ortiz + * + * 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 + */ + +LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Codec de vídeo MS-RLE de Wine" + IDS_ABOUT "Codec de vídeo MS-RLE de Wine\nCopyright 2002 por Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Fr.rc b/reactos/dll/win32/msrle32/msrle_Fr.rc new file mode 100644 index 00000000000..e6eb31423f2 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Fr.rc @@ -0,0 +1,28 @@ +/* + * French resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * + * 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 + */ + +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine: décodeur/encodeur vidéo MS-RLE" + IDS_ABOUT "Wine: décodeur/encodeur vidéo MS-RLE\nCopyright 2002 par Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Hu.rc b/reactos/dll/win32/msrle32/msrle_Hu.rc new file mode 100644 index 00000000000..95016acb4d2 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Hu.rc @@ -0,0 +1,28 @@ +/* + * Hungarian resource file for MS-RLE + * + * Copyright 2006 Andras Kovacs + * + * 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 + */ + +LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE video kodek" + IDS_ABOUT L"Wine MS-RLE video kodek\nCopyright 2002, Michael G\x00fcnnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_It.rc b/reactos/dll/win32/msrle32/msrle_It.rc new file mode 100644 index 00000000000..695a78285f8 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_It.rc @@ -0,0 +1,29 @@ +/* + * Italian resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * Copyright 2003 Ivan Leo Puoti + * + * 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 + */ + +LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Codec video MS-RLE di Wine" + IDS_ABOUT "Codec video MS-RLE di Wine\nCopyright 2002 Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Ja.rc b/reactos/dll/win32/msrle32/msrle_Ja.rc new file mode 100644 index 00000000000..c2866a155c1 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Ja.rc @@ -0,0 +1,33 @@ +/* + * Japanese resource file for MS-RLE + * + * Copyright 2004 Hajime Segawa + * + * 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 + */ + +/* UTF-8 */ +#pragma code_page(65001) + +LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE ビデオコーデック" + IDS_ABOUT "Wine MS-RLE ビデオコーデック\nCopyright 2002 by Michael Günewig" +} + +#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Ko.rc b/reactos/dll/win32/msrle32/msrle_Ko.rc new file mode 100644 index 00000000000..3f9d137b009 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Ko.rc @@ -0,0 +1,28 @@ +/* + * Korean resource file for MS-RLE + * + * Copyright 2005 YunSong Hwang + * + * 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 + */ + +LANGUAGE LANG_KOREAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE ºñµð¿À ÄÚµ¦" + IDS_ABOUT "Wine MS-RLE ºñµð¿À ÄÚµ¦\nCopyright 2002 by Michael Gunnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Nl.rc b/reactos/dll/win32/msrle32/msrle_Nl.rc new file mode 100644 index 00000000000..f98f5fd9835 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Nl.rc @@ -0,0 +1,28 @@ +/* + * MS-RLE (Dutch resources) + * + * Copyright 2003 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 + */ + +LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE videodecoder" + IDS_ABOUT "Wine MS-RLE videodecoder\nCopyright 2002 Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_No.rc b/reactos/dll/win32/msrle32/msrle_No.rc new file mode 100644 index 00000000000..411e4590447 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_No.rc @@ -0,0 +1,28 @@ +/* + * Norwegian Bokmål resource file for MS-RLE + * + * Copyright 2005 Alexander N. Sørnes + * + * 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 + */ + +LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE-videokodek" + IDS_ABOUT "Wine MS-RLE-videokodek\nKopirett 2002 tilhører Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Pl.rc b/reactos/dll/win32/msrle32/msrle_Pl.rc new file mode 100644 index 00000000000..013fea5a0ed --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Pl.rc @@ -0,0 +1,29 @@ +/* + * English resource file for MS-RLE + * + * Copyright 2002 Michael Gnnewig + * Copyright 2006 Mikolaj Zalewski + * + * 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 + */ + +LANGUAGE LANG_POLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Kodek Wine MS-RLE" + IDS_ABOUT L"Koder-dekoder Wine MS-RLE\nCopyright 2002 - Michael G\x00fcnnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Pt.rc b/reactos/dll/win32/msrle32/msrle_Pt.rc new file mode 100644 index 00000000000..cc74b38e981 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Pt.rc @@ -0,0 +1,38 @@ +/* + * Portuguese resource file for MS-RLE + * + * Copyright 2003 Marcelo Duarte + * Copyright 2006 Américo José Melo + * + * 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 + */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE codificador/decodificador de vídeo" + IDS_ABOUT "Wine MS-RLE codificador/decodificador de vídeo\nCopyright 2002 por Michael Günnewig" +} + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE codificador/decodificador de vídeo" + IDS_ABOUT "Wine MS-RLE codificador/decodificador de vídeo\nDireitos de autor 2002 por Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Ro.rc b/reactos/dll/win32/msrle32/msrle_Ro.rc new file mode 100644 index 00000000000..64366c36a91 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Ro.rc @@ -0,0 +1,31 @@ +/* + * Copyright 2002 Michael Günnewig + * Copyright 2008 Michael Stefaniuc + * + * 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 + */ + +LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL + +#pragma code_page(65001) + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Codecul video Wine MS-RLE" + IDS_ABOUT "Codecul video Wine MS-RLE\nCopyright 2002 by Michael Günnewig" +} + +#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Ru.rc b/reactos/dll/win32/msrle32/msrle_Ru.rc new file mode 100644 index 00000000000..4f8bd56b158 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Ru.rc @@ -0,0 +1,28 @@ +/* + * Russian resource file for MS-RLE + * + * Copyright 2003 Igor Stepin + * + * 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 + */ + +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Âèäåî êîäåê Wine MS-RLE" + IDS_ABOUT "Âèäåî êîäåê Wine MS-RLE\nCopyright 2002 by Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Si.rc b/reactos/dll/win32/msrle32/msrle_Si.rc new file mode 100644 index 00000000000..eeb23739f7d --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Si.rc @@ -0,0 +1,32 @@ +/* + * Slovenian resource file for MS-RLE + * + * Copyright 2003, 2008 Rok Mandeljc + * + * 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 + */ + +#pragma code_page(65001) + +LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE video kodek" + IDS_ABOUT "Wine MS-RLE video kodek\nCopyright 2002 by Michael Günnewig" +} + +#pragma code_page(default) diff --git a/reactos/dll/win32/msrle32/msrle_Sv.rc b/reactos/dll/win32/msrle32/msrle_Sv.rc new file mode 100644 index 00000000000..fba656a33d0 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Sv.rc @@ -0,0 +1,28 @@ +/* + * Swedish resource file for MS-RLE + * + * Copyright 2007 Daniel Nylander + * + * 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 + */ + +LANGUAGE LANG_SWEDISH, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE videokodek" + IDS_ABOUT "Wine MS-RLE videokodek\nCopyright 2002 Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_Tr.rc b/reactos/dll/win32/msrle32/msrle_Tr.rc new file mode 100644 index 00000000000..36cee7531f1 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_Tr.rc @@ -0,0 +1,28 @@ +/* + * Turkish resource file for MS-RLE + * + * Copyright 2006 Fatih Aþýcý + * + * 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 + */ + +LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + IDS_NAME "WINE-MS-RLE" + IDS_DESCRIPTION "Wine MS-RLE vidyo çözücü" + IDS_ABOUT "Wine MS-RLE vidyo çözücü\nTelif Hakký 2002 Michael Günnewig" +} diff --git a/reactos/dll/win32/msrle32/msrle_private.h b/reactos/dll/win32/msrle32/msrle_private.h new file mode 100644 index 00000000000..bf2aed03213 --- /dev/null +++ b/reactos/dll/win32/msrle32/msrle_private.h @@ -0,0 +1,62 @@ +/* + * Copyright 2002 Michael Günnewig + * + * 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 + */ + +#ifndef __MSRLE32_PRIVATE_H +#define __MSRLE32_PRIVATE_H + +#ifndef RC_INVOKED +#include +#endif + +#include "windef.h" +#include "winbase.h" +#include "mmsystem.h" +#include "wingdi.h" +#include "winuser.h" +#include "vfw.h" + +#define IDS_NAME 100 +#define IDS_DESCRIPTION 101 +#define IDS_ABOUT 102 + +#define MSRLE32_DEFAULTQUALITY (75 * ICQUALITY_HIGH) / 100 + +#define FOURCC_RLE mmioFOURCC('R','L','E',' ') +#define FOURCC_RLE4 mmioFOURCC('R','L','E','4') +#define FOURCC_RLE8 mmioFOURCC('R','L','E','8') +#define FOURCC_MRLE mmioFOURCC('M','R','L','E') + +#define WIDTHBYTES(i) ((WORD)((i+31u)&(~31u))/8u) /* ULONG aligned ! */ +#define DIBWIDTHBYTES(bi) WIDTHBYTES((WORD)(bi).biWidth * (WORD)(bi).biBitCount) + +typedef struct _CodecInfo { + FOURCC fccHandler; + DWORD dwQuality; + + BOOL bCompress; + LONG nPrevFrame; + LPWORD pPrevFrame; + LPWORD pCurFrame; + + BOOL bDecompress; + LPBYTE palette_map; +} CodecInfo; + +typedef const BITMAPINFOHEADER * LPCBITMAPINFOHEADER; + +#endif diff --git a/reactos/dll/win32/msrle32/rsrc.rc b/reactos/dll/win32/msrle32/rsrc.rc new file mode 100644 index 00000000000..6d3ff958153 --- /dev/null +++ b/reactos/dll/win32/msrle32/rsrc.rc @@ -0,0 +1,53 @@ +/* + * Top level resource file for MS-RLE + * + * Copyright 2002 Michael Günnewig + * + * 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 "windef.h" +#include "winbase.h" + +#include "msrle_private.h" + +/* + * Everything specific to any language goes + * in one of the specific files. + * Note that you can and may override resources + * which also have a neutral version. This is to + * get localized bitmaps for example. + */ + +#include "msrle_Bg.rc" +#include "msrle_Cs.rc" +#include "msrle_Da.rc" +#include "msrle_De.rc" +#include "msrle_En.rc" +#include "msrle_Es.rc" +#include "msrle_Fr.rc" +#include "msrle_Hu.rc" +#include "msrle_It.rc" +#include "msrle_Ja.rc" +#include "msrle_Ko.rc" +#include "msrle_Nl.rc" +#include "msrle_No.rc" +#include "msrle_Pl.rc" +#include "msrle_Pt.rc" +#include "msrle_Ro.rc" +#include "msrle_Ru.rc" +#include "msrle_Si.rc" +#include "msrle_Sv.rc" +#include "msrle_Tr.rc" diff --git a/reactos/dll/win32/win32.rbuild b/reactos/dll/win32/win32.rbuild index 681aeb99d75..17cb60f4dd1 100644 --- a/reactos/dll/win32/win32.rbuild +++ b/reactos/dll/win32/win32.rbuild @@ -193,9 +193,15 @@ + + + + + + @@ -214,6 +220,9 @@ + + + diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index 99c4ab08bff..491e743fc2b 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -65,11 +65,14 @@ reactos/dll/win32/mlang # Autosync reactos/dll/win32/mpr # Autosync reactos/dll/win32/msacm32 # Out of sync reactos/dll/win32/mscat32 # Autosync +reactos/dll/win32/mscms # Autosync reactos/dll/win32/mscoree # Autosync +reactos/dll/win32/msftedit # Autosync reactos/dll/win32/mshtml # Autosync reactos/dll/win32/msimg32 # Autosync reactos/dll/win32/msi # Autosync reactos/dll/win32/msimtf # Autosync +reactos/dll/win32/msrle32 # Autosync reactos/dll/win32/mstask # Autosync reactos/dll/win32/msvcrt20 # Autosync reactos/dll/win32/msvfw32 # Autosync