[PATCH] GDI+: Implement GdipGetImageEncoders.

Nathan Beckmann nathan.beckmann at gmail.com
Thu Mar 6 02:38:30 CST 2008


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 at 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
>
>



More information about the wine-devel mailing list