gdiplus: Implement GdipImageSelectActiveFrame.

This commit is contained in:
Dmitry Timoshkov 2012-06-20 13:45:39 +09:00 committed by Alexandre Julliard
parent b85270e3a5
commit 755c19f3e7
2 changed files with 97 additions and 21 deletions

View File

@ -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,88 @@ 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;
new_image->type = ~0;
GdipFree(new_image);
return Ok;
}
IStream_Release(stream);
return stat;
}
GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *source, GpImage **image)
{
GpStatus stat;

View File

@ -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);