- 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.
This commit is contained in:
Michael Günnewig 2003-06-13 23:17:01 +00:00 committed by Alexandre Julliard
parent d1957c6092
commit da9e567992
2 changed files with 66 additions and 40 deletions

View File

@ -155,7 +155,7 @@ static BOOL isSupportedDIB(LPCBITMAPINFOHEADER lpbi)
/* check for size(s) */ /* check for size(s) */
if (!lpbi->biWidth || !lpbi->biHeight) if (!lpbi->biWidth || !lpbi->biHeight)
return FALSE; /* image with zero size, makes no sense so error ! */ 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 ! */ return FALSE; /* image too big ! */
/* check for non existing colortable for hi- and true-color DIB's */ /* check for non existing colortable for hi- and true-color DIB's */
@ -169,7 +169,7 @@ static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQ
{ {
INT diff = 0x00FFFFFF; INT diff = 0x00FFFFFF;
UINT i; UINT i;
UINT index = 0; UINT idx = 0;
/* pre-conditions */ /* pre-conditions */
assert(clrs != NULL); assert(clrs != NULL);
@ -182,14 +182,14 @@ static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQ
r = r*r + g*g + b*b; r = r*r + g*g + b*b;
if (r < diff) { if (r < diff) {
index = i; idx = i;
diff = r; diff = r;
if (diff == 0) if (diff == 0)
break; break;
} }
} }
return index; return idx;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -197,29 +197,31 @@ static BYTE MSRLE32_GetNearestPaletteIndex(UINT count, const RGBQUAD *clrs, RGBQ
void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBYTE lpIn) void computeInternalFrame(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, LPBYTE lpIn)
{ {
WORD wIntensityTbl[256]; WORD wIntensityTbl[256];
LONG lInLine, lOutLine; DWORD lInLine, lOutLine;
LPWORD lpOut; LPWORD lpOut;
int i, y; UINT i;
LONG y;
/* pre-conditions */ /* pre-conditions */
assert(pi != NULL && lpbiIn != NULL && lpIn != NULL); assert(pi != NULL && lpbiIn != NULL && lpIn != NULL);
assert(pi->pCurFrame != NULL); assert(pi->pCurFrame != NULL);
lInLine = DIBWIDTHBYTES(*lpbiIn); lInLine = DIBWIDTHBYTES(*lpbiIn);
lOutLine = WIDTHBYTES(lpbiIn->biWidth * 8*sizeof(WORD)) / 2; lOutLine = WIDTHBYTES((WORD)lpbiIn->biWidth * 8u * sizeof(WORD)) / 2u;
lpOut = pi->pCurFrame; lpOut = pi->pCurFrame;
assert(lpbiIn->biClrUsed != 0); 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++) for (i = 0; i < lpbiIn->biClrUsed; i++)
wIntensityTbl[i] = Intensity(lp[i]); wIntensityTbl[i] = Intensity(lp[i]);
} }
for (y = 0; y < lpbiIn->biHeight; y++) { for (y = 0; y < lpbiIn->biHeight; y++) {
int x; LONG x;
switch (lpbiIn->biBitCount) { switch (lpbiIn->biBitCount) {
case 1: case 1:
@ -388,9 +390,9 @@ static INT MSRLE32_CompressRLE4Line(CodecInfo *pi, LPWORD lpP, LPWORD lpC, LPCBI
while (count > 2) { while (count > 2) {
INT i; INT i;
INT size = min(count, 254); 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; count -= size;
*lpOut++ = 0; *lpOut++ = 0;
*lpOut++ = size; *lpOut++ = size;
@ -530,6 +532,7 @@ LRESULT MSRLE32_CompressRLE4(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
{ {
LPWORD lpC; LPWORD lpC;
LONG lLine, lInLine, lDist; LONG lLine, lInLine, lDist;
LPBYTE lpOutStart = lpOut;
/* pre-conditions */ /* pre-conditions */
assert(pi != NULL && lpbiOut != NULL); assert(pi != NULL && lpbiOut != NULL);
@ -560,6 +563,7 @@ LRESULT MSRLE32_CompressRLE4(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
/* add EOL -- end of line */ /* add EOL -- end of line */
lpbiOut->biSizeImage += 2; lpbiOut->biSizeImage += 2;
*((LPWORD)lpOut)++ = 0; *((LPWORD)lpOut)++ = 0;
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} }
} else { } else {
/* delta-frame -- compute delta between last and this internal frame */ /* delta-frame -- compute delta between last and this internal frame */
@ -656,14 +660,14 @@ LRESULT MSRLE32_CompressRLE4(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
/* add EOL -- end of line */ /* add EOL -- end of line */
lpbiOut->biSizeImage += 2; lpbiOut->biSizeImage += 2;
*((LPWORD)lpOut)++ = 0; *((LPWORD)lpOut)++ = 0;
assert(lpOut == lpOutStart + lpbiOut->biSizeImage);
} }
} }
} }
/* add EOI -- end of image */ /* change EOL to EOI -- end of image */
lpbiOut->biSizeImage += 2; lpOut[-1] = 1;
*lpOut++ = 0; assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
*lpOut++ = 1;
return ICERR_OK; return ICERR_OK;
} }
@ -672,6 +676,7 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
{ {
LPWORD lpC; LPWORD lpC;
LONG lDist, lInLine, lLine; LONG lDist, lInLine, lLine;
LPBYTE lpOutStart = lpOut;
assert(pi != NULL && lpbiOut != NULL); assert(pi != NULL && lpbiOut != NULL);
assert(lpIn != NULL && lpOut != NULL); assert(lpIn != NULL && lpOut != NULL);
@ -693,6 +698,7 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
do { do {
x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x, x = MSRLE32_CompressRLE8Line(pi, NULL, lpC, lpbiIn, lpIn, lDist, x,
&lpOut, &lpbiOut->biSizeImage); &lpOut, &lpbiOut->biSizeImage);
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} while (x < lpbiOut->biWidth); } while (x < lpbiOut->biWidth);
lpC += lLine; lpC += lLine;
@ -701,6 +707,7 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
/* add EOL -- end of line */ /* add EOL -- end of line */
lpbiOut->biSizeImage += 2; lpbiOut->biSizeImage += 2;
*((LPWORD)lpOut)++ = 0; *((LPWORD)lpOut)++ = 0;
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} }
} else { } else {
/* delta-frame -- compute delta between last and this internal frame */ /* delta-frame -- compute delta between last and this internal frame */
@ -745,6 +752,7 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
/* add EOL -- end of line */ /* add EOL -- end of line */
lpbiOut->biSizeImage += 2; lpbiOut->biSizeImage += 2;
*((LPWORD)lpOut)++ = 0; *((LPWORD)lpOut)++ = 0;
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} }
/* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */ /* FIXME: if (jumpy == 0 && could encode all) then jump too expensive */
@ -770,6 +778,7 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
/* skip the 'same' things corresponding to previous frame */ /* skip the 'same' things corresponding to previous frame */
x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x, x = MSRLE32_CompressRLE8Line(pi, lpP, lpC, lpbiIn, lpIn, lDist, x,
&lpOut, &lpbiOut->biSizeImage); &lpOut, &lpbiOut->biSizeImage);
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} }
} while (x < lpbiOut->biWidth); } while (x < lpbiOut->biWidth);
@ -782,14 +791,14 @@ LRESULT MSRLE32_CompressRLE8(CodecInfo *pi, LPBITMAPINFOHEADER lpbiIn, LPBYTE lp
lpbiOut->biSizeImage += 2; lpbiOut->biSizeImage += 2;
*lpOut++ = 0; *lpOut++ = 0;
*lpOut++ = 0; *lpOut++ = 0;
assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
} }
} }
} }
/* add EOI -- end of image */ /* change EOL to EOI -- end of image */
lpbiOut->biSizeImage += 2; lpOut[-1] = 1;
*lpOut++ = 0; assert(lpOut == (lpOutStart + lpbiOut->biSizeImage));
*lpOut++ = 1;
return ICERR_OK; return ICERR_OK;
} }
@ -838,7 +847,7 @@ static LRESULT MSRLE32_DecompressRLE4(CodecInfo *pi, LPCBITMAPINFOHEADER lpbi,
} }
break; break;
default: /* absolute mode */ default: /* absolute mode */
extra_byte = (code1 / 2) & 0x01; extra_byte = (code1 / 2) & 0x01 || (code1 % 2);
if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth) if (pixel_ptr/bytes_per_pixel + code1 > lpbi->biWidth)
return ICERR_ERROR; return ICERR_ERROR;
@ -848,14 +857,14 @@ static LRESULT MSRLE32_DecompressRLE4(CodecInfo *pi, LPCBITMAPINFOHEADER lpbi,
if (bytes_per_pixel == 1) { if (bytes_per_pixel == 1) {
code1 = lpIn[i]; code1 = lpIn[i];
lpOut[pixel_ptr++] = pi->palette_map[(code1 >> 4)]; 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)]; lpOut[pixel_ptr++] = pi->palette_map[(code1 & 0x0F)];
} else if (bytes_per_pixel == 2) { } else if (bytes_per_pixel == 2) {
code1 = lpIn[i] >> 4; code1 = lpIn[i] >> 4;
lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0]; lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1]; lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
if (2 * i <= code0) { if (2 * i + 1 <= code0) {
code1 = lpIn[i] & 0x0F; code1 = lpIn[i] & 0x0F;
lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0]; lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 0];
lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1]; lpOut[pixel_ptr++] = pi->palette_map[code1 * 2 + 1];
@ -867,7 +876,7 @@ static LRESULT MSRLE32_DecompressRLE4(CodecInfo *pi, LPCBITMAPINFOHEADER lpbi,
lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2]; lpOut[pixel_ptr + 2] = pi->palette_map[code1 * 4 + 2];
pixel_ptr += bytes_per_pixel; pixel_ptr += bytes_per_pixel;
if (2 * i <= code0) { if (2 * i + 1 <= code0) {
code1 = lpIn[i] & 0x0F; code1 = lpIn[i] & 0x0F;
lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0]; lpOut[pixel_ptr + 0] = pi->palette_map[code1 * 4 + 0];
lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1]; lpOut[pixel_ptr + 1] = pi->palette_map[code1 * 4 + 1];
@ -876,6 +885,23 @@ static LRESULT MSRLE32_DecompressRLE4(CodecInfo *pi, LPCBITMAPINFOHEADER lpbi,
} }
} }
} }
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; lpIn += code0 / 2;
/* if the RLE code is odd, skip a byte in the stream */ /* if the RLE code is odd, skip a byte in the stream */
@ -1240,11 +1266,11 @@ static LRESULT CompressGetFormat(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
size = 1<<lpbiIn->biBitCount; size = 1<<lpbiIn->biBitCount;
else else
size = lpbiIn->biClrUsed; size = lpbiIn->biClrUsed;
lpbiOut->biClrUsed = min(size, 1u << lpbiOut->biBitCount); lpbiOut->biClrUsed = min(size, 1 << lpbiOut->biBitCount);
lpbiOut->biClrImportant = 0; lpbiOut->biClrImportant = 0;
memcpy((LPBYTE)lpbiOut + lpbiOut->biSize, 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; return ICERR_OK;
} else } else
@ -1319,10 +1345,10 @@ static LRESULT CompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
LPCBITMAPINFOHEADER lpbiOut) LPCBITMAPINFOHEADER lpbiOut)
{ {
RGBQUAD *rgbIn; const RGBQUAD *rgbIn;
RGBQUAD *rgbOut; const RGBQUAD *rgbOut;
int i; UINT i;
size_t size; size_t size;
TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
@ -1336,7 +1362,7 @@ static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK) if (CompressQuery(pi, lpbiIn, lpbiOut) != ICERR_OK)
return ICERR_BADFORMAT; return ICERR_BADFORMAT;
/* FIXME: cannot compress and decompress at a time! */ /* FIXME: cannot compress and decompress at same time! */
if (pi->bDecompress) { if (pi->bDecompress) {
FIXME("cannot compress and decompress at same time!\n"); FIXME("cannot compress and decompress at same time!\n");
return ICERR_ERROR; return ICERR_ERROR;
@ -1357,8 +1383,8 @@ static LRESULT CompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
pi->nPrevFrame = -1; pi->nPrevFrame = -1;
pi->bCompress = TRUE; pi->bCompress = TRUE;
rgbIn = (RGBQUAD*)((LPBYTE)lpbiIn + lpbiIn->biSize); rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
rgbOut = (RGBQUAD*)((LPBYTE)lpbiOut + lpbiOut->biSize); rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
switch (lpbiOut->biBitCount) { switch (lpbiOut->biBitCount) {
case 4: case 4:
@ -1583,9 +1609,9 @@ static LRESULT DecompressQuery(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn, static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
LPCBITMAPINFOHEADER lpbiOut) LPCBITMAPINFOHEADER lpbiOut)
{ {
RGBQUAD *rgbIn; const RGBQUAD *rgbIn;
RGBQUAD *rgbOut; const RGBQUAD *rgbOut;
int i; UINT i;
TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut); TRACE("(%p,%p,%p)\n",pi,lpbiIn,lpbiOut);
@ -1607,8 +1633,8 @@ static LRESULT DecompressBegin(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
if (pi->bDecompress) if (pi->bDecompress)
DecompressEnd(pi); DecompressEnd(pi);
rgbIn = (RGBQUAD*)((LPBYTE)lpbiIn + lpbiIn->biSize); rgbIn = (const RGBQUAD*)((const BYTE*)lpbiIn + lpbiIn->biSize);
rgbOut = (RGBQUAD*)((LPBYTE)lpbiOut + lpbiOut->biSize); rgbOut = (const RGBQUAD*)((const BYTE*)lpbiOut + lpbiOut->biSize);
switch (lpbiOut->biBitCount) { switch (lpbiOut->biBitCount) {
case 4: case 4:
@ -1732,7 +1758,7 @@ static LRESULT DecompressGetPalette(CodecInfo *pi, LPCBITMAPINFOHEADER lpbiIn,
lpbiOut->biClrUsed = size; 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 ! */ } /* else could never occur ! */
return ICERR_OK; return ICERR_OK;

View File

@ -36,7 +36,7 @@
#define FOURCC_RLE8 mmioFOURCC('R','L','E','8') #define FOURCC_RLE8 mmioFOURCC('R','L','E','8')
#define FOURCC_MRLE mmioFOURCC('M','R','L','E') #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) #define DIBWIDTHBYTES(bi) WIDTHBYTES((WORD)(bi).biWidth * (WORD)(bi).biBitCount)
typedef struct _CodecInfo { typedef struct _CodecInfo {