1 #if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
2 typedef int Py_ssize_t;
3 #define PY_SSIZE_T_MAX INT_MAX
4 #define PY_SSIZE_T_MIN INT_MIN
5 #endif
6
7 /********************************************************
8 Audio Tools, a module and set of tools for manipulating audio data
9 Copyright (C) 2007-2014 Brian Langenberger
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 *******************************************************/
25
26 #if PY_MAJOR_VERSION >= 3
27 #define IS_PY3K
28 #endif
29
30 PyObject*
31 bitstream_format_size(PyObject *dummy, PyObject *args);
32
33 PyObject*
34 bitstream_format_byte_size(PyObject *dummy, PyObject *args);
35
36 PyObject*
37 bitstream_parse_func(PyObject *dummy, PyObject *args);
38
39 PyObject*
40 bitstream_build_func(PyObject *dummy, PyObject *args);
41
42 PyMethodDef module_methods[] = {
43 {"format_size", (PyCFunction)bitstream_format_size,
44 METH_VARARGS, "Calculate size of format string in bits"}, /*FIXME*/
45 {"format_byte_size", (PyCFunction)bitstream_format_byte_size,
46 METH_VARARGS, "Calculate size of format string in bytes"},
47 {"parse", (PyCFunction)bitstream_parse_func,
48 METH_VARARGS, "parse(format, is_little_endian, data) -> [values]"},
49 {"build", (PyCFunction)bitstream_build_func,
50 METH_VARARGS, "build(format, is_little_endian, [values]) -> data"},
51 {NULL}
52 };
53
54 /*the BitstreamReader object
55 a simple wrapper around our Bitstream reading struct*/
56
57 typedef struct {
58 PyObject_HEAD
59
60 BitstreamReader* bitstream;
61 } bitstream_BitstreamReader;
62
63 static PyObject*
64 brpy_read_unsigned(BitstreamReader *br, unsigned bits);
65
66 static PyObject*
67 brpy_read_signed(BitstreamReader *br, unsigned bits);
68
69 /*reads byte_count bytes from reader to buffer
70 returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
71 int
72 brpy_read_bytes_chunk(BitstreamReader *reader,
73 unsigned byte_count,
74 struct bs_buffer *buffer);
75
76 /*sets "minimum" to the smaller value of x or y
77 returns the smaller object on success, or NULL with PyErr set
78 if some comparison or conversion error occurs
79
80 the reference count of either is *not* incremented*/
81 PyObject*
82 brpy_read_bytes_min(PyObject *x, PyObject *y, long *minimum);
83
84 /*given a byte count as a Python object (presumably numeric)
85 returns a Python string of bytes read or NULL on error*/
86 static PyObject*
87 brpy_read_bytes_obj(BitstreamReader *reader, PyObject *byte_count);
88
89 /*skips byte_count bytes from reader
90 returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
91 int
92 brpy_skip_bytes_chunk(BitstreamReader *reader,
93 unsigned byte_count);
94
95 /*given a byte count as a Python object (presumably numeric)
96 returns 0 on success, 1 if a read error occurs with PyErr set accordingly*/
97 int
98 brpy_skip_bytes_obj(BitstreamReader *reader, PyObject *byte_count);
99
100 /*given a byte count, returns a Python string of bytes read
101 or NULL on error*/
102 static PyObject*
103 brpy_read_bytes(BitstreamReader *reader, unsigned byte_count);
104
105 static PyObject*
106 BitstreamReader_read(bitstream_BitstreamReader *self, PyObject *args);
107
108 static PyObject*
109 BitstreamReader_byte_align(bitstream_BitstreamReader *self, PyObject *args);
110
111 static PyObject*
112 BitstreamReader_byte_aligned(bitstream_BitstreamReader *self, PyObject *args);
113
114 static PyObject*
115 BitstreamReader_skip(bitstream_BitstreamReader *self, PyObject *args);
116
117 static PyObject*
118 BitstreamReader_skip_bytes(bitstream_BitstreamReader *self, PyObject *args);
119
120 static PyObject*
121 BitstreamReader_unread(bitstream_BitstreamReader *self, PyObject *args);
122
123 static PyObject*
124 BitstreamReader_read_signed(bitstream_BitstreamReader *self, PyObject *args);
125
126 static PyObject*
127 BitstreamReader_unary(bitstream_BitstreamReader *self, PyObject *args);
128
129 static PyObject*
130 BitstreamReader_skip_unary(bitstream_BitstreamReader *self, PyObject *args);
131
132 static PyObject*
133 BitstreamReader_read_huffman_code(bitstream_BitstreamReader *self,
134 PyObject *args);
135
136 static PyObject*
137 BitstreamReader_read_bytes(bitstream_BitstreamReader *self,
138 PyObject *args);
139
140 static PyObject*
141 BitstreamReader_set_endianness(bitstream_BitstreamReader *self, PyObject *args);
142
143 static PyObject*
144 BitstreamReader_close(bitstream_BitstreamReader *self, PyObject *args);
145
146 static PyObject*
147 BitstreamReader_getpos(bitstream_BitstreamReader *self, PyObject *args);
148
149 static PyObject*
150 BitstreamReader_setpos(bitstream_BitstreamReader *self, PyObject *args);
151
152 static PyObject*
153 BitstreamReader_seek(bitstream_BitstreamReader *self, PyObject *args);
154
155 static PyObject*
156 BitstreamReader_add_callback(bitstream_BitstreamReader *self, PyObject *args);
157
158 static PyObject*
159 BitstreamReader_pop_callback(bitstream_BitstreamReader *self, PyObject *args);
160
161 static PyObject*
162 BitstreamReader_call_callbacks(bitstream_BitstreamReader *self, PyObject *args);
163
164 static PyObject*
165 BitstreamReader_substream(bitstream_BitstreamReader *self, PyObject *args);
166
167 static PyObject*
168 BitstreamReader_parse(bitstream_BitstreamReader *self, PyObject *args);
169
170 int
171 BitstreamReader_init(bitstream_BitstreamReader *self, PyObject *args);
172
173 static PyObject*
174 BitstreamReader_enter(bitstream_BitstreamReader *self, PyObject *args);
175
176 static PyObject*
177 BitstreamReader_exit(bitstream_BitstreamReader *self, PyObject *args);
178
179 PyMethodDef BitstreamReader_methods[] = {
180 {"read", (PyCFunction)BitstreamReader_read, METH_VARARGS,
181 "read(bits) -> unsigned int"},
182 {"skip", (PyCFunction)BitstreamReader_skip, METH_VARARGS,
183 "skip(bits)\n"
184 "skips over the given number of bits"},
185 {"skip_bytes", (PyCFunction)BitstreamReader_skip_bytes, METH_VARARGS,
186 "skip_bytes(bytes)\n"
187 "skips over the given number of bytes"},
188 {"byte_align", (PyCFunction)BitstreamReader_byte_align, METH_NOARGS,
189 "byte_align()\n"
190 "moves to the next whole byte boundary, if necessary"},
191 {"byte_aligned", (PyCFunction)BitstreamReader_byte_aligned, METH_NOARGS,
192 "byte_aligned() -> True if the stream is currently byte-aligned"},
193 {"unread", (PyCFunction)BitstreamReader_unread, METH_VARARGS,
194 "unread(bit)\n"
195 "pushes a single bit back into the stream"},
196 {"read_signed", (PyCFunction)BitstreamReader_read_signed, METH_VARARGS,
197 "read_signed(bits) -> signed int"},
198 {"unary", (PyCFunction)BitstreamReader_unary, METH_VARARGS,
199 "unary(stop_bit) -> unsigned int\n"
200 "counts the number of bits until the next stop bit"},
201 {"skip_unary", (PyCFunction)BitstreamReader_skip_unary, METH_VARARGS,
202 "skip_unary(stop_bit)\n"
203 "skips a number of bits until the next stop bit"},
204 {"read_huffman_code", (PyCFunction)BitstreamReader_read_huffman_code,
205 METH_VARARGS,
206 "read_huffman_code(huffman_tree) -> int\n"
207 "given a compiled HuffmanTree, returns the next code from the stream"},
208 {"read_bytes", (PyCFunction)BitstreamReader_read_bytes, METH_VARARGS,
209 "read_bytes(bytes) -> string"},
210 {"set_endianness", (PyCFunction)BitstreamReader_set_endianness,
211 METH_VARARGS,
212 "set_endianness(endianness)\n"
213 "where 0 = big endian, 1 = little-endian\n"
214 "the stream is automatically byte-aligned"},
215 {"parse", (PyCFunction)BitstreamReader_parse, METH_VARARGS,
216 "parse(format_string) -> [value1, value2, ...]\n"
217 "where \"format_string\" maps to the calls:\n"
218 "\"#u\" -> read(#)\n"
219 "\"#s\" -> read_signed(#)\n"
220 "\"#p\" -> skip(#)\n"
221 "\"#P\" -> skip_bytes(#)\n"
222 "\"#b\" -> read_bytes(#)\n"
223 "\"a\" -> byte_align()\n\n"
224 "for instance:\n"
225 "r.parse(\"3u 4s 36u\") == [r.read(3), r.read_signed(4), r.read(36)]"},
226 {"close", (PyCFunction)BitstreamReader_close, METH_NOARGS,
227 "close()\n"
228 "closes the stream and any underlying file object"},
229 {"getpos", (PyCFunction)BitstreamReader_getpos, METH_NOARGS,
230 "getpos() -> position"},
231 {"setpos", (PyCFunction)BitstreamReader_setpos, METH_VARARGS,
232 "setpos(position)"},
233 {"seek", (PyCFunction)BitstreamReader_seek, METH_VARARGS,
234 "seek(position, whence)\n"
235 "positions the stream at the given position where\n"
236 "position is stream position in bytes and\n"
237 "whence 0 = stream start, 1 = current position, 2 = stream end\n"
238 "no callbacks are performed on intervening bytes"},
239 {"add_callback", (PyCFunction)BitstreamReader_add_callback, METH_VARARGS,
240 "add_callback(function)\n"
241 "where \"function\" takes a single byte as an argument\n"
242 "and is called upon each read byte from the stream"},
243 {"pop_callback", (PyCFunction)BitstreamReader_pop_callback, METH_NOARGS,
244 "pop_callback() -> function\n"
245 "removes and returns the most recently added callback"},
246 {"call_callbacks", (PyCFunction)BitstreamReader_call_callbacks,
247 METH_VARARGS,
248 "call_callbacks(byte)\n"
249 "calls the attached callbacks as if the byte had been read"},
250 {"substream", (PyCFunction)BitstreamReader_substream, METH_VARARGS,
251 "substream(bytes) -> BitstreamReader\n"
252 "returns a sub-reader containing the given number of input bytes"},
253 {"__enter__", (PyCFunction)BitstreamReader_enter,
254 METH_NOARGS, "enter() -> self"},
255 {"__exit__", (PyCFunction)BitstreamReader_exit,
256 METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
257 {NULL}
258 };
259
260 void
261 BitstreamReader_dealloc(bitstream_BitstreamReader *self);
262
263 static PyObject*
264 BitstreamReader_new(PyTypeObject *type, PyObject *args,
265 PyObject *kwds);
266
267 void
268 BitstreamReader_callback(uint8_t byte, PyObject *callback);
269
270 PyTypeObject bitstream_BitstreamReaderType = {
271 PyVarObject_HEAD_INIT(NULL, 0)
272 "bitstream.BitstreamReader", /*tp_name*/
273 sizeof(bitstream_BitstreamReader), /*tp_basicsize*/
274 0, /*tp_itemsize*/
275 (destructor)BitstreamReader_dealloc, /*tp_dealloc*/
276 0, /*tp_print*/
277 0, /*tp_getattr*/
278 0, /*tp_setattr*/
279 0, /*tp_compare*/
280 0, /*tp_repr*/
281 0, /*tp_as_number*/
282 0, /*tp_as_sequence*/
283 0, /*tp_as_mapping*/
284 0, /*tp_hash */
285 0, /*tp_call*/
286 0, /*tp_str*/
287 0, /*tp_getattro*/
288 0, /*tp_setattro*/
289 0, /*tp_as_buffer*/
290 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
291 "BitstreamReader(file, endianness)", /* tp_doc */
292 0, /* tp_traverse */
293 0, /* tp_clear */
294 0, /* tp_richcompare */
295 0, /* tp_weaklistoffset */
296 0, /* tp_iter */
297 0, /* tp_iternext */
298 BitstreamReader_methods, /* tp_methods */
299 0, /* tp_members */
300 0, /* tp_getset */
301 0, /* tp_base */
302 0, /* tp_dict */
303 0, /* tp_descr_get */
304 0, /* tp_descr_set */
305 0, /* tp_dictoffset */
306 (initproc)BitstreamReader_init,/* tp_init */
307 0, /* tp_alloc */
308 BitstreamReader_new, /* tp_new */
309 };
310
311
312 typedef struct {
313 PyObject_HEAD
314
315 br_huffman_table_t* br_table;
316 bw_huffman_table_t* bw_table;
317 } bitstream_HuffmanTree;
318
319 static PyObject*
320 HuffmanTree_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
321
322 int
323 HuffmanTree_init(bitstream_HuffmanTree *self, PyObject *args);
324
325 void
326 HuffmanTree_dealloc(bitstream_HuffmanTree *self);
327
328
329 PyTypeObject bitstream_HuffmanTreeType = {
330 PyVarObject_HEAD_INIT(NULL, 0)
331 "bitstream.HuffmanTree", /*tp_name*/
332 sizeof(bitstream_HuffmanTree), /*tp_basicsize*/
333 0, /*tp_itemsize*/
334 (destructor)HuffmanTree_dealloc, /*tp_dealloc*/
335 0, /*tp_print*/
336 0, /*tp_getattr*/
337 0, /*tp_setattr*/
338 0, /*tp_compare*/
339 0, /*tp_repr*/
340 0, /*tp_as_number*/
341 0, /*tp_as_sequence*/
342 0, /*tp_as_mapping*/
343 0, /*tp_hash */
344 0, /*tp_call*/
345 0, /*tp_str*/
346 0, /*tp_getattro*/
347 0, /*tp_setattro*/
348 0, /*tp_as_buffer*/
349 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
350 "Huffman Tree objects", /* tp_doc */
351 0, /* tp_traverse */
352 0, /* tp_clear */
353 0, /* tp_richcompare */
354 0, /* tp_weaklistoffset */
355 0, /* tp_iter */
356 0, /* tp_iternext */
357 0, /* tp_methods */
358 0, /* tp_members */
359 0, /* tp_getset */
360 0, /* tp_base */
361 0, /* tp_dict */
362 0, /* tp_descr_get */
363 0, /* tp_descr_set */
364 0, /* tp_dictoffset */
365 (initproc)HuffmanTree_init, /* tp_init */
366 0, /* tp_alloc */
367 HuffmanTree_new, /* tp_new */
368 };
369
370 /*BitstreamReaderPosition is an opaque container for positions
371 returned by BitstreamReader.getpos()
372 it has no methods or attributes and can't even be instantiated directly*/
373 typedef struct {
374 PyObject_HEAD
375
376 br_pos_t *pos;
377 } bitstream_BitstreamReaderPosition;
378
379 static PyObject*
380 BitstreamReaderPosition_new(PyTypeObject *type, PyObject *args,
381 PyObject *kwds);
382
383 int
384 BitstreamReaderPosition_init(bitstream_BitstreamReaderPosition *self,
385 PyObject *args);
386
387 void
388 BitstreamReaderPosition_dealloc(bitstream_BitstreamReaderPosition *self);
389
390 PyTypeObject bitstream_BitstreamReaderPositionType = {
391 PyVarObject_HEAD_INIT(NULL, 0)
392 "bitstream.BitstreamReaderPosition", /*tp_name*/
393 sizeof(bitstream_BitstreamReaderPosition), /*tp_basicsize*/
394 0, /*tp_itemsize*/
395 (destructor)BitstreamReaderPosition_dealloc, /*tp_dealloc*/
396 0, /*tp_print*/
397 0, /*tp_getattr*/
398 0, /*tp_setattr*/
399 0, /*tp_compare*/
400 0, /*tp_repr*/
401 0, /*tp_as_number*/
402 0, /*tp_as_sequence*/
403 0, /*tp_as_mapping*/
404 0, /*tp_hash */
405 0, /*tp_call*/
406 0, /*tp_str*/
407 0, /*tp_getattro*/
408 0, /*tp_setattro*/
409 0, /*tp_as_buffer*/
410 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
411 "BitstreamReaderPosition", /* tp_doc */
412 0, /* tp_traverse */
413 0, /* tp_clear */
414 0, /* tp_richcompare */
415 0, /* tp_weaklistoffset */
416 0, /* tp_iter */
417 0, /* tp_iternext */
418 0, /* tp_methods */
419 0, /* tp_members */
420 0, /* tp_getset */
421 0, /* tp_base */
422 0, /* tp_dict */
423 0, /* tp_descr_get */
424 0, /* tp_descr_set */
425 0, /* tp_dictoffset */
426 (initproc)BitstreamReaderPosition_init, /* tp_init */
427 0, /* tp_alloc */
428 BitstreamReaderPosition_new, /* tp_new */
429 };
430
431 PyObject*
bitstream_format_size(PyObject * dummy,PyObject * args)432 bitstream_format_size(PyObject *dummy, PyObject *args)
433 {
434 char* format_string;
435
436 if (!PyArg_ParseTuple(args, "s", &format_string))
437 return NULL;
438
439 return Py_BuildValue("I", bs_format_size(format_string));
440 }
441
442 PyObject*
bitstream_format_byte_size(PyObject * dummy,PyObject * args)443 bitstream_format_byte_size(PyObject *dummy, PyObject *args)
444 {
445 char* format_string;
446
447 if (!PyArg_ParseTuple(args, "s", &format_string))
448 return NULL;
449
450 return Py_BuildValue("I", bs_format_byte_size(format_string));
451 }
452
453 typedef struct {
454 PyObject_HEAD
455
456 BitstreamWriter* bitstream;
457 } bitstream_BitstreamWriter;
458
459 static PyObject*
460 bwpy_min_unsigned(unsigned bits);
461
462 static PyObject*
463 bwpy_max_unsigned(unsigned bits);
464
465 static PyObject*
466 bwpy_min_signed(unsigned bits);
467
468 static PyObject*
469 bwpy_max_signed(unsigned bits);
470
471 static int
472 bwpy_in_range(PyObject *min_value, PyObject *value, PyObject *max_value);
473
474 static int
475 bw_validate_unsigned_range(unsigned bits, PyObject *value);
476
477 static int
478 bw_validate_signed_range(unsigned bits, PyObject *value);
479
480 static int
481 bwpy_write_unsigned(BitstreamWriter *bw, unsigned bits, PyObject *value);
482
483 static int
484 bwpy_write_signed(BitstreamWriter *bw, unsigned bits, PyObject *value);
485
486 static PyObject*
487 BitstreamWriter_write(bitstream_BitstreamWriter *self, PyObject *args);
488
489 static PyObject*
490 BitstreamWriter_write_signed(bitstream_BitstreamWriter *self, PyObject *args);
491
492 static PyObject*
493 BitstreamWriter_unary(bitstream_BitstreamWriter *self, PyObject *args);
494
495 static PyObject*
496 BitstreamWriter_write_huffman_code(bitstream_BitstreamWriter *self,
497 PyObject *args);
498
499 static PyObject*
500 BitstreamWriter_byte_align(bitstream_BitstreamWriter *self, PyObject *args);
501
502 static PyObject*
503 BitstreamWriter_byte_aligned(bitstream_BitstreamWriter *self, PyObject *args);
504
505 static PyObject*
506 BitstreamWriter_set_endianness(bitstream_BitstreamWriter *self,
507 PyObject *args);
508
509 static PyObject*
510 BitstreamWriter_write_bytes(bitstream_BitstreamWriter *self,
511 PyObject *args);
512
513 static PyObject*
514 BitstreamWriter_add_callback(bitstream_BitstreamWriter *self,
515 PyObject *args);
516
517 static PyObject*
518 BitstreamWriter_pop_callback(bitstream_BitstreamWriter *self,
519 PyObject *args);
520
521 static PyObject*
522 BitstreamWriter_call_callbacks(bitstream_BitstreamWriter *self,
523 PyObject *args);
524
525 static PyObject*
526 BitstreamWriter_getpos(bitstream_BitstreamWriter *self,
527 PyObject *args);
528
529 static PyObject*
530 BitstreamWriter_setpos(bitstream_BitstreamWriter *self,
531 PyObject *args);
532
533 static PyObject*
534 BitstreamWriter_build(bitstream_BitstreamWriter *self, PyObject *args);
535
536 static PyObject*
537 BitstreamWriter_flush(bitstream_BitstreamWriter *self, PyObject *args);
538
539 static PyObject*
540 BitstreamWriter_close(bitstream_BitstreamWriter *self, PyObject *args);
541
542 static PyObject*
543 BitstreamWriter_enter(bitstream_BitstreamWriter *self, PyObject *args);
544
545 static PyObject*
546 BitstreamWriter_exit(bitstream_BitstreamWriter *self, PyObject *args);
547
548 int
549 BitstreamWriter_init(bitstream_BitstreamWriter *self, PyObject *args);
550
551 PyMethodDef BitstreamWriter_methods[] = {
552 {"write", (PyCFunction)BitstreamWriter_write, METH_VARARGS,
553 "write(bits, unsigned int)"},
554 {"write_signed", (PyCFunction)BitstreamWriter_write_signed, METH_VARARGS,
555 "write_signed(bits, signed int)"},
556 {"unary", (PyCFunction)BitstreamWriter_unary, METH_VARARGS,
557 "unary(stop_bit, unsigned int)\n"
558 "where \"stop_bit\" must be 0 or 1\n"
559 "writes value as the given number of not stop_bit values (1 or 0)\n"
560 "followed by a stop_bit"},
561 {"write_huffman_code",
562 (PyCFunction)BitstreamWriter_write_huffman_code,
563 METH_VARARGS, "write_huffman_code(huffman_tree, value)\n"
564 "given a compiled HuffmanTree and int value,\n"
565 "writes that value to the stream"},
566 {"byte_align", (PyCFunction)BitstreamWriter_byte_align, METH_NOARGS,
567 "byte_align()\n"
568 "pads the stream with 0 bits until the next whole byte"},
569 {"byte_aligned", (PyCFunction)BitstreamWriter_byte_aligned, METH_NOARGS,
570 "byte_aligned() -> True if the stream is currently byte-aligned"},
571 {"flush", (PyCFunction)BitstreamWriter_flush, METH_NOARGS,
572 "flush()\n"
573 "flushes pending data to any underlying file object"},
574 {"close", (PyCFunction)BitstreamWriter_close, METH_NOARGS,
575 "close()\n"
576 "closes the stream and any underlying file object"},
577 {"set_endianness", (PyCFunction)BitstreamWriter_set_endianness,
578 METH_VARARGS,
579 "set_endianness(endianness)\n"
580 "where 0 = big endian, 1 = little endian"},
581 {"write_bytes", (PyCFunction)BitstreamWriter_write_bytes, METH_VARARGS,
582 "write_bytes(bytes, string)"},
583 {"build", (PyCFunction)BitstreamWriter_build, METH_VARARGS,
584 "build(format_string, [value1, value2, ...])\n"
585 "where \"format_string\" maps to the calls:\n"
586 "\"#u\" -> write(#, unsigned int value)\n"
587 "\"#s\" -> write_signed(#, signed int value)\n"
588 "\"#p\" -> write(#, 0)\n"
589 "\"#P\" -> write(# * 8, 0)\n"
590 "\"#b\" -> write_bytes(#, string value)\n"
591 "\"a\" -> byte_align()\n\n"
592 "for instance:\n"
593 "w.build(\"3u 4s 36u\", [1, -2, 3L])\n ==\n"
594 "w.write(3, 1); w.write_signed(4, -2); w.write(36, 3L)"},
595 {"add_callback", (PyCFunction)BitstreamWriter_add_callback, METH_VARARGS,
596 "add_callback(function)\n"
597 "where \"function\" takes a single byte as an argument\n"
598 "and is called upon each written byte to the stream"},
599 {"pop_callback", (PyCFunction)BitstreamWriter_pop_callback, METH_NOARGS,
600 "pop_callback() -> function\n"
601 "removes and returns the most recently added callback"},
602 {"call_callbacks", (PyCFunction)BitstreamWriter_call_callbacks,
603 METH_VARARGS,
604 "call_callbacks(byte)\n"
605 "calls the attached callbacks as if the byte had been written"},
606 {"getpos", (PyCFunction)BitstreamWriter_getpos, METH_NOARGS,
607 "getpos() -> position"},
608 {"setpos", (PyCFunction)BitstreamWriter_setpos, METH_VARARGS,
609 "setpos(position)"},
610 {"__enter__", (PyCFunction)BitstreamWriter_enter,
611 METH_NOARGS, "enter() -> self"},
612 {"__exit__", (PyCFunction)BitstreamWriter_exit,
613 METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
614 {NULL}
615 };
616
617 void
618 BitstreamWriter_dealloc(bitstream_BitstreamWriter *self);
619
620 static PyObject*
621 BitstreamWriter_new(PyTypeObject *type, PyObject *args,
622 PyObject *kwds);
623
624 PyTypeObject bitstream_BitstreamWriterType = {
625 PyVarObject_HEAD_INIT(NULL, 0)
626 "bitstream.BitstreamWriter", /*tp_name*/
627 sizeof(bitstream_BitstreamWriter), /*tp_basicsize*/
628 0, /*tp_itemsize*/
629 (destructor)BitstreamWriter_dealloc, /*tp_dealloc*/
630 0, /*tp_print*/
631 0, /*tp_getattr*/
632 0, /*tp_setattr*/
633 0, /*tp_compare*/
634 0, /*tp_repr*/
635 0, /*tp_as_number*/
636 0, /*tp_as_sequence*/
637 0, /*tp_as_mapping*/
638 0, /*tp_hash */
639 0, /*tp_call*/
640 0, /*tp_str*/
641 0, /*tp_getattro*/
642 0, /*tp_setattro*/
643 0, /*tp_as_buffer*/
644 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
645 "BitstreamWriter objects", /* tp_doc */
646 0, /* tp_traverse */
647 0, /* tp_clear */
648 0, /* tp_richcompare */
649 0, /* tp_weaklistoffset */
650 0, /* tp_iter */
651 0, /* tp_iternext */
652 BitstreamWriter_methods, /* tp_methods */
653 0, /* tp_members */
654 0, /* tp_getset */
655 0, /* tp_base */
656 0, /* tp_dict */
657 0, /* tp_descr_get */
658 0, /* tp_descr_set */
659 0, /* tp_dictoffset */
660 (initproc)BitstreamWriter_init,/* tp_init */
661 0, /* tp_alloc */
662 BitstreamWriter_new, /* tp_new */
663 };
664
665
666 typedef struct {
667 PyObject_HEAD
668
669 BitstreamRecorder* bitstream;
670 } bitstream_BitstreamRecorder;
671
672 static PyObject*
673 BitstreamRecorder_write(bitstream_BitstreamRecorder *self,
674 PyObject *args);
675
676 static PyObject*
677 BitstreamRecorder_write_signed(bitstream_BitstreamRecorder *self,
678 PyObject *args);
679
680 static PyObject*
681 BitstreamRecorder_unary(bitstream_BitstreamRecorder *self,
682 PyObject *args);
683
684 static PyObject*
685 BitstreamRecorder_write_huffman_code(bitstream_BitstreamRecorder *self,
686 PyObject *args);
687
688 static PyObject*
689 BitstreamRecorder_byte_align(bitstream_BitstreamRecorder *self,
690 PyObject *args);
691
692 static PyObject*
693 BitstreamRecorder_byte_aligned(bitstream_BitstreamRecorder *self,
694 PyObject *args);
695
696 static PyObject*
697 BitstreamRecorder_set_endianness(bitstream_BitstreamRecorder *self,
698 PyObject *args);
699
700 static PyObject*
701 BitstreamRecorder_bits(bitstream_BitstreamRecorder *self,
702 PyObject *args);
703
704 static PyObject*
705 BitstreamRecorder_bytes(bitstream_BitstreamRecorder *self,
706 PyObject *args);
707
708 static PyObject*
709 BitstreamRecorder_data(bitstream_BitstreamRecorder *self,
710 PyObject *args);
711
712 static PyObject*
713 BitstreamRecorder_swap(bitstream_BitstreamRecorder *self,
714 PyObject *args);
715
716 static PyObject*
717 BitstreamRecorder_write_bytes(bitstream_BitstreamRecorder *self,
718 PyObject *args);
719
720 static PyObject*
721 BitstreamRecorder_build(bitstream_BitstreamRecorder *self,
722 PyObject *args);
723
724 static PyObject*
725 BitstreamRecorder_add_callback(bitstream_BitstreamRecorder *self,
726 PyObject *args);
727
728 static PyObject*
729 BitstreamRecorder_pop_callback(bitstream_BitstreamRecorder *self,
730 PyObject *args);
731
732 static PyObject*
733 BitstreamRecorder_call_callbacks(bitstream_BitstreamRecorder *self,
734 PyObject *args);
735
736 static PyObject*
737 BitstreamRecorder_flush(bitstream_BitstreamRecorder *self,
738 PyObject *args);
739
740 static PyObject*
741 BitstreamRecorder_reset(bitstream_BitstreamRecorder *self,
742 PyObject *args);
743
744 /*returns the internal BitstreamWriter struct of the given object
745 or NULL if it is not a BitstreamWriter/Recorder*/
746 static BitstreamWriter*
747 internal_writer(PyObject *writer);
748
749 static PyObject*
750 BitstreamRecorder_copy(bitstream_BitstreamRecorder *self,
751 PyObject *args);
752
753 static PyObject*
754 BitstreamRecorder_getpos(bitstream_BitstreamRecorder *self,
755 PyObject *args);
756
757 static PyObject*
758 BitstreamRecorder_setpos(bitstream_BitstreamRecorder *self,
759 PyObject *args);
760
761 static PyObject*
762 BitstreamRecorder_close(bitstream_BitstreamRecorder *self,
763 PyObject *args);
764
765 static PyObject*
766 BitstreamRecorder_enter(bitstream_BitstreamRecorder *self, PyObject *args);
767
768 static PyObject*
769 BitstreamRecorder_exit(bitstream_BitstreamRecorder *self, PyObject *args);
770
771 int
772 BitstreamRecorder_init(bitstream_BitstreamRecorder *self,
773 PyObject *args);
774
775 PyMethodDef BitstreamRecorder_methods[] = {
776 {"write", (PyCFunction)BitstreamRecorder_write, METH_VARARGS,
777 "write(bits, unsigned int)"},
778 {"write_signed", (PyCFunction)BitstreamRecorder_write_signed, METH_VARARGS,
779 "write_signed(bits, signed int)"},
780 {"unary", (PyCFunction)BitstreamRecorder_unary, METH_VARARGS,
781 "unary(stop_bit, unsigned int)\n"
782 "where \"stop_bit\" must be 0 or 1\n"
783 "writes value as the given number of not stop_bit values (1 or 0)\n"
784 "followed by a stop_bit"},
785 {"write_huffman_code",
786 (PyCFunction)BitstreamRecorder_write_huffman_code,
787 METH_VARARGS, "write_huffman_code(huffman_tree, value)\n"
788 "given a compiled HuffmanTree and int value,\n"
789 "writes that value to the stream"},
790 {"byte_align", (PyCFunction)BitstreamRecorder_byte_align, METH_NOARGS,
791 "byte_align()\n"
792 "pads the stream with 0 bits until the next whole byte"},
793 {"byte_aligned", (PyCFunction)BitstreamRecorder_byte_aligned, METH_NOARGS,
794 "byte_aligned() -> True if the stream is currently byte-aligned"},
795 {"flush", (PyCFunction)BitstreamRecorder_flush, METH_NOARGS,
796 "flush()\n"
797 "flushes pending data to any underlying file object"},
798 {"close", (PyCFunction)BitstreamRecorder_close, METH_NOARGS,
799 "close()\n"},
800 {"set_endianness", (PyCFunction)BitstreamRecorder_set_endianness,
801 METH_VARARGS,
802 "set_endianness(endianness)\n"
803 "where 0 = big endian, 1 = little endian"},
804 {"write_bytes", (PyCFunction)BitstreamRecorder_write_bytes,
805 METH_VARARGS,
806 "write_bytes(bytes, string)"},
807 {"bits", (PyCFunction)BitstreamRecorder_bits, METH_NOARGS,
808 "bits() -> unsigned int\n"
809 "returns the total number of bits written thus far"},
810 {"bytes", (PyCFunction)BitstreamRecorder_bytes, METH_NOARGS,
811 "bytes() -> unsigned int\n"
812 "returns the total number of bytes written thus far"},
813 {"data", (PyCFunction)BitstreamRecorder_data, METH_NOARGS,
814 "data() -> string\n"
815 "returns the written data as a string"},
816 {"reset", (PyCFunction)BitstreamRecorder_reset, METH_NOARGS,
817 "reset()\n"
818 "removes all written data and resets the stream for new data"},
819 {"copy", (PyCFunction)BitstreamRecorder_copy, METH_VARARGS,
820 "copy(target)\n"
821 "copies the written data to \"target\", which must be a\n"
822 "BitstreamWriter or Recorder"},
823 {"build", (PyCFunction)BitstreamRecorder_build, METH_VARARGS,
824 "build(format_string, [value1, value2, ...])\n"
825 "where \"format_string\" maps to the calls:\n"
826 "\"#u\" -> write(#, unsigned int value)\n"
827 "\"#s\" -> write_signed(#, signed int value)\n"
828 "\"#p\" -> write(#, 0)\n"
829 "\"#P\" -> write(# * 8, 0)\n"
830 "\"#b\" -> write_bytes(#, string value)\n"
831 "\"a\" -> byte_align()\n\n"
832 "for instance:\n"
833 "r.build(\"3u 4s 36u\", [1, -2, 3L])\n ==\n"
834 "r.write(3, 1); r.write_signed(4, -2); r.write(36, 3L)"},
835 {"swap", (PyCFunction)BitstreamRecorder_swap, METH_VARARGS,
836 "swap(recorder)\n"
837 "swaps our written data with that of another BitstreamRecorder"},
838 {"add_callback", (PyCFunction)BitstreamRecorder_add_callback,
839 METH_VARARGS,
840 "add_callback(function)\n"
841 "where \"function\" takes a single byte as an argument\n"
842 "and is called upon each written byte to the stream"},
843 {"pop_callback", (PyCFunction)BitstreamRecorder_pop_callback,
844 METH_NOARGS,
845 "pop_callback() -> function\n"
846 "removes and returns the most recently added callback"},
847 {"call_callbacks", (PyCFunction)BitstreamRecorder_call_callbacks,
848 METH_VARARGS,
849 "call_callbacks(byte)\n"
850 "calls the attached callbacks as if the byte had been written"},
851 {"getpos", (PyCFunction)BitstreamRecorder_getpos, METH_NOARGS,
852 "getpos() -> position"},
853 {"setpos", (PyCFunction)BitstreamRecorder_setpos, METH_VARARGS,
854 "setpos(position)"},
855 {"__enter__", (PyCFunction)BitstreamRecorder_enter,
856 METH_NOARGS, "enter() -> self"},
857 {"__exit__", (PyCFunction)BitstreamRecorder_exit,
858 METH_VARARGS, "exit(exc_type, exc_value, traceback) -> None"},
859 {NULL}
860 };
861
862 void
863 BitstreamRecorder_dealloc(bitstream_BitstreamRecorder *self);
864
865 static PyObject*
866 BitstreamRecorder_new(PyTypeObject *type, PyObject *args,
867 PyObject *kwds);
868
869 PyTypeObject bitstream_BitstreamRecorderType = {
870 PyVarObject_HEAD_INIT(NULL, 0)
871 "bitstream.BitstreamRecorder", /*tp_name*/
872 sizeof(bitstream_BitstreamRecorder), /*tp_basicsize*/
873 0, /*tp_itemsize*/
874 (destructor)BitstreamRecorder_dealloc, /*tp_dealloc*/
875 0, /*tp_print*/
876 0, /*tp_getattr*/
877 0, /*tp_setattr*/
878 0, /*tp_compare*/
879 0, /*tp_repr*/
880 0, /*tp_as_number*/
881 0, /*tp_as_sequence*/
882 0, /*tp_as_mapping*/
883 0, /*tp_hash */
884 0, /*tp_call*/
885 0, /*tp_str*/
886 0, /*tp_getattro*/
887 0, /*tp_setattro*/
888 0, /*tp_as_buffer*/
889 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
890 "BitstreamRecorder objects", /* tp_doc */
891 0, /* tp_traverse */
892 0, /* tp_clear */
893 0, /* tp_richcompare */
894 0, /* tp_weaklistoffset */
895 0, /* tp_iter */
896 0, /* tp_iternext */
897 BitstreamRecorder_methods, /* tp_methods */
898 0, /* tp_members */
899 0, /* tp_getset */
900 0, /* tp_base */
901 0, /* tp_dict */
902 0, /* tp_descr_get */
903 0, /* tp_descr_set */
904 0, /* tp_dictoffset */
905 (initproc)BitstreamRecorder_init, /* tp_init */
906 0, /* tp_alloc */
907 BitstreamRecorder_new, /* tp_new */
908 };
909
910 /*BitstreamWriterPosition is an opaque container for positions
911 returned by BitstreamWriter.getpos()
912 it has no methods or attributes and can't even be instantiated directly*/
913 typedef struct {
914 PyObject_HEAD
915
916 bw_pos_t *pos;
917 } bitstream_BitstreamWriterPosition;
918
919 static PyObject*
920 BitstreamWriterPosition_new(PyTypeObject *type, PyObject *args,
921 PyObject *kwds);
922
923 int
924 BitstreamWriterPosition_init(bitstream_BitstreamWriterPosition *self,
925 PyObject *args);
926
927 void
928 BitstreamWriterPosition_dealloc(bitstream_BitstreamWriterPosition *self);
929
930 PyTypeObject bitstream_BitstreamWriterPositionType = {
931 PyVarObject_HEAD_INIT(NULL, 0)
932 "bitstream.BitstreamWriterPosition", /*tp_name*/
933 sizeof(bitstream_BitstreamWriterPosition), /*tp_basicsize*/
934 0, /*tp_itemsize*/
935 (destructor)BitstreamWriterPosition_dealloc, /*tp_dealloc*/
936 0, /*tp_print*/
937 0, /*tp_getattr*/
938 0, /*tp_setattr*/
939 0, /*tp_compare*/
940 0, /*tp_repr*/
941 0, /*tp_as_number*/
942 0, /*tp_as_sequence*/
943 0, /*tp_as_mapping*/
944 0, /*tp_hash */
945 0, /*tp_call*/
946 0, /*tp_str*/
947 0, /*tp_getattro*/
948 0, /*tp_setattro*/
949 0, /*tp_as_buffer*/
950 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
951 "BitstreamWriterPosition", /* tp_doc */
952 0, /* tp_traverse */
953 0, /* tp_clear */
954 0, /* tp_richcompare */
955 0, /* tp_weaklistoffset */
956 0, /* tp_iter */
957 0, /* tp_iternext */
958 0, /* tp_methods */
959 0, /* tp_members */
960 0, /* tp_getset */
961 0, /* tp_base */
962 0, /* tp_dict */
963 0, /* tp_descr_get */
964 0, /* tp_descr_set */
965 0, /* tp_dictoffset */
966 (initproc)BitstreamWriterPosition_init, /* tp_init */
967 0, /* tp_alloc */
968 BitstreamWriterPosition_new, /* tp_new */
969 };
970
971 /*given a BitstreamReader, format string and list object
972 parses the format from the reader and appends Python values to the list
973 returns 0 on success, 1 on failure (with PyErr set)*/
974 int
975 bitstream_parse(BitstreamReader* stream,
976 const char* format,
977 PyObject* values);
978
979 /*given a BitstreamWriter, format string and PySequence of Python values,
980 writes those values to the writer
981 returns 0 on success, 1 on failure (with PyErr set)*/
982 int
983 bitstream_build(BitstreamWriter* stream,
984 const char* format,
985 PyObject* iterator);
986
987 void
988 BitstreamWriter_callback(uint8_t byte, PyObject *callback);
989