home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
NETWORK
/
netpbm_src.lzh
/
NETPBM
/
PPM
/
bitio.c
< prev
next >
Wrap
Text File
|
1996-11-18
|
4KB
|
209 lines
/*\
* $Id: bitio.c,v 1.5 1992/11/24 19:36:46 dws Exp dws $
*
* bitio.c - bitstream I/O
*
* Works for (sizeof(unsigned long)-1)*8 bits.
*
* Copyright (C) 1992 by David W. Sanderson.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. This software is provided "as is"
* without express or implied warranty.
*
* $Log: bitio.c,v $
* Revision 1.5 1992/11/24 19:36:46 dws
* Added copyright.
*
* Revision 1.4 1992/11/17 03:37:50 dws
* updated comment
*
* Revision 1.3 1992/11/10 23:15:16 dws
* Removed superfluous code.
*
* Revision 1.2 1992/11/10 23:11:22 dws
* Generalized to handle more than one bitstream at once.
*
* Revision 1.1 1992/11/10 18:33:21 dws
* Initial revision
*
\*/
#include "bitio.h"
struct bitstream
{
FILE *
f; /* bytestream */
unsigned long
bitbuf; /* bit buffer */
int
nbitbuf; /* number of bits in 'bitbuf' */
char
mode;
};
#define Mask(n) ((1<<(n))-1)
#define BitPut(b,ul,n) ((b)->bitbuf = (((b)->bitbuf<<(n)) \
|((ul)&Mask(n))), \
(b)->nbitbuf += (n))
#define BitGet(b,n) (((b)->bitbuf>>((b)->nbitbuf-=(n))) & Mask(n))
/*
* pm_bitinit() - allocate and return a struct bitstream * for the
* given FILE*.
*
* mode must be one of "r" or "w", according to whether you will be
* reading from or writing to the struct bitstream *.
*
* Returns 0 on error.
*/
struct bitstream *
pm_bitinit(f, mode)
FILE *f;
char *mode;
{
struct bitstream *ans = (struct bitstream *)0;
if(!f || !mode || !*mode)
return ans;
if(strcmp(mode, "r") && strcmp(mode, "w"))
return ans;
ans = (struct bitstream *)calloc(1, sizeof(struct bitstream));
if(ans)
{
ans->f = f;
ans->mode = *mode;
}
return ans;
}
/*
* pm_bitfini() - deallocate the given struct bitstream *.
*
* You must call this after you are done with the struct bitstream *.
*
* It may flush some bits left in the buffer.
*
* Returns the number of bytes written, -1 on error.
*/
int
pm_bitfini(b)
struct bitstream *b;
{
int nbyte = 0;
if(!b)
return -1;
/* flush the output */
if(b->mode == 'w')
{
/* flush the bits */
if (b->nbitbuf < 0 || b->nbitbuf >= 8)
{
/* pm_bitwrite() didn't work */
return -1;
}
/*
* If we get to here, nbitbuf is 0..7
*/
if(b->nbitbuf)
{
char c;
BitPut(b, 0, (long)8-(b->nbitbuf));
c = (char) BitGet(b, (long)8);
if(putc(c, b->f) == EOF)
{
return -1;
}
nbyte++;
}
}
free(b);
return nbyte;
}
/*
* pm_bitread() - read the next nbits into *val from the given file.
*
* The last pm_bitread() must be followed by a call to pm_bitfini().
*
* Returns the number of bytes read, -1 on error.
*/
int
pm_bitread(b, nbits, val)
struct bitstream *b;
unsigned long nbits;
unsigned long *val;
{
int nbyte = 0;
int c;
if(!b)
return -1;
while (b->nbitbuf < nbits)
{
if((c = getc(b->f)) == EOF)
{
return -1;
}
nbyte++;
BitPut(b, c, (long) 8);
}
*val = BitGet(b, nbits);
return nbyte;
}
/*
* pm_bitwrite() - write the low nbits of val to the given file.
*
* The last pm_bitwrite() must be followed by a call to pm_bitfini().
*
* Returns the number of bytes written, -1 on error.
*/
int
pm_bitwrite(b, nbits, val)
struct bitstream *b;
unsigned long nbits;
unsigned long val;
{
int nbyte = 0;
char c;
if(!b)
return -1;
BitPut(b, val, nbits);
while (b->nbitbuf >= 8)
{
c = (char) BitGet(b, (long)8);
if(putc(c, b->f) == EOF)
{
return -1;
}
nbyte++;
}
return nbyte;
}