// Decoder functions PyObject* _anim_decoder_new(PyObject* self, PyObject* args) { PyBytesObject *webp_string; const uint8_t *webp; Py_ssize_t size; WebPData webp_src; char* mode; WebPDecoderConfig config; WebPAnimDecoderObject* decp = NULL; WebPAnimDecoder* dec = NULL; if (!PyArg_ParseTuple(args, "S", &webp_string)) { return NULL; } PyBytes_AsStringAndSize((PyObject *)webp_string, (char**)&webp, &size); webp_src.bytes = webp; webp_src.size = size; // Sniff the mode, since the decoder API doesn't tell us mode = "RGBA"; if (WebPGetFeatures(webp, size, &config.input) == VP8_STATUS_OK) { if (!config.input.has_alpha) { mode = "RGBX"; } } // Create the decoder (default mode is RGBA, if no options passed) decp = PyObject_New(WebPAnimDecoderObject, &WebPAnimDecoder_Type); if (decp) { decp->mode = mode; if (WebPDataCopy(&webp_src, &(decp->data))) { dec = WebPAnimDecoderNew(&(decp->data), NULL); if (dec) { if (WebPAnimDecoderGetInfo(dec, &(decp->info))) { decp->dec = dec; return (PyObject*)decp; } } } PyObject_Del(decp); } PyErr_SetString(PyExc_RuntimeError, "could not create decoder object"); return NULL; }
WebPMuxError ChunkAssignData(WebPChunk* chunk, const WebPData* const data, int copy_data, uint32_t tag) { // For internally allocated chunks, always copy data & make it owner of data. if (tag == kChunks[IDX_VP8X].tag || tag == kChunks[IDX_ANIM].tag) { copy_data = 1; } ChunkRelease(chunk); if (data != NULL) { if (copy_data) { // Copy data. if (!WebPDataCopy(data, &chunk->data_)) return WEBP_MUX_MEMORY_ERROR; chunk->owner_ = 1; // Chunk is owner of data. } else { // Don't copy data. chunk->data_ = *data; } } chunk->tag_ = tag; return WEBP_MUX_OK; }