]> git.sur5r.net Git - glabels/blob - glabels2/qrencode-3.1.0/bitstream.c
36a8ee6e2b1e06999db1d40a63ebfcbf10c922d1
[glabels] / glabels2 / qrencode-3.1.0 / bitstream.c
1 /*
2  * qrencode - QR Code encoder
3  *
4  * Binary sequence class.
5  * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #include "bitstream.h"
27
28 BitStream *BitStream_new(void)
29 {
30         BitStream *bstream;
31
32         bstream = (BitStream *)malloc(sizeof(BitStream));
33         if(bstream == NULL) return NULL;
34
35         bstream->length = 0;
36         bstream->data = NULL;
37
38         return bstream;
39 }
40
41 static int BitStream_allocate(BitStream *bstream, int length)
42 {
43         unsigned char *data;
44
45         if(bstream == NULL) {
46                 return -1;
47         }
48
49         data = (unsigned char *)malloc(length);
50         if(data == NULL) {
51                 return -1;
52         }
53
54         if(bstream->data) {
55                 free(bstream->data);
56         }
57         bstream->length = length;
58         bstream->data = data;
59
60         return 0;
61 }
62
63 static BitStream *BitStream_newFromNum(int bits, unsigned int num)
64 {
65         unsigned int mask;
66         int i;
67         unsigned char *p;
68         BitStream *bstream;
69
70         bstream = BitStream_new();
71         if(bstream == NULL) return NULL;
72
73         if(BitStream_allocate(bstream, bits)) {
74                 BitStream_free(bstream);
75                 return NULL;
76         }
77
78         p = bstream->data;
79         mask = 1 << (bits - 1);
80         for(i=0; i<bits; i++) {
81                 if(num & mask) {
82                         *p = 1;
83                 } else {
84                         *p = 0;
85                 }
86                 p++;
87                 mask = mask >> 1;
88         }
89
90         return bstream;
91 }
92
93 static BitStream *BitStream_newFromBytes(int size, unsigned char *data)
94 {
95         unsigned char mask;
96         int i, j;
97         unsigned char *p;
98         BitStream *bstream;
99
100         bstream = BitStream_new();
101         if(bstream == NULL) return NULL;
102
103         if(BitStream_allocate(bstream, size * 8)) {
104                 BitStream_free(bstream);
105                 return NULL;
106         }
107
108         p = bstream->data;
109         for(i=0; i<size; i++) {
110                 mask = 0x80;
111                 for(j=0; j<8; j++) {
112                         if(data[i] & mask) {
113                                 *p = 1;
114                         } else {
115                                 *p = 0;
116                         }
117                         p++;
118                         mask = mask >> 1;
119                 }
120         }
121
122         return bstream;
123 }
124
125 int BitStream_append(BitStream *bstream, BitStream *arg)
126 {
127         unsigned char *data;
128
129         if(arg == NULL) {
130                 return -1;
131         }
132         if(arg->length == 0) {
133                 return 0;
134         }
135         if(bstream->length == 0) {
136                 if(BitStream_allocate(bstream, arg->length)) {
137                         return -1;
138                 }
139                 memcpy(bstream->data, arg->data, arg->length);
140                 return 0;
141         }
142
143         data = (unsigned char *)malloc(bstream->length + arg->length);
144         if(data == NULL) {
145                 return -1;
146         }
147         memcpy(data, bstream->data, bstream->length);
148         memcpy(data + bstream->length, arg->data, arg->length);
149
150         free(bstream->data);
151         bstream->length += arg->length;
152         bstream->data = data;
153
154         return 0;
155 }
156
157 int BitStream_appendNum(BitStream *bstream, int bits, unsigned int num)
158 {
159         BitStream *b;
160         int ret;
161
162         if(bits == 0) return 0;
163
164         b = BitStream_newFromNum(bits, num);
165         if(b == NULL) return -1;
166
167         ret = BitStream_append(bstream, b);
168         BitStream_free(b);
169
170         return ret;
171 }
172
173 int BitStream_appendBytes(BitStream *bstream, int size, unsigned char *data)
174 {
175         BitStream *b;
176         int ret;
177
178         if(size == 0) return 0;
179
180         b = BitStream_newFromBytes(size, data);
181         if(b == NULL) return -1;
182
183         ret = BitStream_append(bstream, b);
184         BitStream_free(b);
185
186         return ret;
187 }
188
189 unsigned char *BitStream_toByte(BitStream *bstream)
190 {
191         int i, j, size, bytes;
192         unsigned char *data, v;
193         unsigned char *p;
194
195         size = BitStream_size(bstream);
196         if(size == 0) {
197                 return NULL;
198         }
199         data = (unsigned char *)malloc((size + 7) / 8);
200         if(data == NULL) {
201                 return NULL;
202         }
203
204         bytes = size  / 8;
205
206         p = bstream->data;
207         for(i=0; i<bytes; i++) {
208                 v = 0;
209                 for(j=0; j<8; j++) {
210                         v = v << 1;
211                         v |= *p;
212                         p++;
213                 }
214                 data[i] = v;
215         }
216         if(size & 7) {
217                 v = 0;
218                 for(j=0; j<(size & 7); j++) {
219                         v = v << 1;
220                         v |= *p;
221                         p++;
222                 }
223                 data[bytes] = v;
224         }
225
226         return data;
227 }
228
229 void BitStream_free(BitStream *bstream)
230 {
231         if(bstream != NULL) {
232                 free(bstream->data);
233                 free(bstream);
234         }
235 }