/*returns a BitstreamReader for reading 1 bit white noise dither values or NULL if an error occurs opening the os module*/ static BitstreamReader* open_dither(void) { PyObject* os_module; if ((os_module = PyImport_ImportModule("os")) != NULL) { return br_open_external(os_module, BS_BIG_ENDIAN, 4096, read_os_random, NULL, /*unseekable stream*/ NULL, /*unseekable stream*/ NULL, /*unseekable stream*/ NULL, /*unseekable stream*/ close_os_random, free_os_random); } else { return NULL; } }
int FlacDecoder_init(decoders_FlacDecoder *self, PyObject *args, PyObject *kwds) { self->file = NULL; self->bitstream = NULL; self->seektable = a_obj_new((ARRAY_COPY_FUNC)seekpoint_copy, free, NULL); self->subframe_data = aa_int_new(); self->residuals = a_int_new(); self->qlp_coeffs = a_int_new(); self->framelist_data = a_int_new(); self->audiotools_pcm = NULL; self->remaining_samples = 0; if (!PyArg_ParseTuple(args, "O", &self->file)) { return -1; } else { Py_INCREF(self->file); } /*open BitstreamReader from FLAC file stream based on whether it's a low-level file object*/ if (PyFile_Check(self->file)) { /*open bitstream through file object*/ self->bitstream = br_open(PyFile_AsFile(self->file), BS_BIG_ENDIAN); } else { /*treat file as Python-implemented file-like object*/ self->bitstream = br_open_external( self->file, BS_BIG_ENDIAN, 4096, (ext_read_f)br_read_python, (ext_close_f)bs_close_python, (ext_free_f)bs_free_python_nodecref); } /*read the STREAMINFO block, SEEKTABLE block and setup the total number of samples to read*/ if (flacdec_read_metadata(self->bitstream, &(self->streaminfo), self->seektable, &(self->channel_mask))) { self->streaminfo.channels = 0; return -1; } if (PyFile_Check(self->file)) { /*place mark at beginning of stream but after metadata in case seeking is needed*/ self->bitstream->mark(self->bitstream); } self->remaining_samples = self->streaminfo.total_samples; /*initialize the output MD5 sum*/ audiotools__MD5Init(&(self->md5)); self->perform_validation = 1; self->stream_finalized = 0; /*setup a framelist generator function*/ if ((self->audiotools_pcm = open_audiotools_pcm()) == NULL) return -1; /*mark stream as not closed and ready for reading*/ self->closed = 0; return 0; }
int ALACDecoder_init(decoders_ALACDecoder *self, PyObject *args, PyObject *kwds) { PyObject *file; unsigned atom_size; char atom_name[4]; int got_decoding_parameters = 0; int got_seektable = 0; self->bitstream = NULL; self->mdat_start = NULL; self->total_pcm_frames = 0; self->read_pcm_frames = 0; self->seektable = NULL; self->closed = 0; self->audiotools_pcm = NULL; /*setup some dummy parameters*/ self->params.block_size = 4096; self->params.history_multiplier = 40; self->params.initial_history = 10; self->params.maximum_K = 14; if (!PyArg_ParseTuple(args, "O", &file)) { return -1; } else { Py_INCREF(file); } self->bitstream = br_open_external(file, BS_BIG_ENDIAN, 4096, br_read_python, bs_setpos_python, bs_getpos_python, bs_free_pos_python, bs_fseek_python, bs_close_python, bs_free_python_decref); /*walk through atoms*/ while (read_atom_header(self->bitstream, &atom_size, atom_name)) { if (!memcmp(atom_name, "mdat", 4)) { /*get mdat atom's starting position*/ if (self->mdat_start) { PyErr_SetString(PyExc_ValueError, "multiple mdat atoms found in stream"); return -1; } else { self->mdat_start = self->bitstream->getpos(self->bitstream); self->bitstream->seek(self->bitstream, atom_size - 8, BS_SEEK_CUR); } } else if (!memcmp(atom_name, "moov", 4)) { /*find and parse metadata from moov atom*/ struct qt_atom *moov_atom; if (!setjmp(*br_try(self->bitstream))) { moov_atom = qt_atom_parse_by_name(self->bitstream, atom_size, atom_name); br_etry(self->bitstream); } else { br_etry(self->bitstream); PyErr_SetString(PyExc_IOError, "I/O error parsing moov atom"); return -1; } if (!got_decoding_parameters && get_decoding_parameters(self, moov_atom)) { /*this is an arbitrary block size limit to keep from blowing up the stack Apple's reference encoder uses 4096 exclusively but the file format allows sizes up to 32 bits(!) which would break the whole world if anybody used them all for a single ALAC frame. so I'll just assume such files are malicious and reject them outright*/ if (self->params.block_size > 65535) { PyErr_SetString(PyExc_ValueError, "block size too large"); return -1; } got_decoding_parameters = 1; } if (!got_seektable && get_seektable(self, moov_atom)) { got_seektable = 1; } moov_atom->free(moov_atom); } else { /*skip remaining atoms*/ if (atom_size >= 8) { self->bitstream->seek(self->bitstream, atom_size - 8, BS_SEEK_CUR); } } } if (!got_decoding_parameters) { PyErr_SetString(PyExc_ValueError, "no decoding parameters"); return -1; } /*seek to start of mdat atom*/ if (self->mdat_start) { self->bitstream->setpos(self->bitstream, self->mdat_start); } else { PyErr_SetString(PyExc_ValueError, "no mdat atom found in stream"); return -1; } /*open FrameList generator*/ if ((self->audiotools_pcm = open_audiotools_pcm()) == NULL) { return -1; } return 0; }