Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/pnmimage/pnmbitio.cxx

Go to the documentation of this file.
00001 /*
00002  * bitio.c - bitstream I/O
00003  *
00004  * Works for (sizeof(unsigned long)-1)*8 bits.
00005  *
00006  * Copyright (C) 1992 by David W. Sanderson.
00007  * 
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation for any purpose and without fee is hereby granted,
00010  * provided that the above copyright notice appear in all copies and
00011  * that both that copyright notice and this permission notice appear
00012  * in supporting documentation.  This software is provided "as is"
00013  * without express or implied warranty.
00014  */
00015 
00016 #include "pnmbitio.h"
00017 #include <assert.h>
00018 struct bitstream
00019 {
00020         istream *inf;
00021         ostream *outf;
00022         unsigned long
00023                 bitbuf;         /* bit buffer */
00024         int
00025                 nbitbuf;        /* number of bits in 'bitbuf' */
00026         char
00027                 mode;
00028 };
00029 
00030 #define Mask(n)         ((1<<(n))-1)
00031 
00032 #define BitPut(b,ul,n)  ((b)->bitbuf = (((b)->bitbuf<<(n))      \
00033                                         |((ul)&Mask(n))),       \
00034                         (b)->nbitbuf += (n))
00035 
00036 #define BitGet(b,n)     (((b)->bitbuf>>((b)->nbitbuf-=(n))) & Mask(n))
00037 
00038 /*
00039  * pm_bitinit() - allocate and return a struct bitstream * for the
00040  * given FILE*.
00041  *
00042  * mode must be one of "r" or "w", according to whether you will be
00043  * reading from or writing to the struct bitstream *.
00044  *
00045  * Returns 0 on error.
00046  */
00047 
00048 EXPCL_PANDA struct bitstream *
00049 pm_bitinit(istream *f, char *mode)
00050 {
00051         struct bitstream *ans = (struct bitstream *)0;
00052 
00053         if(!f || !mode || !*mode)
00054                 return ans;
00055         if(strcmp(mode, "r"))
00056                 return ans;
00057 
00058         ans = (struct bitstream *)calloc(1, sizeof(struct bitstream));
00059         if(ans)
00060         {
00061                 ans->inf = f;
00062                 ans->mode = *mode;
00063         }
00064 
00065         return ans;
00066 }
00067 
00068 EXPCL_PANDA struct bitstream *
00069 pm_bitinit(ostream *f, char *mode)
00070 {
00071         struct bitstream *ans = (struct bitstream *)0;
00072 
00073         if(!f || !mode || !*mode)
00074                 return ans;
00075         if(strcmp(mode, "w"))
00076                 return ans;
00077 
00078         ans = (struct bitstream *)calloc(1, sizeof(struct bitstream));
00079         if(ans)
00080         {
00081                 ans->outf = f;
00082                 ans->mode = *mode;
00083         }
00084 
00085         return ans;
00086 }
00087 
00088 /*
00089  * pm_bitfini() - deallocate the given struct bitstream *.
00090  *
00091  * You must call this after you are done with the struct bitstream *.
00092  * 
00093  * It may flush some bits left in the buffer.
00094  *
00095  * Returns the number of bytes written, -1 on error.
00096  */
00097 
00098 EXPCL_PANDA int
00099 pm_bitfini(struct bitstream *b)
00100 {
00101         int             nbyte = 0;
00102 
00103         if(!b)
00104                 return -1;
00105 
00106         /* flush the output */
00107         if(b->mode == 'w')
00108         {
00109                 /* flush the bits */
00110                 if (b->nbitbuf < 0 || b->nbitbuf >= 8)
00111                 {
00112                         /* pm_bitwrite() didn't work */
00113                         return -1;
00114                 }
00115 
00116                 /*
00117                  * If we get to here, nbitbuf is 0..7
00118                  */
00119                 if(b->nbitbuf)
00120                 {
00121                         char    c;
00122 
00123                         BitPut(b, 0, (long)8-(b->nbitbuf));
00124                         c = (char) BitGet(b, (long)8);
00125                         if(!b->outf->put(c))
00126                         {
00127                                 return -1;
00128                         }
00129                         nbyte++;
00130                 }
00131         }
00132 
00133         free(b);
00134         return nbyte;
00135 }
00136 
00137 /*
00138  * pm_bitread() - read the next nbits into *val from the given file.
00139  * 
00140  * The last pm_bitread() must be followed by a call to pm_bitfini().
00141  * 
00142  * Returns the number of bytes read, -1 on error.
00143  */
00144 
00145 EXPCL_PANDA int
00146 pm_bitread(struct bitstream *b, unsigned long nbits, unsigned long *val)
00147 {
00148         int             nbyte = 0;
00149         int             c;
00150 
00151         if(!b)
00152                 return -1;
00153 
00154         #ifdef _DEBUG
00155           assert(((signed long)nbits) > 0);
00156         #endif
00157         
00158         while (b->nbitbuf < (signed long)nbits)
00159         {
00160                 if((c = b->inf->get()) == EOF)
00161                 {
00162                         return -1;
00163                 }
00164                 nbyte++;
00165 
00166                 BitPut(b, c, (long) 8);
00167         }
00168 
00169         *val = BitGet(b, nbits);
00170         return nbyte;
00171 }
00172 
00173 /*
00174  * pm_bitwrite() - write the low nbits of val to the given file.
00175  * 
00176  * The last pm_bitwrite() must be followed by a call to pm_bitfini().
00177  * 
00178  * Returns the number of bytes written, -1 on error.
00179  */
00180 
00181 EXPCL_PANDA int
00182 pm_bitwrite(struct bitstream *b, unsigned long nbits, unsigned long val)
00183 {
00184         int             nbyte = 0;
00185         char            c;
00186 
00187         if(!b)
00188                 return -1;
00189 
00190         BitPut(b, val, nbits);
00191 
00192         while (b->nbitbuf >= 8)
00193         {
00194                 c = (char) BitGet(b, (long)8);
00195 
00196                 if(!b->outf->put(c))
00197                 {
00198                         return -1;
00199                 }
00200                 nbyte++;
00201         }
00202 
00203         return nbyte;
00204 }

Generated on Fri May 2 00:43:05 2003 for Panda by doxygen1.3