Improved msrle32 library

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hallo.

A new patch which fixes the following issues:

- Fixed end flags while encoding -- only EOI instead of EOL and EOI.
- Fixed 4-bit RLE encoding of keyframes.
- Fixed signed/unsigned mismatches.
- Added some missing const's.

Non-keyframes for 4-bit RLE-encoding will come later.


  Michael

Index: dlls/msvideo/msrle32/msrle32.c
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msrle32/msrle32.c,v
retrieving revision 1.3
diff -d -u -r1.3 msrle32.c
--- dlls/msvideo/msrle32/msrle32.c	4 Nov 2002 23:53:44 -0000	1.3
+++ dlls/msvideo/msrle32/msrle32.c	13 Jun 2003 17:07:02 -0000
@@ -155,7 +155,7 @@
   /* check for size(s) */
   if (!lpbi->biWidth || !lpbi->biHeight)
     return FALSE; /* image with zero size, makes no sense so error ! */
-  if (DIBWIDTHBYTES(*lpbi) * lpbi->biHeight >= (1UL << 31) - 1)
+  if (DIBWIDTHBYTES(*lpbi) * (DWORD)lpbi->biHeight >= (1UL << 31) - 1)
     return FALSE; /* image too big ! */
 
   /* check for non existing colortable for hi- and true-color DIB's */
@@ -169,7 +169,7 @@
 {
   INT  diff = 0x00FFFFFF;
   UINT i;
-  UINT index = 0;
+  UINT idx = 0;
 
   /* pre-conditions */
   assert(clrs != NULL);
@@ -182,14 +182,14 @@
     r = r*r + g*g + b*b;
 
     if (r < diff) {
-      index = i;
-      diff  = r;
+      idx  = i;
+      diff = r;
       if (diff == 0)
 	break;
     }
   }
 
-  return index;
+  return idx;
 }
 
 /*****************************************************************************/
@@ -197,29 +197,31 @@
 void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBYTE lpIn)
 {
   WORD   wIntensityTbl[256];
-  LONG   lInLine, lOutLine;
+  DWORD  lInLine, lOutLine;
   LPWORD lpOut;
-  int i, y;
+  UINT   i;
+  LONG   y;
 
   /* pre-conditions */
   assert(pi != NULL && lpbiIn != NULL && lpIn != NULL);
   assert(pi->pCurFrame != NULL);
 
   lInLine  = DIBWIDTHBYTES(*lpbiIn);
-  lOutLine = WIDTHBYTES(lpbiIn->biWidth * 8*sizeof(WORD)) / 2;
+  lOutLine = WIDTHBYTES((WORD)lpbiIn->biWidth * 8u * sizeof(WORD)) / 2u;
   lpOut    = pi->pCurFrame;
 
   assert(lpbiIn->biClrUsed != 0);
 
   {
-    const RGBQUAD *lp = (LPRGBQUAD)((LPBYTE)lpbiIn + lpbiIn->biSize);
+    const RGBQUAD *lp =
+      (const RGBQUAD *)((const BYTE*)lpbiIn + lpbiIn->biSize);
 
     for (i = 0; i < lpbiIn->biClrUsed; i++)
       wIntensityTbl[i] = Intensity(lp[i]);
   }
 
   for (y = 0; y < lpbiIn->biHeight; y++) {
-    int x;
+    LONG x;
 
     switch (lpbiIn->biBitCount) {
     case 1:
@@ -388,9 +390,9 @@
     while (count > 2) {
       INT  i;
       INT  size       = min(count, 254);
-      BOOL extra_byte = (size/2) % 2;
+      BOOL extra_byte = (size / 2) % 2 || (size % 2);
 
-      *lpSizeImage += 2 + size/2 + extra_byte;
+      *lpSizeImage += 2 + size/2 + (size % 2) + extra_byte;
       count -= size;
       *lpOut++ = 0;
       *lpOut++ = size;
@@ -530,6 +532,7 @@
 {
   LPWORD lpC;
   LONG   lLine, lInLine, lDist;
+  LPBYTE lpOutStart = lpOut;
 
   /* pre-conditions */
   assert(pi != NULL && lpbiOut != NULL);
@@ -560,6 +563,7 @@
       /* add EOL -- end of line */
       lpbiOut->biSizeImage += 2;
       *((LPWORD)lpOut)++ = 0;
+      assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
     }
   } else {
     /* delta-frame -- compute delta between last and this internal frame */
@@ -656,14 +660,14 @@
 	/* add EOL -- end of line */
 	lpbiOut->biSizeImage += 2;
 	*((LPWORD)lpOut)++ = 0;
+	assert(lpOut == lpOutStart + lpbiOut->biSizeImage);
       }
     }
   }
 
-  /* add EOI -- end of image */
-  lpbiOut->biSizeImage += 2;
-  *lpOut++ = 0;
-  *lpOut++ = 1;
+  /* change EOL to EOI -- end of image */
+  lpOut[-1] = 1;
+  assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
 
   return ICERR_OK;
 }
