Bug Summary

File:_webp.c
Warning:line 959, column 35
PyObject ownership leak with reference count of 1

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name _webp.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -analyzer-output=html -analyzer-checker=python -analyzer-disable-checker=deadcode -analyzer-config prune-paths=true,suppress-c++-stdlib=true,suppress-null-return-paths=false,crosscheck-with-z3=true,model-path=/opt/pyrefcon/lib/pyrefcon/models/models -analyzer-config experimental-enable-naive-ctu-analysis=true,ctu-dir=/tmp/pyrefcon/Pillow/csa-scan,ctu-index-name=/tmp/pyrefcon/Pillow/csa-scan/externalDefMap.txt,ctu-invocation-list=/tmp/pyrefcon/Pillow/csa-scan/invocations.yaml,display-ctu-progress=false -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debug-info-kind=limited -dwarf-version=4 -debugger-tuning=gdb -fcoverage-compilation-dir=/tmp/pyrefcon/Pillow -resource-dir /opt/pyrefcon/lib/clang/13.0.0 -isystem /opt/pyrefcon/lib/pyrefcon/models/python3.8 -D NDEBUG -D _FORTIFY_SOURCE=2 -D HAVE_WEBPMUX -I /usr/include/freetype2 -I /usr/include/openjpeg-2.3 -I /tmp/pyrefcon/Pillow -I /usr/include/x86_64-linux-gnu -I /usr/include/fribidi -I /usr/include -internal-isystem /opt/pyrefcon/lib/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-result -Wsign-compare -Wall -Wformat -Werror=format-security -Wformat -Werror=format-security -Wdate-time -fdebug-compilation-dir=/tmp/pyrefcon/Pillow -ferror-limit 19 -fwrapv -pthread -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/pyrefcon/Pillow/csa-scan/reports -x c src/_webp.c

src/_webp.c

