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 {