[5/5] gdiplus: Implement GdipImageSelectActiveFrame.
Dmitry Timoshkov
dmitry at baikal.ru
Tue Jun 19 02:52:02 CDT 2012
---
dlls/gdiplus/image.c | 112 +++++++++++++++++++++++++++++++++++++--------
dlls/gdiplus/tests/image.c | 4 +-
2 files changed, 95 insertions(+), 21 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 7da052f..9dada84 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1995,10 +1995,8 @@ static void move_bitmap(GpBitmap *dst, GpBitmap *src, BOOL clobber_palette)
GdipFree(src);
}
-GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
+static GpStatus free_image_data(GpImage *image)
{
- TRACE("%p\n", image);
-
if(!image)
return InvalidParameter;
@@ -2033,6 +2031,18 @@ GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
if (image->stream)
IStream_Release(image->stream);
GdipFree(image->palette_entries);
+
+ return Ok;
+}
+
+GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
+{
+ GpStatus status;
+
+ TRACE("%p\n", image);
+
+ status = free_image_data(image);
+ if (status != Ok) return status;
image->type = ~0;
GdipFree(image);
@@ -2522,22 +2532,6 @@ GpStatus WINGDIPAPI GdipImageGetFrameDimensionsList(GpImage* image,
return Ok;
}
-GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image,
- GDIPCONST GUID* dimensionID, UINT frameidx)
-{
- static int calls;
-
- TRACE("(%p, %s, %u)\n", image, debugstr_guid(dimensionID), frameidx);
-
- if(!image || !dimensionID)
- return InvalidParameter;
-
- if(!(calls++))
- FIXME("not implemented\n");
-
- return Ok;
-}
-
GpStatus WINGDIPAPI GdipLoadImageFromFile(GDIPCONST WCHAR* filename,
GpImage **image)
{
@@ -2862,6 +2856,86 @@ static GpStatus get_decoder_info(IStream* stream, const struct image_codec **res
return GenericError;
}
+GpStatus WINGDIPAPI GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID *dimensionID,
+ UINT frame)
+{
+ GpStatus stat;
+ LARGE_INTEGER seek;
+ HRESULT hr;
+ const struct image_codec *codec = NULL;
+ IStream *stream;
+ GpImage *new_image;
+
+ TRACE("(%p,%s,%u)\n", image, debugstr_guid(dimensionID), frame);
+
+ if (!image || !dimensionID)
+ return InvalidParameter;
+
+ if (frame >= image->frame_count)
+ return InvalidParameter;
+
+ if (image->type != ImageTypeBitmap && image->type != ImageTypeMetafile)
+ {
+ WARN("invalid image type %d\n", image->type);
+ return InvalidParameter;
+ }
+
+ if (image->current_frame == frame)
+ return Ok;
+
+ if (!image->stream)
+ {
+ TRACE("image doesn't have an associated stream\n");
+ return Ok;
+ }
+
+ hr = IStream_Clone(image->stream, &stream);
+ if (FAILED(hr))
+ {
+ STATSTG statstg;
+
+ hr = IStream_Stat(image->stream, &statstg, STATFLAG_NOOPEN);
+ if (FAILED(hr)) return hresult_to_status(hr);
+
+ stat = GdipCreateStreamOnFile(statstg.pwcsName, GENERIC_READ, &stream);
+ if (stat != Ok) return stat;
+ }
+
+ /* choose an appropriate image decoder */
+ stat = get_decoder_info(stream, &codec);
+ if (stat != Ok)
+ {
+ IStream_Release(stream);
+ return stat;
+ }
+
+ /* seek to the start of the stream */
+ seek.QuadPart = 0;
+ hr = IStream_Seek(stream, seek, STREAM_SEEK_SET, NULL);
+ if (FAILED(hr))
+ {
+ IStream_Release(stream);
+ return hresult_to_status(hr);
+ }
+
+ /* call on the image decoder to do the real work */
+ stat = codec->decode_func(stream, &codec->info.Clsid, frame, &new_image);
+
+ if (stat == Ok)
+ {
+ memcpy(&new_image->format, &codec->info.FormatID, sizeof(GUID));
+ free_image_data(image);
+ if (image->type == ImageTypeBitmap)
+ *(GpBitmap *)image = *(GpBitmap *)new_image;
+ else if (image->type == ImageTypeMetafile)
+ *(GpMetafile *)image = *(GpMetafile *)new_image;
+ return Ok;
+ }
+
+ IStream_Release(stream);
+ return stat;
+}
+
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *source, GpImage **image)
{
GpStatus stat;
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 635b633..84baaa3 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -2307,7 +2307,7 @@ static void test_multiframegif(void)
color = 0xdeadbeef;
GdipBitmapGetPixel(bmp, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xff000000, color);
+ expect(0xff000000, color);
stat = GdipImageSelectActiveFrame((GpImage*)bmp, &dimension, 0);
expect(Ok, stat);
@@ -2338,7 +2338,7 @@ static void test_multiframegif(void)
stat = GdipBitmapGetPixel(bmp, 0, 0, &color);
expect(Ok, stat);
- todo_wine expect(0xffffffff, color);
+ expect(0xffffffff, color);
GdipDisposeImage((GpImage*)bmp);
IStream_Release(stream);
--
1.7.11
More information about the wine-patches
mailing list