• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**********************************************************************
2  * File:        bitstrm.c  (Formerly bits.c)
3  * Description: Bitstream read/write class member functions.
4  * Author:					Ray Smith
5  * Created:					Tue Feb 19 10:59:44 GMT 1991
6  *
7  * (C) Copyright 1991, Hewlett-Packard Ltd.
8  ** Licensed under the Apache License, Version 2.0 (the "License");
9  ** you may not use this file except in compliance with the License.
10  ** You may obtain a copy of the License at
11  ** http://www.apache.org/licenses/LICENSE-2.0
12  ** Unless required by applicable law or agreed to in writing, software
13  ** distributed under the License is distributed on an "AS IS" BASIS,
14  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  ** See the License for the specific language governing permissions and
16  ** limitations under the License.
17  *
18  **********************************************************************/
19 
20 #include          "mfcpch.h"     //precompiled headers
21 #ifdef __MSW32__
22 #include          <io.h>
23 #else
24 #include          <unistd.h>
25 #endif
26 #include          "fileerr.h"
27 #include          "bitstrm.h"
28 
29 const uinT16
30 R_BITSTREAM::bitmasks[17] = {
31   0, 1, 3, 7, 15, 31, 63, 127, 255,
32   511, 1023, 2047, 4095, 8191, 16383, 32767, 65535
33 };
34 
35 /**********************************************************************
36  * R_BITSTREAM::open
37  *
38  * Establish a bitstream for reading.
39  **********************************************************************/
40 
open(int fd)41 uinT16 R_BITSTREAM::open(        //open for read
42                          int fd  //file to read
43                         ) {
44   bitfd = fd;
45   bufsize = read (fd, (char *) bitbuf, BITBUFSIZE * sizeof (uinT8));
46   //fill buffer
47   if (bufsize < 0) {
48     READFAILED.error ("R_BITSTREAM::open", TESSLOG, NULL);
49     return 0;
50   }
51   bitword = bitbuf[0] | (bitbuf[1] << 8);
52   bitindex = 2;
53   bitbit = 16;
54   return (uinT16) bitword;
55 }
56 
57 
58 /**********************************************************************
59  * R_BITSTREAM::read_code
60  *
61  * Remove a code from the bitstream.
62  **********************************************************************/
63 
read_code(uinT8 length)64 uinT16 R_BITSTREAM::read_code(              //take code out
65                               uinT8 length  //length of code
66                              ) {
67   bitbit -= length;              //no of bits left
68   bitword >>= length;            //remove bits
69   while (bitbit < 16) {
70                                  //get next byte
71     bitword |= bitbuf[bitindex++] << bitbit;
72     bitbit += 8;
73     if (bitindex >= bufsize) {
74       bufsize =
75         read (bitfd, (char *) bitbuf, BITBUFSIZE * sizeof (uinT8));
76       if (bufsize < 0) {
77         READFAILED.error ("R_BITSTREAM::read_code", TESSLOG, NULL);
78         return 0;
79       }
80       bitindex = 0;              //newly filled buffer
81     }
82   }
83   return (uinT16) bitword;
84 }
85 
86 
87 /**********************************************************************
88  * R_BITSTREAM::masks
89  *
90  * Read a code from the static member.
91  **********************************************************************/
92 
masks(inT32 index)93 uinT16 R_BITSTREAM::masks(             //take code out
94                           inT32 index  //length of code
95                          ) {
96   return bitmasks[index];
97 }
98 
99 
100 /**********************************************************************
101  * W_BITSTREAM::open
102  *
103  * Establish a bitstream for writing.
104  **********************************************************************/
105 
open(int fd)106 void W_BITSTREAM::open(        //open for write
107                        int fd  //file to write
108                       ) {
109   bitfd = fd;
110   bitindex = 0;
111   bitword = 0;
112   bitbit = 0;
113 }
114 
115 
116 /**********************************************************************
117  * W_BITSTREAM::write_code
118  *
119  * Add a code to the bitstream.
120  **********************************************************************/
121 
write_code(uinT16 code,uinT8 length)122 inT8 W_BITSTREAM::write_code(              //take code out
123                              uinT16 code,  //code to add
124                              uinT8 length  //length of code
125                             ) {
126   if (length == 0) {
127                                  //flushing
128     if (bitbit > 0)
129                                  //get last byte
130       bitbuf[bitindex++] = (uinT8) bitword;
131     if ((bitindex > 0) &&
132       (write (bitfd, (char *) bitbuf, bitindex * sizeof (uinT8)) !=
133     (inT32) (bitindex * sizeof (uinT8)))) {
134       WRITEFAILED.error ("W_BITSTREAM::write_code", TESSLOG, "Flushing");
135       return -1;
136     }
137   }
138   else {
139     bitword |= code << bitbit;   //add new code
140     bitbit += length;
141     while (bitbit >= 8) {
142                                  //get next byte
143       bitbuf[bitindex++] = (uinT8) bitword;
144       bitbit -= 8;
145       bitword >>= 8;
146       if (bitindex >= BITBUFSIZE) {
147         if (write (bitfd, (char *) bitbuf, bitindex * sizeof (uinT8))
148         != (inT32) (bitindex * sizeof (uinT8))) {
149           WRITEFAILED.error ("W_BITSTREAM::write_code", TESSLOG, NULL);
150           return -1;
151         }
152         bitindex = 0;            //newly filled buffer
153       }
154     }
155   }
156   return 0;                      //success
157 }
158