1#define PY_SSIZE_T_CLEAN
2#include <Python.h>
3#include "libImaging/Imaging.h"
4#include <webp/encode.h>
5#include <webp/decode.h>
6#include <webp/types.h>
7
8#ifdef HAVE_WEBPMUX1
9#include <webp/mux.h>
10#include <webp/demux.h>
11
12/*
13 * Check the versions from mux.h and demux.h, to ensure the WebPAnimEncoder and
14 * WebPAnimDecoder APIs are present (initial support was added in 0.5.0). The
15 * very early versions had some significant differences, so we require later
16 * versions, before enabling animation support.
17 */
18#if WEBP_MUX_ABI_VERSION0x0108 >= 0x0104 && WEBP_DEMUX_ABI_VERSION0x0107 >= 0x0105
19#define HAVE_WEBPANIM
20#endif
21
22#endif
23
24void
25ImagingSectionEnter(ImagingSectionCookie *cookie) {
26 *cookie = (PyThreadState *)PyEval_SaveThread();
27}
28
29void
30ImagingSectionLeave(ImagingSectionCookie *cookie) {
31 PyEval_RestoreThread((PyThreadState *)*cookie);
32}
33
34/* -------------------------------------------------------------------- */
35/* WebP Muxer Error Handling */
36/* -------------------------------------------------------------------- */
37
38#ifdef HAVE_WEBPMUX1
39
40static const char *const kErrorMessages[-WEBP_MUX_NOT_ENOUGH_DATA + 1] = {
41 "WEBP_MUX_NOT_FOUND",
42 "WEBP_MUX_INVALID_ARGUMENT",
43 "WEBP_MUX_BAD_DATA",
44 "WEBP_MUX_MEMORY_ERROR",
45 "WEBP_MUX_NOT_ENOUGH_DATA"};
46
47PyObject *
48HandleMuxError(WebPMuxError err, char *chunk) {
49 char message[100];
50 int message_len;
51 assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA)((void) (0));
52
53 // Check for a memory error first
54 if (err == WEBP_MUX_MEMORY_ERROR) {
55 return PyErr_NoMemory();
56 }
57
58 // Create the error message
59 if (chunk == NULL((void*)0)) {
60 message_len =
61 sprintf(message, "could not assemble chunks: %s", kErrorMessages[-err])__builtin___sprintf_chk (message, 2 - 1, __builtin_object_size
(message, 2 > 1), "could not assemble chunks: %s", kErrorMessages
[-err])
;
62 } else {
63 message_len = sprintf(__builtin___sprintf_chk (message, 2 - 1, __builtin_object_size
(message, 2 > 1), "could not set %.4s chunk: %s", chunk, kErrorMessages
[-err])
64 message, "could not set %.4s chunk: %s", chunk, kErrorMessages[-err])__builtin___sprintf_chk (message, 2 - 1, __builtin_object_size
(message, 2 > 1), "could not set %.4s chunk: %s", chunk, kErrorMessages
[-err])
;
65 }
66 if (message_len < 0) {
67 PyErr_SetString(PyExc_RuntimeError, "failed to construct error message");
68 return NULL((void*)0);
69 }
70
71 // Set the proper error type
72 switch (err) {
73 case WEBP_MUX_NOT_FOUND:
74 case WEBP_MUX_INVALID_ARGUMENT:
75 PyErr_SetString(PyExc_ValueError, message);
76 break;
77
78 case WEBP_MUX_BAD_DATA:
79 case WEBP_MUX_NOT_ENOUGH_DATA:
80 PyErr_SetString(PyExc_OSError, message);
81 break;
82
83 default:
84 PyErr_SetString(PyExc_RuntimeError, message);
85 break;
86 }
87 return NULL((void*)0);
88}
89
90#endif
91
92/* -------------------------------------------------------------------- */
93/* WebP Animation Support */
94/* -------------------------------------------------------------------- */
95
96#ifdef HAVE_WEBPANIM
97
98// Encoder type
99typedef struct {
100 PyObject_HEADPyObject ob_base; WebPAnimEncoder *enc;
101 WebPPicture frame;
102} WebPAnimEncoderObject;
103
104static PyTypeObject WebPAnimEncoder_Type;
105
106// Decoder type
107typedef struct {
108 PyObject_HEADPyObject ob_base; WebPAnimDecoder *dec;
109 WebPAnimInfo info;
110 WebPData data;
111 char *mode;
112} WebPAnimDecoderObject;
113
114static PyTypeObject WebPAnimDecoder_Type;
115
116// Encoder functions
117PyObject *
118_anim_encoder_new(PyObject *self, PyObject *args) {
119 int width, height;
120 uint32_t bgcolor;
121 int loop_count;
122 int minimize_size;
123 int kmin, kmax;
124 int allow_mixed;
125 int verbose;
126 WebPAnimEncoderOptions enc_options;
127 WebPAnimEncoderObject *encp = NULL((void*)0);
128 WebPAnimEncoder *enc = NULL((void*)0);
129
130 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(
131 args,
132 "iiIiiiiii",
133 &width,
134 &height,
135 &bgcolor,
136 &loop_count,
137 &minimize_size,
138 &kmin,
139 &kmax,
140 &allow_mixed,
141 &verbose)) {
142 return NULL((void*)0);
143 }
144
145 // Setup and configure the encoder's options (these are animation-specific)
146 if (!WebPAnimEncoderOptionsInit(&enc_options)) {
147 PyErr_SetString(PyExc_RuntimeError, "failed to initialize encoder options");
148 return NULL((void*)0);
149 }
150 enc_options.anim_params.bgcolor = bgcolor;
151 enc_options.anim_params.loop_count = loop_count;
152 enc_options.minimize_size = minimize_size;
153 enc_options.kmin = kmin;
154 enc_options.kmax = kmax;
155 enc_options.allow_mixed = allow_mixed;
156 enc_options.verbose = verbose;
157
158 // Validate canvas dimensions
159 if (width <= 0 || height <= 0) {
160 PyErr_SetString(PyExc_ValueError, "invalid canvas dimensions");
161 return NULL((void*)0);
162 }
163
164 // Create a new animation encoder and picture frame
165 encp = PyObject_New(WebPAnimEncoderObject, &WebPAnimEncoder_Type)( (WebPAnimEncoderObject *) _PyObject_New(&WebPAnimEncoder_Type
) )
;
166 if (encp) {
167 if (WebPPictureInit(&(encp->frame))) {
168 enc = WebPAnimEncoderNew(width, height, &enc_options);
169 if (enc) {
170 encp->enc = enc;
171 return (PyObject *)encp;
172 }
173 WebPPictureFree(&(encp->frame));
174 }
175 PyObject_DelPyObject_Free(encp);
176 }
177 PyErr_SetString(PyExc_RuntimeError, "could not create encoder object");
178 return NULL((void*)0);
179}
180
181PyObject *
182_anim_encoder_dealloc(PyObject *self) {
183 WebPAnimEncoderObject *encp = (WebPAnimEncoderObject *)self;
184 WebPPictureFree(&(encp->frame));
185 WebPAnimEncoderDelete(encp->enc);
186 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
187}
188
189PyObject *
190_anim_encoder_add(PyObject *self, PyObject *args) {
191 uint8_t *rgb;
192 Py_ssize_t size;
193 int timestamp;
194 int width;
195 int height;
196 char *mode;
197 int lossless;
198 float quality_factor;
199 int method;
200 WebPConfig config;
201 WebPAnimEncoderObject *encp = (WebPAnimEncoderObject *)self;
202 WebPAnimEncoder *enc = encp->enc;
203 WebPPicture *frame = &(encp->frame);
204
205 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(
206 args,
207 "z#iiisifi",
208 (char **)&rgb,
209 &size,
210 &timestamp,
211 &width,
212 &height,
213 &mode,
214 &lossless,
215 &quality_factor,
216 &method)) {
217 return NULL((void*)0);
218 }
219
220 // Check for NULL frame, which sets duration of final frame
221 if (!rgb) {
222 WebPAnimEncoderAdd(enc, NULL((void*)0), timestamp, NULL((void*)0));
223 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
224 }
225
226 // Setup config for this frame
227 if (!WebPConfigInit(&config)) {
228 PyErr_SetString(PyExc_RuntimeError, "failed to initialize config!");
229 return NULL((void*)0);
230 }
231 config.lossless = lossless;
232 config.quality = quality_factor;
233 config.method = method;
234
235 // Validate the config
236 if (!WebPValidateConfig(&config)) {
237 PyErr_SetString(PyExc_ValueError, "invalid configuration");
238 return NULL((void*)0);
239 }
240
241 // Populate the frame with raw bytes passed to us
242 frame->width = width;
243 frame->height = height;
244 frame->use_argb = 1; // Don't convert RGB pixels to YUV
245 if (strcmp(mode, "RGBA") == 0) {
246 WebPPictureImportRGBA(frame, rgb, 4 * width);
247 } else if (strcmp(mode, "RGBX") == 0) {
248 WebPPictureImportRGBX(frame, rgb, 4 * width);
249 } else {
250 WebPPictureImportRGB(frame, rgb, 3 * width);
251 }
252
253 // Add the frame to the encoder
254 if (!WebPAnimEncoderAdd(enc, frame, timestamp, &config)) {
255 PyErr_SetString(PyExc_RuntimeError, WebPAnimEncoderGetError(enc));
256 return NULL((void*)0);
257 }
258
259 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
260}
261
262PyObject *
263_anim_encoder_assemble(PyObject *self, PyObject *args) {
264 uint8_t *icc_bytes;
265 uint8_t *exif_bytes;
266 uint8_t *xmp_bytes;
267 Py_ssize_t icc_size;
268 Py_ssize_t exif_size;
269 Py_ssize_t xmp_size;
270 WebPData webp_data;
271 WebPAnimEncoderObject *encp = (WebPAnimEncoderObject *)self;
272 WebPAnimEncoder *enc = encp->enc;
273 WebPMux *mux = NULL((void*)0);
274 PyObject *ret = NULL((void*)0);
275
276 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(
277 args,
278 "s#s#s#",
279 &icc_bytes,
280 &icc_size,
281 &exif_bytes,
282 &exif_size,
283 &xmp_bytes,
284 &xmp_size)) {
285 return NULL((void*)0);
286 }
287
288 // Init the output buffer
289 WebPDataInit(&webp_data);
290
291 // Assemble everything into the output buffer
292 if (!WebPAnimEncoderAssemble(enc, &webp_data)) {
293 PyErr_SetString(PyExc_RuntimeError, WebPAnimEncoderGetError(enc));
294 return NULL((void*)0);
295 }
296
297 // Re-mux to add metadata as needed
298 if (icc_size > 0 || exif_size > 0 || xmp_size > 0) {
299 WebPMuxError err = WEBP_MUX_OK;
300 int i_icc_size = (int)icc_size;
301 int i_exif_size = (int)exif_size;
302 int i_xmp_size = (int)xmp_size;
303 WebPData icc_profile = {icc_bytes, i_icc_size};
304 WebPData exif = {exif_bytes, i_exif_size};
305 WebPData xmp = {xmp_bytes, i_xmp_size};
306
307 mux = WebPMuxCreate(&webp_data, 1);
308 if (mux == NULL((void*)0)) {
309 PyErr_SetString(PyExc_RuntimeError, "could not re-mux to add metadata");
310 return NULL((void*)0);
311 }
312 WebPDataClear(&webp_data);
313
314 // Add ICCP chunk
315 if (i_icc_size > 0) {
316 err = WebPMuxSetChunk(mux, "ICCP", &icc_profile, 1);
317 if (err != WEBP_MUX_OK) {
318 return HandleMuxError(err, "ICCP");
319 }
320 }
321
322 // Add EXIF chunk
323 if (i_exif_size > 0) {
324 err = WebPMuxSetChunk(mux, "EXIF", &exif, 1);
325 if (err != WEBP_MUX_OK) {
326 return HandleMuxError(err, "EXIF");
327 }
328 }
329
330 // Add XMP chunk
331 if (i_xmp_size > 0) {
332 err = WebPMuxSetChunk(mux, "XMP ", &xmp, 1);
333 if (err != WEBP_MUX_OK) {
334 return HandleMuxError(err, "XMP");
335 }
336 }
337
338 err = WebPMuxAssemble(mux, &webp_data);
339 if (err != WEBP_MUX_OK) {
340 return HandleMuxError(err, NULL((void*)0));
341 }
342 }
343
344 // Convert to Python bytes
345 ret = PyBytes_FromStringAndSize((char *)webp_data.bytes, webp_data.size);
346 WebPDataClear(&webp_data);
347
348 // If we had to re-mux, we should free it now that we're done with it
349 if (mux != NULL((void*)0)) {
350 WebPMuxDelete(mux);
351 }
352
353 return ret;
354}
355
356// Decoder functions
357PyObject *
358_anim_decoder_new(PyObject *self, PyObject *args) {
359 PyBytesObject *webp_string;
360 const uint8_t *webp;
361 Py_ssize_t size;
362 WebPData webp_src;
363 char *mode;
364 WebPDecoderConfig config;
365 WebPAnimDecoderObject *decp = NULL((void*)0);
366 WebPAnimDecoder *dec = NULL((void*)0);
367
368 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "S", &webp_string)) {
369 return NULL((void*)0);
370 }
371 PyBytes_AsStringAndSize((PyObject *)webp_string, (char **)&webp, &size);
372 webp_src.bytes = webp;
373 webp_src.size = size;
374
375 // Sniff the mode, since the decoder API doesn't tell us
376 mode = "RGBA";
377 if (WebPGetFeatures(webp, size, &config.input) == VP8_STATUS_OK) {
378 if (!config.input.has_alpha) {
379 mode = "RGBX";
380 }
381 }
382
383 // Create the decoder (default mode is RGBA, if no options passed)
384 decp = PyObject_New(WebPAnimDecoderObject, &WebPAnimDecoder_Type)( (WebPAnimDecoderObject *) _PyObject_New(&WebPAnimDecoder_Type
) )
;
385 if (decp) {
386 decp->mode = mode;
387 if (WebPDataCopy(&webp_src, &(decp->data))) {
388 dec = WebPAnimDecoderNew(&(decp->data), NULL((void*)0));
389 if (dec) {
390 if (WebPAnimDecoderGetInfo(dec, &(decp->info))) {
391 decp->dec = dec;
392 return (PyObject *)decp;
393 }
394 }
395 }
396 PyObject_DelPyObject_Free(decp);
397 }
398 PyErr_SetString(PyExc_RuntimeError, "could not create decoder object");
399 return NULL((void*)0);
400}
401
402PyObject *
403_anim_decoder_dealloc(PyObject *self) {
404 WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
405 WebPDataClear(&(decp->data));
406 WebPAnimDecoderDelete(decp->dec);
407 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
408}
409
410PyObject *
411_anim_decoder_get_info(PyObject *self) {
412 WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
413 WebPAnimInfo *info = &(decp->info);
414
415 return Py_BuildValue_Py_BuildValue_SizeT(
416 "IIIIIs",
417 info->canvas_width,
418 info->canvas_height,
419 info->loop_count,
420 info->bgcolor,
421 info->frame_count,
422 decp->mode);
423}
424
425PyObject *
426_anim_decoder_get_chunk(PyObject *self, PyObject *args) {
427 char *mode;
428 WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
429 const WebPDemuxer *demux;
430 WebPChunkIterator iter;
431 PyObject *ret;
432
433 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "s", &mode)) {
434 return NULL((void*)0);
435 }
436
437 demux = WebPAnimDecoderGetDemuxer(decp->dec);
438 if (!WebPDemuxGetChunk(demux, mode, 1, &iter)) {
439 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
440 }
441
442 ret = PyBytes_FromStringAndSize((const char *)iter.chunk.bytes, iter.chunk.size);
443 WebPDemuxReleaseChunkIterator(&iter);
444
445 return ret;
446}
447
448PyObject *
449_anim_decoder_get_next(PyObject *self) {
450 uint8_t *buf;
451 int timestamp;
452 PyObject *bytes;
453 PyObject *ret;
454 WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
455
456 if (!WebPAnimDecoderGetNext(decp->dec, &buf, &timestamp)) {
457 PyErr_SetString(PyExc_OSError, "failed to read next frame");
458 return NULL((void*)0);
459 }
460
461 bytes = PyBytes_FromStringAndSize(
462 (char *)buf, decp->info.canvas_width * 4 * decp->info.canvas_height);
463
464 ret = Py_BuildValue_Py_BuildValue_SizeT("Si", bytes, timestamp);
465
466 Py_DECREF(bytes)_Py_DECREF(((PyObject*)(bytes)));
467 return ret;
468}
469
470PyObject *
471_anim_decoder_reset(PyObject *self) {
472 WebPAnimDecoderObject *decp = (WebPAnimDecoderObject *)self;
473 WebPAnimDecoderReset(decp->dec);
474 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
475}
476
477/* -------------------------------------------------------------------- */
478/* Type Definitions */
479/* -------------------------------------------------------------------- */
480
481// WebPAnimEncoder methods
482static struct PyMethodDef _anim_encoder_methods[] = {
483 {"add", (PyCFunction)_anim_encoder_add, METH_VARARGS0x0001, "add"},
484 {"assemble", (PyCFunction)_anim_encoder_assemble, METH_VARARGS0x0001, "assemble"},
485 {NULL((void*)0), NULL((void*)0)} /* sentinel */
486};
487
488// WebPAnimDecoder type definition
489static PyTypeObject WebPAnimEncoder_Type = {
490 PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "WebPAnimEncoder", /*tp_name */
491 sizeof(WebPAnimEncoderObject), /*tp_size */
492 0, /*tp_itemsize */
493 /* methods */
494 (destructor)_anim_encoder_dealloc, /*tp_dealloc*/
495 0, /*tp_print*/
496 0, /*tp_getattr*/
497 0, /*tp_setattr*/
498 0, /*tp_compare*/
499 0, /*tp_repr*/
500 0, /*tp_as_number */
501 0, /*tp_as_sequence */
502 0, /*tp_as_mapping */
503 0, /*tp_hash*/
504 0, /*tp_call*/
505 0, /*tp_str*/
506 0, /*tp_getattro*/
507 0, /*tp_setattro*/
508 0, /*tp_as_buffer*/
509 Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /*tp_flags*/
510 0, /*tp_doc*/
511 0, /*tp_traverse*/
512 0, /*tp_clear*/
513 0, /*tp_richcompare*/
514 0, /*tp_weaklistoffset*/
515 0, /*tp_iter*/
516 0, /*tp_iternext*/
517 _anim_encoder_methods, /*tp_methods*/
518 0, /*tp_members*/
519 0, /*tp_getset*/
520};
521
522// WebPAnimDecoder methods
523static struct PyMethodDef _anim_decoder_methods[] = {
524 {"get_info", (PyCFunction)_anim_decoder_get_info, METH_NOARGS0x0004, "get_info"},
525 {"get_chunk", (PyCFunction)_anim_decoder_get_chunk, METH_VARARGS0x0001, "get_chunk"},
526 {"get_next", (PyCFunction)_anim_decoder_get_next, METH_NOARGS0x0004, "get_next"},
527 {"reset", (PyCFunction)_anim_decoder_reset, METH_NOARGS0x0004, "reset"},
528 {NULL((void*)0), NULL((void*)0)} /* sentinel */
529};
530
531// WebPAnimDecoder type definition
532static PyTypeObject WebPAnimDecoder_Type = {
533 PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, "WebPAnimDecoder", /*tp_name */
534 sizeof(WebPAnimDecoderObject), /*tp_size */
535 0, /*tp_itemsize */
536 /* methods */
537 (destructor)_anim_decoder_dealloc, /*tp_dealloc*/
538 0, /*tp_print*/
539 0, /*tp_getattr*/
540 0, /*tp_setattr*/
541 0, /*tp_compare*/
542 0, /*tp_repr*/
543 0, /*tp_as_number */
544 0, /*tp_as_sequence */
545 0, /*tp_as_mapping */
546 0, /*tp_hash*/
547 0, /*tp_call*/
548 0, /*tp_str*/
549 0, /*tp_getattro*/
550 0, /*tp_setattro*/
551 0, /*tp_as_buffer*/
552 Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /*tp_flags*/
553 0, /*tp_doc*/
554 0, /*tp_traverse*/
555 0, /*tp_clear*/
556 0, /*tp_richcompare*/
557 0, /*tp_weaklistoffset*/
558 0, /*tp_iter*/
559 0, /*tp_iternext*/
560 _anim_decoder_methods, /*tp_methods*/
561 0, /*tp_members*/
562 0, /*tp_getset*/
563};
564
565#endif
566
567/* -------------------------------------------------------------------- */
568/* Legacy WebP Support */
569/* -------------------------------------------------------------------- */
570
571PyObject *
572WebPEncode_wrapper(PyObject *self, PyObject *args) {
573 int width;
574 int height;
575 int lossless;
576 float quality_factor;
577 int method;
578 uint8_t *rgb;
579 uint8_t *icc_bytes;
580 uint8_t *exif_bytes;
581 uint8_t *xmp_bytes;
582 uint8_t *output;
583 char *mode;
584 Py_ssize_t size;
585 Py_ssize_t icc_size;
586 Py_ssize_t exif_size;
587 Py_ssize_t xmp_size;
588 size_t ret_size;
589 int rgba_mode;
590 int channels;
591 int ok;
592 ImagingSectionCookie cookie;
593 WebPConfig config;
594 WebPMemoryWriter writer;
595 WebPPicture pic;
596
597 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(
598 args,
599 "y#iiifss#is#s#",
600 (char **)&rgb,
601 &size,
602 &width,
603 &height,
604 &lossless,
605 &quality_factor,
606 &mode,
607 &icc_bytes,
608 &icc_size,
609 &method,
610 &exif_bytes,
611 &exif_size,
612 &xmp_bytes,
613 &xmp_size)) {
614 return NULL((void*)0);
615 }
616
617 rgba_mode = strcmp(mode, "RGBA") == 0;
618 if (!rgba_mode && strcmp(mode, "RGB") != 0) {
619 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
620 }
621
622 channels = rgba_mode ? 4 : 3;
623 if (size < width * height * channels) {
624 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
625 }
626
627 // Setup config for this frame
628 if (!WebPConfigInit(&config)) {
629 PyErr_SetString(PyExc_RuntimeError, "failed to initialize config!");
630 return NULL((void*)0);
631 }
632 config.lossless = lossless;
633 config.quality = quality_factor;
634 config.method = method;
635
636 // Validate the config
637 if (!WebPValidateConfig(&config)) {
638 PyErr_SetString(PyExc_ValueError, "invalid configuration");
639 return NULL((void*)0);
640 }
641
642 if (!WebPPictureInit(&pic)) {
643 PyErr_SetString(PyExc_ValueError, "could not initialise picture");
644 return NULL((void*)0);
645 }
646 pic.width = width;
647 pic.height = height;
648 pic.use_argb = 1; // Don't convert RGB pixels to YUV
649
650 if (rgba_mode) {
651 WebPPictureImportRGBA(&pic, rgb, channels * width);
652 } else {
653 WebPPictureImportRGB(&pic, rgb, channels * width);
654 }
655
656 WebPMemoryWriterInit(&writer);
657 pic.writer = WebPMemoryWrite;
658 pic.custom_ptr = &writer;
659
660 ImagingSectionEnter(&cookie);
661 ok = WebPEncode(&config, &pic);
662 ImagingSectionLeave(&cookie);
663
664 WebPPictureFree(&pic);
665 if (!ok) {
666 PyErr_Format(PyExc_ValueError, "encoding error %d", (&pic)->error_code);
667 return NULL((void*)0);
668 }
669 output = writer.mem;
670 ret_size = writer.size;
671
672#ifndef HAVE_WEBPMUX1
673 if (ret_size > 0) {
674 PyObject *ret = PyBytes_FromStringAndSize((char *)output, ret_size);
675 free(output);
676 return ret;
677 }
678#else
679 {
680 /* I want to truncate the *_size items that get passed into WebP
681 data. Pypy2.1.0 had some issues where the Py_ssize_t items had
682 data in the upper byte. (Not sure why, it shouldn't have been there)
683 */
684 int i_icc_size = (int)icc_size;
685 int i_exif_size = (int)exif_size;
686 int i_xmp_size = (int)xmp_size;
687 WebPData output_data = {0};
688 WebPData image = {output, ret_size};
689 WebPData icc_profile = {icc_bytes, i_icc_size};
690 WebPData exif = {exif_bytes, i_exif_size};
691 WebPData xmp = {xmp_bytes, i_xmp_size};
692 WebPMuxError err;
693 int dbg = 0;
694
695 int copy_data = 0; // value 1 indicates given data WILL be copied to the mux
696 // and value 0 indicates data will NOT be copied.
697
698 WebPMux *mux = WebPMuxNew();
699 WebPMuxSetImage(mux, &image, copy_data);
700
701 if (dbg) {
702 /* was getting %ld icc_size == 0, icc_size>0 was true */
703 fprintf(stderr, "icc size %d, %d \n", i_icc_size, i_icc_size > 0)__fprintf_chk (stderr, 2 - 1, "icc size %d, %d \n", i_icc_size
, i_icc_size > 0)
;
704 }
705
706 if (i_icc_size > 0) {
707 if (dbg) {
708 fprintf(stderr, "Adding ICC Profile\n")__fprintf_chk (stderr, 2 - 1, "Adding ICC Profile\n");
709 }
710 err = WebPMuxSetChunk(mux, "ICCP", &icc_profile, copy_data);
711 if (err != WEBP_MUX_OK) {
712 return HandleMuxError(err, "ICCP");
713 }
714 }
715
716 if (dbg) {
717 fprintf(stderr, "exif size %d \n", i_exif_size)__fprintf_chk (stderr, 2 - 1, "exif size %d \n", i_exif_size);
718 }
719 if (i_exif_size > 0) {
720 if (dbg) {
721 fprintf(stderr, "Adding Exif Data\n")__fprintf_chk (stderr, 2 - 1, "Adding Exif Data\n");
722 }
723 err = WebPMuxSetChunk(mux, "EXIF", &exif, copy_data);
724 if (err != WEBP_MUX_OK) {
725 return HandleMuxError(err, "EXIF");
726 }
727 }
728
729 if (dbg) {
730 fprintf(stderr, "xmp size %d \n", i_xmp_size)__fprintf_chk (stderr, 2 - 1, "xmp size %d \n", i_xmp_size);
731 }
732 if (i_xmp_size > 0) {
733 if (dbg) {
734 fprintf(stderr, "Adding XMP Data\n")__fprintf_chk (stderr, 2 - 1, "Adding XMP Data\n");
735 }
736 err = WebPMuxSetChunk(mux, "XMP ", &xmp, copy_data);
737 if (err != WEBP_MUX_OK) {
738 return HandleMuxError(err, "XMP ");
739 }
740 }
741
742 WebPMuxAssemble(mux, &output_data);
743 WebPMuxDelete(mux);
744 free(output);
745
746 ret_size = output_data.size;
747 if (ret_size > 0) {
748 PyObject *ret =
749 PyBytes_FromStringAndSize((char *)output_data.bytes, ret_size);
750 WebPDataClear(&output_data);
751 return ret;
752 }
753 }
754#endif
755 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
756}
757
758PyObject *
759WebPDecode_wrapper(PyObject *self, PyObject *args) {
760 PyBytesObject *webp_string;
761 const uint8_t *webp;
762 Py_ssize_t size;
763 PyObject *ret = Py_None(&_Py_NoneStruct), *bytes = NULL((void*)0), *pymode = NULL((void*)0), *icc_profile = NULL((void*)0),
764 *exif = NULL((void*)0);
765 WebPDecoderConfig config;
766 VP8StatusCode vp8_status_code = VP8_STATUS_OK;
767 char *mode = "RGB";
768
769 if (!PyArg_ParseTuple_PyArg_ParseTuple_SizeT(args, "S", &webp_string)) {
770 return NULL((void*)0);
771 }
772
773 if (!WebPInitDecoderConfig(&config)) {
774 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
775 }
776
777 PyBytes_AsStringAndSize((PyObject *)webp_string, (char **)&webp, &size);
778
779 vp8_status_code = WebPGetFeatures(webp, size, &config.input);
780 if (vp8_status_code == VP8_STATUS_OK) {
781 // If we don't set it, we don't get alpha.
782 // Initialized to MODE_RGB
783 if (config.input.has_alpha) {
784 config.output.colorspace = MODE_RGBA;
785 mode = "RGBA";
786 }
787
788#ifndef HAVE_WEBPMUX1
789 vp8_status_code = WebPDecode(webp, size, &config);
790#else
791 {
792 int copy_data = 0;
793 WebPData data = {webp, size};
794 WebPMuxFrameInfo image;
795 WebPData icc_profile_data = {0};
796 WebPData exif_data = {0};
797
798 WebPMux *mux = WebPMuxCreate(&data, copy_data);
799 if (NULL((void*)0) == mux) {
800 goto end;
801 }
802
803 if (WEBP_MUX_OK != WebPMuxGetFrame(mux, 1, &image)) {
804 WebPMuxDelete(mux);
805 goto end;
806 }
807
808 webp = image.bitstream.bytes;
809 size = image.bitstream.size;
810
811 vp8_status_code = WebPDecode(webp, size, &config);
812
813 if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "ICCP", &icc_profile_data)) {
814 icc_profile = PyBytes_FromStringAndSize(
815 (const char *)icc_profile_data.bytes, icc_profile_data.size);
816 }
817
818 if (WEBP_MUX_OK == WebPMuxGetChunk(mux, "EXIF", &exif_data)) {
819 exif = PyBytes_FromStringAndSize(
820 (const char *)exif_data.bytes, exif_data.size);
821 }
822
823 WebPDataClear(&image.bitstream);
824 WebPMuxDelete(mux);
825 }
826#endif
827 }
828
829 if (vp8_status_code != VP8_STATUS_OK) {
830 goto end;
831 }
832
833 if (config.output.colorspace < MODE_YUV) {
834 bytes = PyBytes_FromStringAndSize(
835 (char *)config.output.u.RGBA.rgba, config.output.u.RGBA.size);
836 } else {
837 // Skipping YUV for now. Need Test Images.
838 // UNDONE -- unclear if we'll ever get here if we set mode_rgb*
839 bytes = PyBytes_FromStringAndSize(
840 (char *)config.output.u.YUVA.y, config.output.u.YUVA.y_size);
841 }
842
843 pymode = PyUnicode_FromString(mode);
844 ret = Py_BuildValue_Py_BuildValue_SizeT(
845 "SiiSSS",
846 bytes,
847 config.output.width,
848 config.output.height,
849 pymode,
850 NULL((void*)0) == icc_profile ? Py_None(&_Py_NoneStruct) : icc_profile,
851 NULL((void*)0) == exif ? Py_None(&_Py_NoneStruct) : exif);
852
853end:
854 WebPFreeDecBuffer(&config.output);
855
856 Py_XDECREF(bytes)_Py_XDECREF(((PyObject*)(bytes)));
857 Py_XDECREF(pymode)_Py_XDECREF(((PyObject*)(pymode)));
858 Py_XDECREF(icc_profile)_Py_XDECREF(((PyObject*)(icc_profile)));
859 Py_XDECREF(exif)_Py_XDECREF(((PyObject*)(exif)));
860
861 if (Py_None(&_Py_NoneStruct) == ret) {
862 Py_RETURN_NONEreturn _Py_INCREF(((PyObject*)((&_Py_NoneStruct)))), (&
_Py_NoneStruct)
;
863 }
864
865 return ret;
866}
867
868// Return the decoder's version number, packed in hexadecimal using 8bits for
869// each of major/minor/revision. E.g: v2.5.7 is 0x020507.
870PyObject *
871WebPDecoderVersion_wrapper() {
872 return Py_BuildValue_Py_BuildValue_SizeT("i", WebPGetDecoderVersion());
873}
874
875// Version as string
876const char *
877WebPDecoderVersion_str(void) {
878 static char version[20];
879 int version_number = WebPGetDecoderVersion();
880 sprintf(__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
881 version,__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
882 "%d.%d.%d",__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
883 version_number >> 16,__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
884 (version_number >> 8) % 0x100,__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
885 version_number % 0x100)__builtin___sprintf_chk (version, 2 - 1, __builtin_object_size
(version, 2 > 1), "%d.%d.%d", version_number >> 16,
(version_number >> 8) % 0x100, version_number % 0x100)
;
886 return version;
887}
888
889/*
890 * The version of webp that ships with (0.1.3) Ubuntu 12.04 doesn't handle alpha well.
891 * Files that are valid with 0.3 are reported as being invalid.
892 */
893int
894WebPDecoderBuggyAlpha(void) {
895 return WebPGetDecoderVersion() == 0x0103;
896}
897
898PyObject *
899WebPDecoderBuggyAlpha_wrapper() {
900 return Py_BuildValue_Py_BuildValue_SizeT("i", WebPDecoderBuggyAlpha());
901}
902
903/* -------------------------------------------------------------------- */
904/* Module Setup */
905/* -------------------------------------------------------------------- */
906
907static PyMethodDef webpMethods[] = {
908#ifdef HAVE_WEBPANIM
909 {"WebPAnimDecoder", _anim_decoder_new, METH_VARARGS0x0001, "WebPAnimDecoder"},
910 {"WebPAnimEncoder", _anim_encoder_new, METH_VARARGS0x0001, "WebPAnimEncoder"},
911#endif
912 {"WebPEncode", WebPEncode_wrapper, METH_VARARGS0x0001, "WebPEncode"},
913 {"WebPDecode", WebPDecode_wrapper, METH_VARARGS0x0001, "WebPDecode"},
914 {"WebPDecoderVersion", WebPDecoderVersion_wrapper, METH_NOARGS0x0004, "WebPVersion"},
915 {"WebPDecoderBuggyAlpha",
916 WebPDecoderBuggyAlpha_wrapper,
917 METH_NOARGS0x0004,
918 "WebPDecoderBuggyAlpha"},
919 {NULL((void*)0), NULL((void*)0)}};
920
921void
922addMuxFlagToModule(PyObject *m) {
923 PyObject *have_webpmux;
924#ifdef HAVE_WEBPMUX1
925 have_webpmux = Py_True((PyObject *) &_Py_TrueStruct);
926#else
927 have_webpmux = Py_False((PyObject *) &_Py_FalseStruct);
928#endif
929 Py_INCREF(have_webpmux)_Py_INCREF(((PyObject*)(have_webpmux)));
930 PyModule_AddObject(m, "HAVE_WEBPMUX", have_webpmux);
931}
932
933void
934addAnimFlagToModule(PyObject *m) {
935 PyObject *have_webpanim;
936#ifdef HAVE_WEBPANIM
937 have_webpanim = Py_True((PyObject *) &_Py_TrueStruct);
938#else
939 have_webpanim = Py_False((PyObject *) &_Py_FalseStruct);
940#endif
941 Py_INCREF(have_webpanim)_Py_INCREF(((PyObject*)(have_webpanim)));
942 PyModule_AddObject(m, "HAVE_WEBPANIM", have_webpanim);
943}
944
945void
946addTransparencyFlagToModule(PyObject *m) {
947 PyModule_AddObject(
948 m, "HAVE_TRANSPARENCY", PyBool_FromLong(!WebPDecoderBuggyAlpha()));
949}
950
951static int
952setup_module(PyObject *m) {
953 PyObject *d = PyModule_GetDict(m);
954 addMuxFlagToModule(m);
955 addAnimFlagToModule(m);
956 addTransparencyFlagToModule(m);
957
958 PyDict_SetItemString(
959 d, "webpdecoder_version", PyUnicode_FromString(WebPDecoderVersion_str()));
2
Calling 'PyUnicode_FromString'
4
Returning from 'PyUnicode_FromString'
5
PyObject ownership leak with reference count of 1
960
961#ifdef HAVE_WEBPANIM
962 /* Ready object types */
963 if (PyType_Ready(&WebPAnimDecoder_Type) < 0 ||
964 PyType_Ready(&WebPAnimEncoder_Type) < 0) {
965 return -1;
966 }
967#endif
968 return 0;
969}
970
971PyMODINIT_FUNCPyObject*
972PyInit__webp(void) {
973 PyObject *m;
974
975 static PyModuleDef module_def = {
976 PyModuleDef_HEAD_INIT{ { 1, ((void*)0) }, ((void*)0), 0, ((void*)0), },
977 "_webp", /* m_name */
978 NULL((void*)0), /* m_doc */
979 -1, /* m_size */
980 webpMethods, /* m_methods */
981 };
982
983 m = PyModule_Create(&module_def)PyModule_Create2(&module_def, 1013);
984 if (setup_module(m) < 0) {
1
Calling 'setup_module'
985 return NULL((void*)0);
986 }
987
988 return m;
989}

/opt/pyrefcon/lib/pyrefcon/models/models/PyUnicode_FromString.model

1#ifndef PyUnicode_FromString
2struct _object;
3typedef struct _object PyObject;
4PyObject* clang_analyzer_PyObject_New_Reference();
5PyObject *PyUnicode_FromString(const char *u) {
6 return clang_analyzer_PyObject_New_Reference();
3
Setting reference count to 1
7}
8#else
9#warning "API PyUnicode_FromString is defined as a macro."
10#endif