Dmitry Timoshkov : gdiplus: Add GIF frame delay to the image properties.
Alexandre Julliard
julliard at winehq.org
Tue Sep 25 15:13:38 CDT 2012
Module: wine
Branch: master
Commit: 3bb4974dd45b8030afd64948e20f616f8a6cc8b3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=3bb4974dd45b8030afd64948e20f616f8a6cc8b3
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Tue Sep 25 12:52:19 2012 +0900
gdiplus: Add GIF frame delay to the image properties.
---
dlls/gdiplus/image.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 69879ac..5c7c30a 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -3195,13 +3195,81 @@ static PropertyItem *get_gif_comment(IWICMetadataReader *reader)
return comment;
}
-static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT active_frame)
+static LONG get_gif_frame_delay(IWICBitmapFrameDecode *frame)
{
+ static const WCHAR delayW[] = { 'D','e','l','a','y',0 };
HRESULT hr;
IWICMetadataBlockReader *block_reader;
IWICMetadataReader *reader;
UINT block_count, i;
- PropertyItem *comment = NULL;
+ PropertyItem *delay;
+ LONG value = 0;
+
+ hr = IWICBitmapFrameDecode_QueryInterface(frame, &IID_IWICMetadataBlockReader, (void **)&block_reader);
+ if (hr == S_OK)
+ {
+ hr = IWICMetadataBlockReader_GetCount(block_reader, &block_count);
+ if (hr == S_OK)
+ {
+ for (i = 0; i < block_count; i++)
+ {
+ hr = IWICMetadataBlockReader_GetReaderByIndex(block_reader, i, &reader);
+ if (hr == S_OK)
+ {
+ delay = get_property(reader, &GUID_MetadataFormatGCE, delayW);
+ if (delay)
+ {
+ if (delay->type == PropertyTagTypeShort && delay->length == 2)
+ value = *(SHORT *)delay->value;
+
+ GdipFree(delay);
+ }
+ IWICMetadataReader_Release(reader);
+ }
+ }
+ }
+ IWICMetadataBlockReader_Release(block_reader);
+ }
+
+ return value;
+}
+
+static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UINT active_frame)
+{
+ HRESULT hr;
+ IWICBitmapFrameDecode *frame;
+ IWICMetadataBlockReader *block_reader;
+ IWICMetadataReader *reader;
+ UINT frame_count, block_count, i;
+ PropertyItem *delay = NULL, *comment = NULL;
+
+ IWICBitmapDecoder_GetFrameCount(decoder, &frame_count);
+ if (frame_count > 1)
+ {
+ delay = GdipAlloc(sizeof(*delay) + frame_count * sizeof(LONG));
+ if (delay)
+ {
+ LONG *value;
+
+ delay->type = PropertyTagTypeLong;
+ delay->id = PropertyTagFrameDelay;
+ delay->length = frame_count * sizeof(LONG);
+ delay->value = delay + 1;
+
+ value = delay->value;
+
+ for (i = 0; i < frame_count; i++)
+ {
+ hr = IWICBitmapDecoder_GetFrame(decoder, i, &frame);
+ if (hr == S_OK)
+ {
+ value[i] = get_gif_frame_delay(frame);
+ IWICBitmapFrameDecode_Release(frame);
+ }
+ else value[i] = 0;
+ }
+ }
+ }
hr = IWICBitmapDecoder_QueryInterface(decoder, &IID_IWICMetadataBlockReader, (void **)&block_reader);
if (hr == S_OK)
@@ -3224,8 +3292,10 @@ static void gif_metadata_reader(GpBitmap *bitmap, IWICBitmapDecoder *decoder, UI
IWICMetadataBlockReader_Release(block_reader);
}
+ if (delay) add_property(bitmap, delay);
if (comment) add_property(bitmap, comment);
+ GdipFree(delay);
GdipFree(comment);
}
More information about the wine-cvs
mailing list