@@ -672,6 +676,7 @@
 {
   LPWORD lpC;
   LONG   lDist, lInLine, lLine;
+  LPBYTE lpOutStart = lpOut;
 
   assert(pi != NULL && lpbiOut != NULL);
   assert(lpIn != NULL && lpOut != NULL);
@@ -693,6 +698,7 @@
       do {
 	x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x,
 			     &lpOut, &lpbiOut->biSizeImage);
+	assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
       } while (x < lpbiOut->biWidth);
 
       lpC  += lLine;
@@ -701,6 +707,7 @@
       /* add EOL -- end of line */
       lpbiOut->biSizeImage += 2;
       *((LPWORD)lpOut)++ = 0;
+      assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
     }
   } else {
     /* delta-frame -- compute delta between last and this internal frame */
@@ -745,6 +752,7 @@
 	    /* add EOL -- end of line */
 	    lpbiOut->biSizeImage += 2;
 	    *((LPWORD)lpOut)++ = 0;
+	    assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
 	  }
 
 	  /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */
@@ -770,6 +778,7 @@
 	  /* skip the 'same' things corresponding to previous frame */
 	  x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x,
 			       &lpOut, &lpbiOut->biSizeImage);
+	  assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
 	}
       } while (x < lpbiOut->biWidth);
 
@@ -782,14 +791,14 @@
 	lpbiOut->biSizeImage += 2;
 	*lpOut++ = 0;
 	*lpOut++ = 0;
+	assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
       }
     }
   }
 
-  /* add EOI -- end of image */
-  lpbiOut->biSizeImage += 2;
-  *lpOut++ = 0;
-  *lpOut++ = 1;
+  /* change EOL to EOI -- end of image */
+  lpOut[-1] = 1;
+  assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
 
   return ICERR_OK;
 }
@@ -838,7 +847,7 @@
 	}
 	break;
       default: /* absolute mode */
-	extra_byte = (code1 / 2) & 0x01;
+	extra_byte = (code1 / 2) & 0x01 || (code1 % 2);
 
 	if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth)
 	  return ICERR_ERROR;
@@ -848,14 +857,14 @@
 	  if (bytes_per_pixel == 1) {
 	    code1 = lpIn[i];
 	    lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)];
-	    if (2 * i <= code0)
+	    if (2 * i + 1 <= code0)
 	      lpOut[pixel_ptr++] = pi->palette_map[(code1 & 0x0F)];
 	  } else if (bytes_per_pixel == 2) {
 	    code1 = lpIn[i] >> 4;
 	    lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
 	    lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
 
-	    if (2 * i <= code0) {
+	    if (2 * i + 1 <= code0) {
 	      code1 = lpIn[i] & 0x0F;
 	      lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
 	      lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
@@ -867,7 +876,7 @@
 	    lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
 	    pixel_ptr += bytes_per_pixel;
 
-	    if (2 * i <= code0) {
+	    if (2 * i + 1 <= code0) {
 	      code1 = lpIn[i] & 0x0F;
 	      lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
 	      lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
@@ -876,6 +885,23 @@
 	    }
 	  }
 	}
+	if (code0 & 0x01) {
+	  if (bytes_per_pixel == 1) {
+	    code1 = lpIn[i];
+	    lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)];
+	  } else if (bytes_per_pixel == 2) {
+	    code1 = lpIn[i] >> 4;
+	    lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
+	    lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
+	  } else {
+	    code1 = lpIn[i] >> 4;
+	    lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
+	    lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
+	    lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
+	    pixel_ptr += bytes_per_pixel;
+	  }
+	  lpIn++;
+	}
 	lpIn += code0 / 2;
 
 	/* if the RLE code is odd, skip a byte in the stream */
@@ -1240,11 +1266,11 @@
       size = 1<<lpbiIn->biBitCount;
     else
       size = lpbiIn->biClrUsed;
