00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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;
00024 int
00025 nbitbuf;
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
00040
00041
00042
00043
00044
00045
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
00090
00091
00092
00093
00094
00095
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
00107 if(b->mode == 'w')
00108 {
00109
00110 if (b->nbitbuf < 0 || b->nbitbuf >= 8)
00111 {
00112
00113 return -1;
00114 }
00115
00116
00117
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
00139
00140
00141
00142
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
00175
00176
00177
00178
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 }