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