home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Der Mediaplex Sampler - Die 6 von Plex
/
6_v_plex.zip
/
6_v_plex
/
DISK5
/
WIN_12
/
IDEPIX2.ZIP
/
TIFFACS.ZIP
/
PACKBITS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-06-23
|
5KB
|
243 lines
/*-------------------------------------------------------
T I F F A C S : Unterstⁿtzungsroutinen fⁿr TIFF-Dateien
Ursprⁿnglich von Aldus, von mir auf dem
Walnut-Creek - Source-Code-ROM gefunden.
Der ursprⁿngliche Source ist TIFF 4.0 und
auch ansonsten ein ziemlicher Mⁿll.
Diese Version hat Funktionsprototypen und
ein paar Fehler weniger, aber im Grunde ist
sie auch ein ziemlicher Mⁿll.
Im Mircosoft System Journal 4/93 ist eine ganz
brauchbare TIF-Routine dabei, aber eben nicht PD
Bernd Herd
Rudolf Virchow Str. 8
6842 Bⁿrstadt
06206/79222
P A C K B I T S : Kompression im PackBits-Format
-------------------------------------------------------------*/
#include <windows.h>
#pragma hdrstop
#include <string.h>
#include "tiff.h"
#include "tiffi.h"
#define MAXINBYTES 127
#define INITIAL 0
#define LITERAL 1
#define UNDECIDED 2
char CalcRaw (WORD n, LPSTR lpIn, char *rawrunbuf)
{
char ncounts = 0;
char thisbyte;
char cnt = 1;
char runbyte = *lpIn++;
while (--n) {
thisbyte = *lpIn++;
if (thisbyte == runbyte) {
cnt++;
} else { /* write prev raw run, & start a new one */
*rawrunbuf++ = cnt;
ncounts++;
cnt = 1;
runbyte = thisbyte;
}
}
*rawrunbuf = cnt;
return (++ncounts);
}
/* this should be a Mac ToolBox lookalike
* n must be <= 127
*/
void near _pascal static PackBits (LPSTR *plpIn, LPSTR *plpOut, WORD n)
{
LPSTR lpIn = *plpIn;
LPSTR lpOut = *plpOut;
char runcount;
char rawrunbuf[MAXINBYTES];
char *pRaw;
char nraw;
char state;
char rawcount;
char twins;
// BOOL success = FALSE;
#ifdef n
if (n <= 0 || n > 127) {
DBMSG(("PackBits: n=%u\n", n));
err = IE_BUG;
goto cu0;
}
#endif
/* calculate raw run counts
*/
nraw = CalcRaw (n, lpIn, rawrunbuf);
#ifdef n
if (nraw <= 0 || nraw > 127) {
DBMSG(("PackBits: nraw=%u\n",nraw));
err = IE_BUG;
goto cu0;
}
#endif
/* initialize a few things
*/
pRaw = rawrunbuf;
state = INITIAL;
/* go through the raw run count array
*/
while (nraw--) {
rawcount = *pRaw++;
#ifdef nein
if (rawcount < 1 || rawcount > 127) {
DBMSG(("PackBits: rawcount=%d\n",rawcount));
err = IE_BUG;
goto cu0;
}
#endif
if (state == INITIAL) {
if (rawcount == 1) {
state = LITERAL;
runcount = 1;
} else if (rawcount == 2) {
state = UNDECIDED;
runcount = 2;
} else { /* rawcount >= 3 */
/* state = INITIAL; */
/* write replicate run and update ptrs
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} else if (state == LITERAL) {
if (rawcount < 3) {
runcount += rawcount;
} else {
state = INITIAL;
/* write literal run and update ptrs
*/
*lpOut++ = runcount - 1;
#ifdef NEIN
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
#endif
memcpy (lpOut, lpIn, runcount);
lpOut += runcount;
lpIn += runcount;
/* write replicate run and update ptrs
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} else { /* state = UNDECIDED */
if (rawcount == 1) {
state = LITERAL;
runcount++;
} else if (rawcount == 2) {
/* state = UNDECIDED */
runcount += 2;
} else { /* rawcount >= 3 */
state = INITIAL;
#ifdef NEIN
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
#endif
/* write out runcount/2 twin replicate runs */
for (twins = (runcount>>1); twins--; ) {
*lpOut++ = -1;
*lpOut++ = *lpIn;
lpIn += 2;
}
/* write out this replicate run
*/
*lpOut++ = -(rawcount - 1);
*lpOut++ = *lpIn;
lpIn += rawcount;
}
} /* end of UNDECIDED case */
} /* end of main for loop */
/* clean up hanging states
*/
if (state == LITERAL) {
#ifdef NEIN
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
#endif
/* write out literal run
*/
*lpOut++ = runcount - 1;
memcpy (lpOut, lpIn, runcount);
lpOut += runcount;
lpIn += runcount;
}
else if (state == UNDECIDED) {
#ifdef NEIN
if (runcount < 1 || runcount > 127) {
DBMSG(("PackBits: runcount=%d\n",runcount));
goto cu0;
}
#endif
/* write out runcount/2 twin replicate runs
*/
for (twins = (runcount>>1); twins--; ) {
*lpOut++ = -1;
*lpOut++ = *lpIn;
lpIn += 2;
}
}
/* set up return values
*/
*plpIn = lpIn;
*plpOut = lpOut;
cu0: return;
} /* that's all, folks */
/* if you might have more than 127 input bytes, call this routine instead
* of the basic PackBits
*/
void BigPackBits (LPSTR *plpIn, LPSTR *plpOut, unsigned n)
{
WORD topack;
while (n) {
topack = (n < MAXINBYTES) ? n : MAXINBYTES;
PackBits (plpIn, plpOut, topack);
n -= topack;
}
}