Don't apply this patch. The test cases crash on Windows. I was using winetricks to test and accidentally did not test under Windows. - Nathan On Wed, Mar 5, 2008 at 11:21 AM, Nathan Beckmann <nathan.beckmann(a)gmail.com> wrote:
Implement helper GdipGetImageEncodersSize.
Also included tests. --- dlls/gdiplus/gdiplus.spec | 4 +- dlls/gdiplus/image.c | 87 ++++++++++++++++++++++++++++++++++++++++++++ dlls/gdiplus/tests/image.c | 53 +++++++++++++++++++++++++++ include/gdiplusenums.h | 13 +++++++ include/gdiplusflat.h | 2 + include/gdiplusimaging.h | 35 ++++++++++++++++++ 6 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/gdiplus.spec b/dlls/gdiplus/gdiplus.spec index b4f314a..a477086 100644 --- a/dlls/gdiplus/gdiplus.spec +++ b/dlls/gdiplus/gdiplus.spec @@ -284,8 +284,8 @@ @ stub GdipGetImageDecoders @ stub GdipGetImageDecodersSize @ stdcall GdipGetImageDimension(ptr ptr ptr) -@ stub GdipGetImageEncoders -@ stub GdipGetImageEncodersSize +@ stdcall GdipGetImageEncoders(long long ptr) +@ stdcall GdipGetImageEncodersSize(ptr ptr) @ stub GdipGetImageFlags @ stdcall GdipGetImageGraphicsContext(ptr ptr) @ stdcall GdipGetImageHeight(ptr ptr) diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c index 5871209..330d90f 100644 --- a/dlls/gdiplus/image.c +++ b/dlls/gdiplus/image.c @@ -831,3 +831,90 @@ GpStatus WINGDIPAPI GdipSetImagePalette(GpImage *image,
return NotImplemented; } + +/************************************************************************* + * Encoders - + * Implemented as dummy objects that let the user know which files are + * supported. Actual encoding is done by OLE. + * + * This code is based heavily on libgdiplus (Mono): + */ + +typedef enum { + BMP, + ICO, +} ImageFormat; + +#define NUM_ENCODERS_SUPPORTED 2 + +/* ImageCodecInfo creation routines taken from libgdiplus */ +static const WCHAR bmp_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'B', 'M', 'P', 0}; /* Built-in BMP */ +static const WCHAR bmp_extension[] = {'*','.','B', 'M', 'P',';', '*','.', 'D','I', 'B',';', '*','.', 'R', 'L', 'E',0}; /* *.BMP;*.DIB;*.RLE */ +static const WCHAR bmp_mimetype[] = {'i', 'm', 'a','g', 'e', '/', 'b', 'm', 'p', 0}; /* image/bmp */ +static const WCHAR bmp_format[] = {'B', 'M', 'P', 0}; /* BMP */ +static const BYTE bmp_sig_pattern[] = { 0x42, 0x4D }; +static const BYTE bmp_sig_mask[] = { 0xFF, 0xFF }; + +static const WCHAR ico_codecname[] = {'B', 'u', 'i','l', 't', '-','i', 'n', ' ', 'I', 'C', 'O', 0}; /* Built-in ICO */ +static const WCHAR ico_extension[] = {'*','.','I', 'C', 'O', 0}; /* *.ICO */ +static const WCHAR ico_mimetype[] = {'i', 'm', 'a','g', 'e', '/', 'x', '-', 'i', 'c', 'o', 'n', 0}; /* image/x-icon */ +static const WCHAR ico_format[] = {'I', 'C', 'O', 0}; /* ICO */ +static const BYTE ico_sig_pattern[] = { 0x00, 0x00, 0x01, 0x00 }; +static const BYTE ico_sig_mask[] = { 0xFF, 0xFF, 0xFF, 0xFF }; + +static const ImageCodecInfo codecs[NUM_ENCODERS_SUPPORTED] = + { + { /* BMP */ + /* Clsid */ { 0x557cf400, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }, + /* FormatID */ { 0xb96b3cabU, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} }, + /* CodecName */ (const WCHAR*) bmp_codecname, + /* DllName */ NULL, + /* FormatDescription */ (const WCHAR*) bmp_format, + /* FilenameExtension */ (const WCHAR*) bmp_extension, + /* MimeType */ (const WCHAR*) bmp_mimetype, + /* Flags */ ImageCodecFlagsEncoder | ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin, + /* Version */ 1, + /* SigCount */ 1, + /* SigSize */ 2, + /* SigPattern */ (const BYTE*) bmp_sig_pattern, + /* SigMask */ (const BYTE*) bmp_sig_mask, + }, + { /* ICO */ + /* Clsid */ { 0x557cf407, 0x1a04, 0x11d3, { 0x9a, 0x73, 0x0, 0x0, 0xf8, 0x1e, 0xf3, 0x2e } }, + /* FormatID */ { 0xb96b3cb5U, 0x0728U, 0x11d3U, {0x9d, 0x7b, 0x00, 0x00, 0xf8, 0x1e, 0xf3, 0x2e} }, + /* CodecName */ (const WCHAR*) ico_codecname, + /* DllName */ NULL, + /* FormatDescription */ (const WCHAR*) ico_format, + /* FilenameExtension */ (const WCHAR*) ico_extension, + /* MimeType */ (const WCHAR*) ico_mimetype, + /* Flags */ ImageCodecFlagsDecoder | ImageCodecFlagsSupportBitmap | ImageCodecFlagsBuiltin, + /* Version */ 1, + /* SigCount */ 1, + /* SigSize */ 4, + /* SigPattern */ (const BYTE*) ico_sig_pattern, + /* SigMask */ (const BYTE*) ico_sig_mask, + }, + }; + +GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size) +{ + if (!numEncoders || !size) + return InvalidParameter; + + *numEncoders = NUM_ENCODERS_SUPPORTED; + *size = sizeof (codecs); + + return Ok; +} + +GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders) +{ + if (!encoders || + (numEncoders != NUM_ENCODERS_SUPPORTED) || + (size != sizeof (codecs))) + return InvalidParameter; + + memcpy(encoders, codecs, sizeof (codecs)); + + return Ok; +} diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c index 5ff164d..5f75c15 100644 --- a/dlls/gdiplus/tests/image.c +++ b/dlls/gdiplus/tests/image.c @@ -122,6 +122,58 @@ static void test_LoadingImages(void) expect(InvalidParameter, stat); }
+static void test_encoders(void) +{ + GpStatus stat; + UINT n; + UINT s; + ImageCodecInfo *codecs; + int i; + int bmp_found; + + static const WCHAR bmp_format[] = {'B', 'M', 'P', 0}; + + stat = GdipGetImageEncodersSize(NULL, NULL); + expect(stat, InvalidParameter); + + stat = GdipGetImageEncodersSize(&n, &s); + expect(stat, Ok); + + codecs = GdipAlloc(sizeof(ImageCodecInfo) * n); + if (!codecs) + return; + + stat = GdipGetImageEncoders(n, s, NULL); + expect(stat, InvalidParameter); + + stat = GdipGetImageEncoders(0, s, codecs); + expect(stat, InvalidParameter); + + stat = GdipGetImageEncoders(n, s-1, codecs); + expect(stat, InvalidParameter); + + stat = GdipGetImageEncoders(n, s+1, codecs); + expect(stat, InvalidParameter); + + stat = GdipGetImageEncoders(n, s, codecs); + expect(stat, Ok); + + bmp_found = FALSE; + for (i = 0; i < n; i++) + { + if (CompareStringW(LOCALE_SYSTEM_DEFAULT, 0, + codecs[i].FormatDescription, -1, + bmp_format, -1) == CSTR_EQUAL) { + bmp_found = TRUE; + break; + } + } + if (!bmp_found) + ok(FALSE, "No BMP codec found.\n"); + + GdipFree(codecs); +} + START_TEST(image) { struct GdiplusStartupInput gdiplusStartupInput; @@ -137,6 +189,7 @@ START_TEST(image) test_Scan0(); test_GetImageDimension(); test_LoadingImages(); + test_encoders();
GdiplusShutdown(gdiplusToken); } diff --git a/include/gdiplusenums.h b/include/gdiplusenums.h index 7c97005..c579ebe 100644 --- a/include/gdiplusenums.h +++ b/include/gdiplusenums.h @@ -257,6 +257,18 @@ enum HotkeyPrefix HotkeyPrefixHide = 2 };
+enum ImageCodecFlags +{ + ImageCodecFlagsEncoder = 1, + ImageCodecFlagsDecoder = 2, + ImageCodecFlagsSupportBitmap = 4, + ImageCodecFlagsSupportVector = 8, + ImageCodecFlagsSeekableEncode = 16, + ImageCodecFlagsBlockingDecode = 32, + ImageCodecFlagsBuiltin = 65536, + ImageCodecFlagsSystem = 131072, + ImageCodecFlagsUser = 262144 +};
#ifndef __cplusplus
@@ -286,6 +298,7 @@ typedef enum StringTrimming StringTrimming; typedef enum StringFormatFlags StringFormatFlags; typedef enum HotkeyPrefix HotkeyPrefix; typedef enum PenAlignment GpPenAlignment; +typedef enum ImageCodecFlags ImageCodecFlags;
#endif /* end of c typedefs */
diff --git a/include/gdiplusflat.h b/include/gdiplusflat.h index 1f635ba..b15a4ea 100644 --- a/include/gdiplusflat.h +++ b/include/gdiplusflat.h @@ -257,6 +257,8 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromStreamICM(IStream*,GpBitmap**); GpStatus WINGDIPAPI GdipDisposeImage(GpImage*); GpStatus WINGDIPAPI GdipFindFirstImageItem(GpImage*,ImageItemData*); GpStatus WINGDIPAPI GdipFindNextImageItem(GpImage*,ImageItemData*); +GpStatus WINGDIPAPI GdipGetImageEncodersSize(UINT *numEncoders, UINT *size); +GpStatus WINGDIPAPI GdipGetImageEncoders(UINT numEncoders, UINT size, ImageCodecInfo *encoders); GpStatus WINGDIPAPI GdipGetImageItemData(GpImage*,ImageItemData*); GpStatus WINGDIPAPI GdipGetImageBounds(GpImage*,GpRectF*,GpUnit*); GpStatus WINGDIPAPI GdipGetImageGraphicsContext(GpImage*,GpGraphics**); diff --git a/include/gdiplusimaging.h b/include/gdiplusimaging.h index c78e1b1..a843da1 100644 --- a/include/gdiplusimaging.h +++ b/include/gdiplusimaging.h @@ -43,6 +43,24 @@ public: EncoderParameter Parameter[1]; };
+class ImageCodecInfo +{ +public: + CLSID Clsid; + GUID FormatID; + const WCHAR* CodecName; + const WCHAR* DllName; + const WCHAR* FormatDescription; + const WCHAR* FilenameExtension; + const WCHAR* MimeType; + DWORD Flags; + DWORD Version; + DWORD SigCount; + DWORD SigSize; + const BYTE* SigPattern; + const BYTE* SigMask; +}; + class BitmapData { public: @@ -84,6 +102,23 @@ typedef struct EncoderParameters EncoderParameter Parameter[1]; } EncoderParameters;
+typedef struct ImageCodecInfo +{ + CLSID Clsid; + GUID FormatID; + const WCHAR* CodecName; + const WCHAR* DllName; + const WCHAR* FormatDescription; + const WCHAR* FilenameExtension; + const WCHAR* MimeType; + DWORD Flags; + DWORD Version; + DWORD SigCount; + DWORD SigSize; + const BYTE* SigPattern; + const BYTE* SigMask; +} ImageCodecInfo; + typedef struct BitmapData { UINT Width; -- 1.5.4.2