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);