Alex Villacís Lasso : oleaut32: olepicture - Support multiple redundant headers before picture data.
Alexandre Julliard
julliard at wine.codeweavers.com
Wed Nov 8 14:11:56 CST 2006
Module: wine
Branch: master
Commit: a7128fbc4deadb2ee713d92746a6219725d13b05
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a7128fbc4deadb2ee713d92746a6219725d13b05
Author: Alex Villacís Lasso <a_villacis at palosanto.com>
Date: Mon Nov 6 16:47:25 2006 -0500
oleaut32: olepicture - Support multiple redundant headers before picture data.
---
dlls/oleaut32/olepicture.c | 55 +++++++++++++++++++++++--------------
dlls/oleaut32/tests/olepicture.c | 47 ++++++++++++++++++++++++++++++++
2 files changed, 81 insertions(+), 21 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index f178575..6485c7d 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -1400,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Loa
BOOL headerisdata = FALSE;
BOOL statfailed = FALSE;
ULONG xread, toread;
+ ULONG headerread;
BYTE *xbuf;
DWORD header[2];
WORD magic;
@@ -1431,31 +1432,43 @@ static HRESULT WINAPI OLEPictureImpl_Loa
/* we will read at least 8 byte ... just right below */
statstg.cbSize.QuadPart = 8;
}
- hr=IStream_Read(pStm,header,8,&xread);
- if (hr || xread!=8) {
- FIXME("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
- return hr;
- }
+ toread = 0;
+ headerread = 0;
headerisdata = FALSE;
- xread = 0;
- if (!memcmp(&(header[0]),"lt\0\0", 4) && (header[1] <= statstg.cbSize.QuadPart-8)) {
- toread = header[1];
- } else {
- if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
- !memcmp(&(header[0]), "BM", 2) || /* BMP header */
- !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
- (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
- (header[1]==0)
- ) {/* Incorrect header, assume none. */
- headerisdata = TRUE;
- toread = statstg.cbSize.QuadPart-8;
- xread = 8;
- } else {
- FIXME("Unknown stream header magic: %08x\n", header[0]);
+ do {
+ hr=IStream_Read(pStm,header,8,&xread);
+ if (hr || xread!=8) {
+ FIXME("Failure while reading picture header (hr is %x, nread is %d).\n",hr,xread);
+ return hr;
+ }
+ headerread += xread;
+ xread = 0;
+
+ if (!memcmp(&(header[0]),"lt\0\0", 4) && (statfailed || (header[1] + headerread <= statstg.cbSize.QuadPart))) {
+ if (toread != 0 && toread != header[1])
+ FIXME("varying lengths of image data (prev=%u curr=%u), only last one will be used\n",
+ toread, header[1]);
toread = header[1];
+ if (toread == 0) break;
+ } else {
+ if (!memcmp(&(header[0]), "GIF8", 4) || /* GIF header */
+ !memcmp(&(header[0]), "BM", 2) || /* BMP header */
+ !memcmp(&(header[0]), "\xff\xd8", 2) || /* JPEG header */
+ (header[1] > statstg.cbSize.QuadPart)|| /* invalid size */
+ (header[1]==0)
+ ) {/* Found start of bitmap data */
+ headerisdata = TRUE;
+ if (toread == 0)
+ toread = statstg.cbSize.QuadPart-8;
+ else toread -= 8;
+ xread = 8;
+ } else {
+ FIXME("Unknown stream header magic: %08x\n", header[0]);
+ toread = header[1];
+ }
}
- }
+ } while (!headerisdata);
if (statfailed) { /* we don't know the size ... read all we get */
int sizeinc = 4096;
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
index 6eb7723..8e653ce 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -190,6 +190,8 @@ test_pic(const unsigned char *imgdata, u
HRESULT hres;
LARGE_INTEGER seekto;
ULARGE_INTEGER newpos1;
+ DWORD * header;
+ unsigned int i;
/* Let the fun begin */
hglob = GlobalAlloc (0, imgsize);
@@ -203,10 +205,55 @@ test_pic(const unsigned char *imgdata, u
hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
test_pic_with_stream(stream, imgsize);
+
+ IStream_Release(stream);
/* again with Non Statable and Non Seekable stream */
stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
test_pic_with_stream(stream, 0);
+
+ IStream_Release(stream);
+
+ /* free memory */
+ GlobalUnlock(hglob);
+ GlobalFree(hglob);
+
+ /* more fun!!! */
+ hglob = GlobalAlloc (0, imgsize + 8 * (2 * sizeof(DWORD)));
+ data = GlobalLock (hglob);
+ header = (DWORD *)data;
+
+ /* multiple copies of header */
+ memcpy(data,"lt\0\0",4);
+ header[1] = imgsize;
+ memcpy(&(header[2]), header, 2 * sizeof(DWORD));
+ memcpy(&(header[4]), header, 4 * sizeof(DWORD));
+ memcpy(&(header[8]), header, 8 * sizeof(DWORD));
+
+ memcpy(data + 8 * (2 * sizeof(DWORD)), imgdata, imgsize);
+
+ for (i = 1; i <= 8; i++) {
+ hres = CreateStreamOnHGlobal (hglob, FALSE, &stream);
+ ok (hres == S_OK, "createstreamonhglobal failed? doubt it... hres 0x%08x\n", hres);
+
+ memset(&seekto,0,sizeof(seekto));
+ seekto.u.LowPart = (8 - i) * (2 * sizeof(DWORD));
+ hres = IStream_Seek(stream,seekto,SEEK_CUR,&newpos1);
+ ok (hres == S_OK, "istream seek failed? doubt it... hres 0x%08x\n", hres);
+ test_pic_with_stream(stream, imgsize);
+
+ IStream_Release(stream);
+
+ /* again with Non Statable and Non Seekable stream */
+ stream = (LPSTREAM)NoStatStreamImpl_Construct(hglob);
+ test_pic_with_stream(stream, 0);
+
+ IStream_Release(stream);
+ }
+
+ /* free memory */
+ GlobalUnlock(hglob);
+ GlobalFree(hglob);
}
static void test_empty_image(void) {
More information about the wine-cvs
mailing list