[PATCH] GDI+: Implement GdipGetImageEncoders.
Nathan Beckmann
nathan.beckmann at gmail.com
Wed Mar 5 13:21:37 CST 2008
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
More information about the wine-patches
mailing list