-    lpbiOut->biClrUsed       = min(size, 1u << lpbiOut->biBitCount);
+    lpbiOut->biClrUsed       = min(size, 1 << lpbiOut->biBitCount);
     lpbiOut->biClrImportant  = 0;
 
     memcpy((LPBYTE)lpbiOut + lpbiOut->biSize,
-	   (LPBYTE)lpbiIn + lpbiIn->biSize, lpbiOut->biClrUsed * sizeof(RGBQUAD));
+	   (const BYTE*)lpbiIn + lpbiIn->biSize, lpbiOut->biClrUsed * sizeof(RGBQUAD));
 
     return ICERR_OK;
   } else
@@ -1319,10 +1345,10 @@
 static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
 			     LPCBITMAPINFOHEADER lpbiOut)
 {
-  RGBQUAD *rgbIn;
-  RGBQUAD *rgbOut;
-  int      i;
-  size_t   size;
+  const RGBQUAD *rgbIn;
+  const RGBQUAD *rgbOut;
+  UINT   i;
+  size_t size;
 
   TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
 
@@ -1336,7 +1362,7 @@
   if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
     return ICERR_BADFORMAT;
 
-  /* FIXME: cannot compress and decompress at a time! */
+  /* FIXME: cannot compress and decompress at same time! */
   if (pi->bDecompress) {
     FIXME("cannot compress and decompress at same time!\n");
     return ICERR_ERROR;
@@ -1357,8 +1383,8 @@
   pi->nPrevFrame = -1;
   pi->bCompress  = TRUE;
 
-  rgbIn  = (RGBQUAD*)((LPBYTE)lpbiIn  + lpbiIn->biSize);
-  rgbOut = (RGBQUAD*)((LPBYTE)lpbiOut + lpbiOut->biSize);
+  rgbIn  = (const RGBQUAD*)((const BYTE*)lpbiIn  + lpbiIn->biSize);
+  rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
 
   switch (lpbiOut->biBitCount) {
   case 4:
@@ -1583,9 +1609,9 @@
 static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
 			       LPCBITMAPINFOHEADER lpbiOut)
 {
-  RGBQUAD *rgbIn;
-  RGBQUAD *rgbOut;
-  int      i;
+  const RGBQUAD *rgbIn;
+  const RGBQUAD *rgbOut;
+  UINT  i;
 
   TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
 
@@ -1607,8 +1633,8 @@
   if (pi->bDecompress)
     DecompressEnd(pi);
 
-  rgbIn  = (RGBQUAD*)((LPBYTE)lpbiIn  + lpbiIn->biSize);
-  rgbOut = (RGBQUAD*)((LPBYTE)lpbiOut + lpbiOut->biSize);
+  rgbIn  = (const RGBQUAD*)((const BYTE*)lpbiIn  + lpbiIn->biSize);
+  rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
 
   switch (lpbiOut->biBitCount) {
   case 4:
@@ -1732,7 +1758,7 @@
 
     lpbiOut->biClrUsed = size;
 
-    memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (LPBYTE)lpbiIn + lpbiIn->biSize, size * sizeof(RGBQUAD));
+    memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, (const BYTE*)lpbiIn + lpbiIn->biSize, size * sizeof(RGBQUAD));
   } /* else could never occur ! */
 
   return ICERR_OK;
Index: dlls/msvideo/msrle32/msrle_private.h
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msrle32/msrle_private.h,v
retrieving revision 1.2
diff -d -u -r1.2 msrle_private.h
--- dlls/msvideo/msrle32/msrle_private.h	3 Jan 2003 19:12:56 -0000	1.2
+++ dlls/msvideo/msrle32/msrle_private.h	13 Jun 2003 17:07:02 -0000
@@ -36,7 +36,7 @@
 #define FOURCC_RLE8  mmioFOURCC('R','L','E','8')
 #define FOURCC_MRLE  mmioFOURCC('M','R','L','E')
 
-#define WIDTHBYTES(i)     ((WORD)((i+31)&(~31))/8) /* ULONG aligned ! */
+#define WIDTHBYTES(i)     ((WORD)((i+31u)&(~31u))/8u) /* ULONG aligned ! */
 #define DIBWIDTHBYTES(bi) WIDTHBYTES((WORD)(bi).biWidth * (WORD)(bi).biBitCount)
 
 typedef struct _CodecInfo {

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux