3 implementation of bitio.h.
5 Copyright (C) 2003 Matthias Kramm <kramm@quiss.org>
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program 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
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
27 #include "../config.h"
31 #define ZLIB_BUFFER_SIZE 16384
35 /* ---------------------------- null reader ------------------------------- */
37 static int reader_nullread(struct reader_t
*r
, void* data
, int len
)
42 static void reader_nullread_dealloc(struct reader_t
*r
)
44 memset(r
, 0, sizeof(struct reader_t
));
46 void reader_init_nullreader(struct reader_t
*r
)
48 r
->read
= reader_nullread
;
49 r
->dealloc
= reader_nullread_dealloc
;
51 r
->type
= READER_TYPE_NULL
;
56 /* ---------------------------- file reader ------------------------------- */
58 static int reader_fileread(struct reader_t
*reader
, void* data
, int len
)
60 int ret
= read((int)reader
->internal
, data
, len
);
65 void reader_init_filereader(struct reader_t
*r
, int handle
)
67 r
->read
= reader_fileread
;
68 r
->internal
= (void*)handle
;
69 r
->type
= READER_TYPE_FILE
;
75 /* ---------------------------- mem reader ------------------------------- */
82 static int reader_memread(struct reader_t
*reader
, void* data
, int len
)
84 struct memread_t
*mr
= (struct memread_t
*)reader
->internal
;
86 if(mr
->length
- reader
->pos
> len
) {
87 memcpy(data
, &mr
->data
[reader
->pos
], len
);
91 memcpy(data
, &mr
->data
[reader
->pos
], mr
->length
- reader
->pos
);
92 reader
->pos
= mr
->length
;
93 return mr
->length
- reader
->pos
;
96 static void reader_memread_dealloc(struct reader_t
*reader
)
99 free(reader
->internal
);
100 memset(reader
, 0, sizeof(struct reader_t
));
102 void reader_init_memreader(struct reader_t
*r
, void*newdata
, int newlength
)
104 struct memread_t
*mr
= malloc(sizeof(struct memread_t
));
106 mr
->length
= newlength
;
107 r
->read
= reader_memread
;
108 r
->dealloc
= reader_memread_dealloc
;
109 r
->internal
= (void*)mr
;
110 r
->type
= READER_TYPE_MEM
;
116 /* ---------------------------- mem writer ------------------------------- */
124 static int writer_memwrite_write(struct writer_t
*w
, void* data
, int len
)
126 struct memwrite_t
*mw
= (struct memwrite_t
*)w
->internal
;
127 if(mw
->length
- w
->pos
> len
) {
128 memcpy(&mw
->data
[w
->pos
], data
, len
);
132 memcpy(&mw
->data
[w
->pos
], data
, mw
->length
- w
->pos
);
134 return mw
->length
- w
->pos
;
137 static void writer_memwrite_finish(struct writer_t
*w
)
143 void writer_init_memwriter(struct writer_t
*w
, void*data
, int len
)
145 struct memwrite_t
*mr
;
146 mr
= malloc(sizeof(struct memwrite_t
));
149 memset(w
, 0, sizeof(struct writer_t
));
150 w
->write
= writer_memwrite_write
;
151 w
->finish
= writer_memwrite_finish
;
152 w
->internal
= (void*)mr
;
153 w
->type
= WRITER_TYPE_MEM
;
159 /* ------------------------- growing mem writer ------------------------------- */
161 struct growmemwrite_t
166 static int writer_growmemwrite_write(struct writer_t
*w
, void* data
, int len
)
168 struct growmemwrite_t
*mw
= (struct growmemwrite_t
*)w
->internal
;
170 fprintf(stderr
, "Illegal write operation: data already given away");
173 if(mw
->length
- w
->pos
<= len
) {
174 unsigned char*newmem
;
175 int newlength
= mw
->length
;
176 while(newlength
- w
->pos
< len
) {
179 newmem
= malloc(newlength
);
180 memcpy(newmem
, mw
->data
, mw
->length
);
183 mw
->length
= newlength
;
185 memcpy(&mw
->data
[w
->pos
], data
, len
);
189 static void writer_growmemwrite_finish(struct writer_t
*w
)
191 struct growmemwrite_t
*mw
= (struct growmemwrite_t
*)w
->internal
;
196 free(w
->internal
);mw
=0;
197 memset(w
, 0, sizeof(struct writer_t
));
199 void* writer_growmemwrite_getmem(struct writer_t
*w
)
201 struct growmemwrite_t
*mw
= (struct growmemwrite_t
*)w
->internal
;
203 /* remove own reference so that neither write() nor finish() can free it.
204 It's property of the caller now.
209 void writer_init_growingmemwriter(struct writer_t
*w
)
211 struct memwrite_t
*mr
;
212 mr
= malloc(sizeof(struct memwrite_t
));
214 mr
->data
= malloc(mr
->length
);
215 memset(w
, 0, sizeof(struct writer_t
));
216 w
->write
= writer_growmemwrite_write
;
217 w
->finish
= writer_growmemwrite_finish
;
218 w
->internal
= (void*)mr
;
219 w
->type
= WRITER_TYPE_GROWING_MEM
;
225 /* ---------------------------- file writer ------------------------------- */
233 static int writer_filewrite_write(struct writer_t
*w
, void* data
, int len
)
235 struct filewrite_t
* fw
= (struct filewrite_t
*)w
->internal
;
236 return write(fw
->handle
, data
, len
);
238 static void writer_filewrite_finish(struct writer_t
*w
)
240 struct filewrite_t
*mr
= (struct filewrite_t
*)w
->internal
;
244 memset(w
, 0, sizeof(struct writer_t
));
246 void writer_init_filewriter(struct writer_t
*w
, int handle
)
248 struct filewrite_t
*mr
= malloc(sizeof(struct filewrite_t
));
251 memset(w
, 0, sizeof(struct writer_t
));
252 w
->write
= writer_filewrite_write
;
253 w
->finish
= writer_filewrite_finish
;
255 w
->type
= WRITER_TYPE_FILE
;
260 void writer_init_filewriter2(struct writer_t
*w
, char*filename
)
262 int fi
= open("movie.swf",
266 O_WRONLY
|O_CREAT
|O_TRUNC
, 0644);
267 writer_init_filewriter(w
, fi
);
268 ((struct filewrite_t
*)w
->internal
)->free_handle
= 1;
271 /* ---------------------------- null writer ------------------------------- */
273 static int writer_nullwrite_write(struct writer_t
*w
, void* data
, int len
)
278 static void writer_nullwrite_finish(struct writer_t
*w
)
280 memset(w
, 0, sizeof(struct writer_t
));
282 void writer_init_nullwriter(struct writer_t
*w
)
284 memset(w
, 0, sizeof(struct writer_t
));
285 w
->write
= writer_nullwrite_write
;
286 w
->finish
= writer_nullwrite_finish
;
288 w
->type
= WRITER_TYPE_NULL
;
293 /* ---------------------------- zlibinflate reader -------------------------- */
299 struct reader_t
*input
;
300 unsigned char readbuffer
[ZLIB_BUFFER_SIZE
];
305 static void zlib_error(int ret
, char* msg
, z_stream
*zs
)
307 fprintf(stderr
, "%s: zlib error (%d): last zlib error: %s\n",
310 zs
->msg
?zs
->msg
:"unknown");
316 static int reader_zlibinflate(struct reader_t
*reader
, void* data
, int len
)
319 struct zlibinflate_t
*z
= (struct zlibinflate_t
*)reader
->internal
;
327 z
->zs
.next_out
= data
;
328 z
->zs
.avail_out
= len
;
331 if(!z
->zs
.avail_in
) {
332 z
->zs
.avail_in
= z
->input
->read(z
->input
, z
->readbuffer
, ZLIB_BUFFER_SIZE
);
333 z
->zs
.next_in
= z
->readbuffer
;
336 ret
= inflate(&z
->zs
, Z_NO_FLUSH
);
338 ret
= inflate(&z
->zs
, Z_FINISH
);
341 ret
!= Z_STREAM_END
) zlib_error(ret
, "bitio:inflate_inflate", &z
->zs
);
343 if (ret
== Z_STREAM_END
) {
344 int pos
= z
->zs
.next_out
- (Bytef
*)data
;
345 ret
= inflateEnd(&z
->zs
);
346 if (ret
!= Z_OK
) zlib_error(ret
, "bitio:inflate_end", &z
->zs
);
347 free(reader
->internal
);
348 reader
->internal
= 0;
352 if(!z
->zs
.avail_out
) {
359 fprintf(stderr
, "Error: swftools was compiled without zlib support");
363 static void reader_zlibinflate_dealloc(struct reader_t
*reader
)
366 struct zlibinflate_t
*z
= (struct zlibinflate_t
*)reader
->internal
;
367 /* test whether read() already did basic deallocation */
368 if(reader
->internal
) {
370 free(reader
->internal
);
372 memset(reader
, 0, sizeof(struct reader_t
));
375 void reader_init_zlibinflate(struct reader_t
*r
, struct reader_t
*input
)
378 struct zlibinflate_t
*z
;
380 memset(r
, 0, sizeof(struct reader_t
));
381 z
= (struct zlibinflate_t
*)malloc(sizeof(struct zlibinflate_t
));
382 memset(z
, 0, sizeof(struct zlibinflate_t
));
384 r
->read
= reader_zlibinflate
;
385 r
->dealloc
= reader_zlibinflate_dealloc
;
386 r
->type
= READER_TYPE_ZLIB
;
389 memset(&z
->zs
,0,sizeof(z_stream
));
390 z
->zs
.zalloc
= Z_NULL
;
391 z
->zs
.zfree
= Z_NULL
;
392 z
->zs
.opaque
= Z_NULL
;
393 ret
= inflateInit(&z
->zs
);
394 if (ret
!= Z_OK
) zlib_error(ret
, "bitio:inflate_init", &z
->zs
);
397 fprintf(stderr
, "Error: swftools was compiled without zlib support");
401 /* ---------------------------- zlibdeflate writer -------------------------- */
407 struct writer_t
*output
;
408 unsigned char writebuffer
[ZLIB_BUFFER_SIZE
];
412 static int writer_zlibdeflate_write(struct writer_t
*writer
, void* data
, int len
)
415 struct zlibdeflate_t
*z
= (struct zlibdeflate_t
*)writer
->internal
;
417 if(writer
->type
!= WRITER_TYPE_ZLIB
) {
418 fprintf(stderr
, "Wrong writer ID (writer not initialized?)\n");
422 fprintf(stderr
, "zlib not initialized!\n");
428 z
->zs
.next_in
= data
;
429 z
->zs
.avail_in
= len
;
432 ret
= deflate(&z
->zs
, Z_NO_FLUSH
);
434 if (ret
!= Z_OK
) zlib_error(ret
, "bitio:deflate_deflate", &z
->zs
);
436 if(z
->zs
.next_out
!= z
->writebuffer
) {
437 z
->output
->write(z
->output
, z
->writebuffer
, z
->zs
.next_out
- (Bytef
*)z
->writebuffer
);
438 z
->zs
.next_out
= z
->writebuffer
;
439 z
->zs
.avail_out
= ZLIB_BUFFER_SIZE
;
442 if(!z
->zs
.avail_in
) {
449 fprintf(stderr
, "Error: swftools was compiled without zlib support");
453 static void writer_zlibdeflate_finish(struct writer_t
*writer
)
456 struct zlibdeflate_t
*z
= (struct zlibdeflate_t
*)writer
->internal
;
457 struct writer_t
*output
;
459 if(writer
->type
!= WRITER_TYPE_ZLIB
) {
460 fprintf(stderr
, "Wrong writer ID (writer not initialized?)\n");
467 ret
= deflate(&z
->zs
, Z_FINISH
);
469 ret
!= Z_STREAM_END
) zlib_error(ret
, "bitio:deflate_finish", &z
->zs
);
471 if(z
->zs
.next_out
!= z
->writebuffer
) {
472 z
->output
->write(z
->output
, z
->writebuffer
, z
->zs
.next_out
- (Bytef
*)z
->writebuffer
);
473 z
->zs
.next_out
= z
->writebuffer
;
474 z
->zs
.avail_out
= ZLIB_BUFFER_SIZE
;
477 if (ret
== Z_STREAM_END
) {
482 ret
= deflateEnd(&z
->zs
);
483 if (ret
!= Z_OK
) zlib_error(ret
, "bitio:deflate_end", &z
->zs
);
484 free(writer
->internal
);
485 memset(writer
, 0, sizeof(struct writer_t
));
486 //output->finish(output);
488 fprintf(stderr
, "Error: swftools was compiled without zlib support");
492 void writer_init_zlibdeflate(struct writer_t
*w
, struct writer_t
*output
)
495 struct zlibdeflate_t
*z
;
497 memset(w
, 0, sizeof(struct writer_t
));
498 z
= (struct zlibdeflate_t
*)malloc(sizeof(struct zlibdeflate_t
));
499 memset(z
, 0, sizeof(struct zlibdeflate_t
));
501 w
->write
= writer_zlibdeflate_write
;
502 w
->finish
= writer_zlibdeflate_finish
;
503 w
->type
= WRITER_TYPE_ZLIB
;
506 memset(&z
->zs
,0,sizeof(z_stream
));
507 z
->zs
.zalloc
= Z_NULL
;
508 z
->zs
.zfree
= Z_NULL
;
509 z
->zs
.opaque
= Z_NULL
;
510 ret
= deflateInit(&z
->zs
, 9);
511 if (ret
!= Z_OK
) zlib_error(ret
, "bitio:deflate_init", &z
->zs
);
514 z
->zs
.next_out
= z
->writebuffer
;
515 z
->zs
.avail_out
= ZLIB_BUFFER_SIZE
;
517 fprintf(stderr
, "Error: swftools was compiled without zlib support");
522 /* ----------------------- bit handling routines -------------------------- */
524 void writer_writebit(struct writer_t
*w
, int bit
)
528 w
->write(w
, &w
->mybyte
, 1);
533 w
->mybyte
|= 1 << (7 - w
->bitpos
);
536 void writer_writebits(struct writer_t
*w
, unsigned int data
, int bits
)
541 writer_writebit(w
, (data
>> (bits
-t
-1))&1);
544 void writer_resetbits(struct writer_t
*w
)
547 w
->write(w
, &w
->mybyte
, 1);
552 unsigned int reader_readbit(struct reader_t
*r
)
557 r
->read(r
, &r
->mybyte
, 1);
559 return (r
->mybyte
>>(7-r
->bitpos
++))&1;
561 unsigned int reader_readbits(struct reader_t
*r
, int num
)
568 val
|=reader_readbit(r
);
572 void reader_resetbits(struct reader_t
*r
)