home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Microsoft Multimedia Jumpstart 1.1a
/
CD_ROM.BIN
/
develpmt
/
source
/
rleapp
/
rle.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-12
|
6KB
|
248 lines
/*--------------------------------------------------------------------------*\
| RLE.C - RLE Delta frame code |
| |
\*--------------------------------------------------------------------------*/
/*
(C) Copyright Microsoft Corp. 1991, 1992. All rights reserved.
You have a royalty-free right to use, modify, reproduce and
distribute the Sample Files (and/or any modified version) in
any way you find useful, provided that you agree that
Microsoft has no warranty obligations or liability for any
Sample Application Files which are modified.
If you did not get this from Microsoft Sources, then it may not be the
most current version. This sample code in particular will be updated
and include more documentation.
Sources are:
The MM Sys BBS: The phone number is 206 936-4082.
CompuServe: WINSDK forum, MDK section.
*/
#include <windows.h>
#include "gmem.h"
#include "dib.h"
#include "rle.h"
extern WORD PASCAL __WinFlags;
#define WinFlags (WORD)(&__WinFlags)
#define RLE_ESCAPE 0
#define RLE_EOL 0
#define RLE_EOF 1
#define RLE_JMP 2
#define RLE_RUN 3
typedef BYTE huge * HPRLE;
typedef BYTE far * LPRLE;
/*----------------------------------------------------------------------------*\
* MEM.ASM
\*----------------------------------------------------------------------------*/
extern LPVOID FAR PASCAL MemCopy(LPVOID dest, LPVOID source, LONG count);
extern LPVOID FAR PASCAL MemFill(LPVOID dest, LONG count, BYTE b);
extern long FAR PASCAL muldiv32(long,long,long);
void FAR PASCAL DecodeRle386(LPBITMAPINFOHEADER lpbi, LPBYTE pb, LPBYTE prle);
void NEAR PASCAL DecodeRle286(LPBITMAPINFOHEADER lpbi, HPRLE pb, HPRLE prle);
//
// RleDeltaFrame
//
// Calculate the RLE bits to go from one dib to another
//
// hdibPrev - Previous DIB
// hdib - DIB to RLE
//
// returns
//
// handle to a RLE DIB
//
HANDLE FAR PASCAL RleDeltaFrame(HANDLE hrle, HANDLE hdibPrev, HANDLE hdib, int iStart, int iLen, int minJump)
{
LPBITMAPINFOHEADER lpbi;
BOOL fAlloc;
LPBYTE pbPrev;
LPBYTE pbDib;
LPBYTE pbRle;
int biHeight;
WORD cbJump=0;
int dy;
if (!hdib)
return NULL;
if (minJump == 0)
minJump = 4;
//
// Get info on the source and dest dibs
//
lpbi = GLock(hdib);
biHeight = (int)lpbi->biHeight;
if (iLen <= 0)
iLen = biHeight;
iLen = min(biHeight-iStart, iLen);
//
// Hey! we only work with 8bpp DIBs if we get otherwise barf.
//
if (lpbi->biBitCount != 8 || lpbi->biCompression != BI_RGB)
return NULL;
//
// create an RLE buffer to place the RLE bits in
//
if (fAlloc = !hrle)
{
hrle = CreateDib(8, (int)lpbi->biWidth, (int)lpbi->biHeight*2);
if (!hrle)
return NULL;
//
// copy over the color table from the DIB to the empty RLE
//
MemCopy(GLock(hrle),GLock(hdib),(int)lpbi->biSize+(int)lpbi->biClrUsed*sizeof(RGBQUAD));
}
//
// lock all the buffers, and start the delta framin'
//
lpbi = GLock(hrle);
pbRle = DibPtr(hrle);
pbDib = DibLock(hdib,0,iStart);
if (hdibPrev)
pbPrev = DibLock(hdibPrev,0,iStart);
else
pbPrev = NULL;
while(iStart > 0)
{
dy = min(iStart,255);
*pbRle++ = RLE_ESCAPE;
*pbRle++ = RLE_JMP;
*pbRle++ = 0;
*pbRle++ = (BYTE)dy;
iStart -= dy;
cbJump += 4;
}
lpbi->biHeight = iLen;
DeltaFrame386(lpbi, pbPrev, pbDib, pbRle, minJump);
lpbi->biHeight = biHeight;
lpbi->biSizeImage += cbJump; // adjust size to include JUMP!
//
// hey we are done! Unlock the buffers and get out
//
if (fAlloc)
hrle = GReAlloc(hrle,lpbi->biSize+lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage);
return hrle;
}
//
// PlayRleDib
//
// Play back a RLE buffer into a DIB
//
// hdib - dest DIB
// x,y - position in dest DIB where to place RLE
// hrle - src RLE
//
// returns
//
// none
//
void PlayRleDib(HANDLE hdib, int x, int y, HANDLE hrle)
{
LPBITMAPINFOHEADER lpbi;
lpbi = GLock(hdib);
if (WinFlags & WF_CPU286)
DecodeRle286(lpbi, DibXY(lpbi,x,y), DibPtr(hrle));
else
DecodeRle386(lpbi, DibXY(lpbi,x,y), DibPtr(hrle));
}
//
// DecodeRle286
//
// Play back a RLE buffer into a DIB buffer
//
// returns
//
// none
//
void NEAR PASCAL DecodeRle286(LPBITMAPINFOHEADER lpbi, HPRLE pb, HPRLE prle)
{
BYTE cnt;
BYTE b;
WORD x;
WORD dx,dy;
WORD wWidthBytes;
wWidthBytes = (WORD)lpbi->biWidth+3 & ~3;
x = 0;
for(;;)
{
cnt = *prle++;
b = *prle++;
if (cnt == RLE_ESCAPE)
{
switch (b)
{
case RLE_EOF:
return;
case RLE_EOL:
pb += wWidthBytes - x;
x = 0;
break;
case RLE_JMP:
dx = (WORD)*prle++;
dy = (WORD)*prle++;
pb += (DWORD)wWidthBytes * dy + dx;
x += dx;
break;
default:
cnt = b;
x += cnt;
while (cnt-- > 0)
*pb++ = *prle++;
if (b & 1)
prle++;
break;
}
}
else
{
x += cnt;
while (cnt-- > 0)
*pb++ = b;
}
}
}