Dmitry Timoshkov : gdiplus: Create a copy of the source stream when loading an image.
Alexandre Julliard
julliard at winehq.org
Tue Jun 19 15:36:27 CDT 2012
Module: wine
Branch: master
Commit: 9e12bc0175f6a65ee45ebce1ca519eac6f5ca501
URL: http://source.winehq.org/git/wine.git/?a=commit;h=9e12bc0175f6a65ee45ebce1ca519eac6f5ca501
Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date: Tue Jun 19 16:51:54 2012 +0900
gdiplus: Create a copy of the source stream when loading an image.
---
dlls/gdiplus/gdiplus_private.h | 3 ++-
dlls/gdiplus/image.c | 34 +++++++++++++++++++++++++++++++---
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/gdiplus_private.h b/dlls/gdiplus/gdiplus_private.h
index 322fb02..9ac9be2 100644
--- a/dlls/gdiplus/gdiplus_private.h
+++ b/dlls/gdiplus/gdiplus_private.h
@@ -260,7 +260,8 @@ struct GpAdustableArrowCap{
};
struct GpImage{
- IPicture* picture;
+ IPicture *picture;
+ IStream *stream; /* a copy of the source stream */
ImageType type;
GUID format;
UINT flags;
diff --git a/dlls/gdiplus/image.c b/dlls/gdiplus/image.c
index 8ad1d24..7da052f 100644
--- a/dlls/gdiplus/image.c
+++ b/dlls/gdiplus/image.c
@@ -1779,6 +1779,7 @@ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(INT width, INT height, INT stride,
(*bitmap)->height = height;
(*bitmap)->format = format;
(*bitmap)->image.picture = NULL;
+ (*bitmap)->image.stream = NULL;
(*bitmap)->hbitmap = hbitmap;
(*bitmap)->hdc = NULL;
(*bitmap)->bits = bits;
@@ -2029,6 +2030,8 @@ GpStatus WINGDIPAPI GdipDisposeImage(GpImage *image)
}
if (image->picture)
IPicture_Release(image->picture);
+ if (image->stream)
+ IStream_Release(image->stream);
GdipFree(image->palette_entries);
image->type = ~0;
GdipFree(image);
@@ -2704,6 +2707,7 @@ end:
bitmap->image.flags |= ImageFlagsReadOnly|ImageFlagsHasRealPixelSize|ImageFlagsHasRealDPI|ImageFlagsColorSpaceRGB;
bitmap->image.frame_count = frame_count;
bitmap->image.current_frame = active_frame;
+ bitmap->image.stream = stream;
}
return status;
@@ -2771,6 +2775,7 @@ static GpStatus decode_image_olepicture_metafile(IStream* stream, REFCLSID clsid
*image = GdipAlloc(sizeof(GpMetafile));
if(!*image) return OutOfMemory;
(*image)->type = ImageTypeMetafile;
+ (*image)->stream = stream;
(*image)->picture = pic;
(*image)->flags = ImageFlagsNone;
(*image)->frame_count = 1;
@@ -2857,21 +2862,42 @@ static GpStatus get_decoder_info(IStream* stream, const struct image_codec **res
return GenericError;
}
-GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream* stream, GpImage **image)
+GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream *source, GpImage **image)
{
GpStatus stat;
LARGE_INTEGER seek;
HRESULT hr;
const struct image_codec *codec=NULL;
+ IStream *stream;
+
+ hr = IStream_Clone(source, &stream);
+ if (FAILED(hr))
+ {
+ STATSTG statstg;
+
+ hr = IStream_Stat(source, &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) return stat;
+ 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)) return hresult_to_status(hr);
+ 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, 0, image);
@@ -2880,8 +2906,10 @@ GpStatus WINGDIPAPI GdipLoadImageFromStream(IStream* stream, GpImage **image)
if (stat == Ok)
{
memcpy(&(*image)->format, &codec->info.FormatID, sizeof(GUID));
+ return Ok;
}
+ IStream_Release(stream);
return stat;
}
More information about the wine-cvs
mailing list