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