JSOBJ Object_npyEndArray(void *prv, JSOBJ obj) { PyObject *ret; char* new_data; NpyArrContext* npyarr = (NpyArrContext*) obj; int emptyType = NPY_DEFAULT_TYPE; npy_intp i; PRINTMARK(); if (!npyarr) { return NULL; } ret = npyarr->ret; i = npyarr->i; npyarr->dec->curdim--; if (i == 0 || !npyarr->ret) { // empty array would not have been initialised so do it now. if (npyarr->dec->dtype) { emptyType = npyarr->dec->dtype->type_num; } npyarr->ret = ret = PyArray_EMPTY(npyarr->shape.len, npyarr->shape.ptr, emptyType, 0); } else if (npyarr->dec->curdim <= 0) { // realloc to final size new_data = PyDataMem_RENEW(PyArray_DATA(ret), i * npyarr->elsize); if (new_data == NULL) { PyErr_NoMemory(); Npy_releaseContext(npyarr); return NULL; } ((PyArrayObject*) ret)->data = (void*) new_data; // PyArray_BYTES(ret) = new_data; } if (npyarr->dec->curdim <= 0) { // finished decoding array, reshape if necessary if (npyarr->shape.len > 1) { npyarr->ret = PyArray_Newshape((PyArrayObject*) ret, &npyarr->shape, NPY_ANYORDER); Py_DECREF(ret); } ret = Npy_returnLabelled(npyarr); npyarr->ret = NULL; Npy_releaseContext(npyarr); } return ret; }
static PyObject* Pyaubio_source_iter_next(Py_source *self) { PyObject *done, *size; if (self->channels == 1) { done = Py_source_do(self, NULL); } else { done = Py_source_do_multi(self, NULL); } if (!PyTuple_Check(done)) { PyErr_Format(PyExc_ValueError, "error when reading source: not opened?"); return NULL; } size = PyTuple_GetItem(done, 1); if (size != NULL && PyLong_Check(size)) { if (PyLong_AsLong(size) == (long)self->hop_size) { PyObject *vec = PyTuple_GetItem(done, 0); return vec; } else if (PyLong_AsLong(size) > 0) { // short read, return a shorter array PyObject *vec = PyTuple_GetItem(done, 0); // take a copy to prevent resizing internal arrays PyArrayObject *shortread = (PyArrayObject*)PyArray_FROM_OTF(vec, NPY_NOTYPE, NPY_ARRAY_ENSURECOPY); PyArray_Dims newdims; PyObject *reshaped; newdims.len = PyArray_NDIM(shortread); newdims.ptr = PyArray_DIMS(shortread); // mono or multiple channels? if (newdims.len == 1) { newdims.ptr[0] = PyLong_AsLong(size); } else { newdims.ptr[1] = PyLong_AsLong(size); } reshaped = PyArray_Newshape(shortread, &newdims, NPY_CORDER); Py_DECREF(shortread); Py_DECREF(vec); return reshaped; } else { PyErr_SetNone(PyExc_StopIteration); return NULL; } } else { PyErr_SetNone(PyExc_StopIteration); return NULL; } }
static PyObject *_read_png(PyObject *filein, bool float_result) { png_byte header[8]; // 8 is the maximum size that can be checked FILE *fp = NULL; mpl_off_t offset = 0; bool close_file = false; bool close_dup_file = false; PyObject *py_file = NULL; png_structp png_ptr = NULL; png_infop info_ptr = NULL; int num_dims; std::vector<png_bytep> row_pointers; png_uint_32 width = 0; png_uint_32 height = 0; int bit_depth; PyObject *result = NULL; // TODO: Remove direct calls to Numpy API here if (PyBytes_Check(filein) || PyUnicode_Check(filein)) { if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"rb")) == NULL) { goto exit; } close_file = true; } else { py_file = filein; } if ((fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset))) { close_dup_file = true; } else { PyErr_Clear(); PyObject *read_method = PyObject_GetAttrString(py_file, "read"); if (!(read_method && PyCallable_Check(read_method))) { Py_XDECREF(read_method); PyErr_SetString(PyExc_TypeError, "Object does not appear to be a 8-bit string path or " "a Python file-like object"); goto exit; } Py_XDECREF(read_method); } if (fp) { if (fread(header, 1, 8, fp) != 8) { PyErr_SetString(PyExc_IOError, "error reading PNG header"); goto exit; } } else { _read_png_data(py_file, header, 8); } if (png_sig_cmp(header, 0, 8)) { PyErr_SetString(PyExc_ValueError, "invalid PNG header"); goto exit; } /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { PyErr_SetString(PyExc_RuntimeError, "png_create_read_struct failed"); goto exit; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { PyErr_SetString(PyExc_RuntimeError, "png_create_info_struct failed"); goto exit; } if (setjmp(png_jmpbuf(png_ptr))) { PyErr_SetString(PyExc_RuntimeError, "Error setting jump"); goto exit; } if (fp) { png_init_io(png_ptr, fp); } else { png_set_read_fn(png_ptr, (void *)py_file, &read_png_data); } png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); // Unpack 1, 2, and 4-bit images if (bit_depth < 8) { png_set_packing(png_ptr); } // If sig bits are set, shift data png_color_8p sig_bit; if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) && png_get_sBIT(png_ptr, info_ptr, &sig_bit)) { png_set_shift(png_ptr, sig_bit); } // Convert big endian to little if (bit_depth == 16) { png_set_swap(png_ptr); } // Convert palletes to full RGB if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); bit_depth = 8; } // If there's an alpha channel convert gray to RGB if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(png_ptr); } png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); row_pointers.resize(height); for (png_uint_32 row = 0; row < height; row++) { row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)]; } png_read_image(png_ptr, &row_pointers[0]); npy_intp dimensions[3]; dimensions[0] = height; // numrows dimensions[1] = width; // numcols if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) { dimensions[2] = 4; // RGBA images } else if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) { dimensions[2] = 3; // RGB images } else { dimensions[2] = 1; // Greyscale images } if (float_result) { double max_value = (1 << bit_depth) - 1; numpy::array_view<float, 3> A(dimensions); for (png_uint_32 y = 0; y < height; y++) { png_byte *row = row_pointers[y]; for (png_uint_32 x = 0; x < width; x++) { if (bit_depth == 16) { png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]]; for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) { A(y, x, p) = (float)(ptr[p]) / max_value; } } else { png_byte *ptr = &(row[x * dimensions[2]]); for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) { A(y, x, p) = (float)(ptr[p]) / max_value; } } } } result = A.pyobj(); } else if (bit_depth == 16) { numpy::array_view<png_uint_16, 3> A(dimensions); for (png_uint_32 y = 0; y < height; y++) { png_byte *row = row_pointers[y]; for (png_uint_32 x = 0; x < width; x++) { png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]]; for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) { A(y, x, p) = ptr[p]; } } } result = A.pyobj(); } else if (bit_depth == 8) { numpy::array_view<png_byte, 3> A(dimensions); for (png_uint_32 y = 0; y < height; y++) { png_byte *row = row_pointers[y]; for (png_uint_32 x = 0; x < width; x++) { png_byte *ptr = &(row[x * dimensions[2]]); for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) { A(y, x, p) = ptr[p]; } } } result = A.pyobj(); } else { PyErr_SetString(PyExc_RuntimeError, "image has unknown bit depth"); goto exit; } // free the png memory png_read_end(png_ptr, info_ptr); // For gray, return an x by y array, not an x by y by 1 num_dims = (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) ? 3 : 2; if (num_dims == 2) { PyArray_Dims dims = {dimensions, 2}; PyObject *reshaped = PyArray_Newshape((PyArrayObject *)result, &dims, NPY_CORDER); Py_DECREF(result); result = reshaped; } exit: if (png_ptr && info_ptr) { #ifndef png_infopp_NULL png_destroy_read_struct(&png_ptr, &info_ptr, NULL); #else png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL); #endif } if (close_dup_file) { mpl_PyFile_DupClose(py_file, fp, offset); } if (close_file) { mpl_PyFile_CloseFile(py_file); Py_DECREF(py_file); } for (png_uint_32 row = 0; row < height; row++) { delete[] row_pointers[row]; } if (PyErr_Occurred()) { Py_XDECREF(result); return NULL; } else { return result; } }