From a7128fbc4deadb2ee713d92746a6219725d13b05 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alex=20Villac=C3=ADs=20Lasso?= Date: Mon, 6 Nov 2006 16:47:25 -0500 Subject: [PATCH] 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 f178575e865..6485c7d1007 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -1400,6 +1400,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { 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_Load(IPersistStream* iface,IStream*pStm) { /* 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 6eb77230ddf..8e653ced314 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -190,6 +190,8 @@ test_pic(const unsigned char *imgdata, unsigned int imgsize) 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, unsigned int imgsize) 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) { -- 2.11.4.GIT