[MSRLE32] Some bugs and improvements.

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

 



Changelog:
  - Fixed interframe compression - now works for RLE4 and RLE8.
  - Fixed alignment of RLE4 in absolute mode.
  - Improved compression (smaller output).

  Michael Günnewig

Index: dlls/msvideo/msrle32/msrle32.c
===================================================================
RCS file: /home/wine/wine/dlls/msvideo/msrle32/msrle32.c,v
retrieving revision 1.4
diff -d -u -r1.4 msrle32.c
--- dlls/msvideo/msrle32/msrle32.c	13 Jun 2003 23:17:01 -0000	1.4
+++ dlls/msvideo/msrle32/msrle32.c	29 Jun 2003 17:32:06 -0000
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002 Michael Günnewig
+ * Copyright 2002-2003 Michael Günnewig
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,8 +17,7 @@
  */
 
 /* TODO:
- *   - compression of RLE4 is buggy -- see FIXME's
- *   - many improvements possible
+ *   - some improvements possible
  *   - implement DecompressSetPalette? -- does we need it for anything?
  */
 
@@ -297,10 +296,13 @@
     if (ColorCmp(clr1, clr3) <= lDist &&
 	ColorCmp(clr2, clr4) <= lDist) {
       /* diff at end? -- look-ahead for atleast ?? more encodable pixel */
-
-      /* FIXME */
-
-      return count;
+      if (pos + 2 < width && ColorCmp(clr1,lpB[pos+1]) <= lDist &&
+	  ColorCmp(clr2,lpB[pos+2]) <= lDist) {
+	if (pos + 4 < width && ColorCmp(lpB[pos+1],lpB[pos+3]) <= lDist &&
+	    ColorCmp(lpB[pos+2],lpB[pos+4]) <= lDist)
+	  return count - 3; /* followed by atleast 4 encodable pixels */
+	return count - 2;
+      }
     } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) {
       /* 'compare' with previous frame for end of diff */
       INT count2 = 0;
@@ -331,9 +333,11 @@
 
   for (count = 0; pos < width; pos++, count++) {
     if (ColorCmp(lpA[pos], lpB[pos]) <= lDist) {
-      /* diff at end? -- look-ahead for atleast one more encodable pixel */
-      if (pos + 1 < width && ColorCmp(lpA[pos], lpB[pos+1]) <= lDist)
-	return count;
+      /* diff at end? -- look-ahead for some more encodable pixel */
+      if (pos + 1 < width && ColorCmp(lpB[pos], lpB[pos+1]) <= lDist)
+	return count - 1;
+      if (pos + 2 < width && ColorCmp(lpB[pos+1], lpB[pos+2]) <= lDist)
+	return count - 1;
     } else if (lpP != NULL && ColorCmp(lpP[pos], lpB[pos]) <= lDist) {
       /* 'compare' with previous frame for end of diff */
       INT count2 = 0;
@@ -382,6 +386,8 @@
     /* add some pixel for absoluting if possible */
     count += countDiffRLE4(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth);
 
+    assert(count > 0);
+
     /* check for near end of line */
     if (x + count > lpbi->biWidth)
       count = lpbi->biWidth - x;
@@ -390,9 +396,11 @@
     while (count > 2) {
       INT  i;
       INT  size       = min(count, 254);
-      BOOL extra_byte = (size / 2) % 2 || (size % 2);
+      int  bytes      = ((size + 1) & (~1)) / 2;
+      BOOL extra_byte = bytes & 0x01;
 
-      *lpSizeImage += 2 + size/2 + (size % 2) + extra_byte;
+      *lpSizeImage += 2 + bytes + extra_byte;
+      assert(((*lpSizeImage) % 2) == 0);
       count -= size;
       *lpOut++ = 0;
       *lpOut++ = size;
@@ -468,6 +476,8 @@
     /* add some more pixels for absoluting if possible */
     count += countDiffRLE8(lpP, lpC - 1, lpC, pos-1, lDist, lpbi->biWidth);
 
+    assert(count > 0);
+
     /* check for over end of line */
     if (x + count > lpbi->biWidth)
       count = lpbi->biWidth - x;
@@ -663,6 +673,10 @@
 	assert(lpOut == lpOutStart + lpbiOut->biSizeImage);
       }
     }
+
+    /* add EOL -- will be changed to EOI */
+    lpbiOut->biSizeImage += 2;
+    *((LPWORD)lpOut)++ = 0;
   }
 
   /* change EOL to EOI -- end of image */
@@ -789,11 +803,14 @@
       if (jumpy == 0) {
 	/* add EOL -- end of line */
 	lpbiOut->biSizeImage += 2;
-	*lpOut++ = 0;
-	*lpOut++ = 0;
+	*((LPDWORD)lpOut)++ = 0;
 	assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
       }
     }
+
+    /* add EOL -- will be changed to EOI */
+    lpbiOut->biSizeImage += 2;
+    *((LPDWORD)lpOut)++ = 0;
   }
 
   /* change EOL to EOI -- end of image */
@@ -847,7 +864,7 @@
 	}
 	break;
       default: /* absolute mode */
-	extra_byte = (code1 / 2) & 0x01 || (code1 % 2);
+	extra_byte = (((code1 + 1) & (~1)) / 2) & 0x01;
 
 	if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth)
 	  return ICERR_ERROR;
@@ -1468,9 +1485,7 @@
 
     if (lpic->lpbiOutput->biBitCount == 4)
       MSRLE32_CompressRLE4(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput,
-		   lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, TRUE);
-    /*MSRLE32_CompressRLE4(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput,
-		   lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0);*/
+		   lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0);
     else
       MSRLE32_CompressRLE8(pi, lpic->lpbiInput, (LPBYTE)lpic->lpInput,
 		   lpic->lpbiOutput, (LPBYTE)lpic->lpOutput, (lpic->dwFlags & ICCOMPRESS_KEYFRAME) != 0);

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

  Powered by Linux