Fix CodeQL Alerts

- Cast int to Py_ssize_t for multiplication
This commit is contained in:
Andrew Senetar 2021-08-26 03:43:31 -05:00
parent 83f401595d
commit 809116c764
Signed by: arsenetar
GPG Key ID: C63300DCE48AB2F1
2 changed files with 336 additions and 354 deletions

View File

@ -2,9 +2,9 @@
* Created On: 2010-01-30 * Created On: 2010-01-30
* Copyright 2014 Hardcoded Software (http://www.hardcoded.net) * Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
* *
* This software is licensed under the "BSD" License as described in the "LICENSE" file, * This software is licensed under the "BSD" License as described in the
* which should be included with this package. The terms are also available at * "LICENSE" file, which should be included with this package. The terms are
* http://www.hardcoded.net/licenses/bsd_license * also available at http://www.hardcoded.net/licenses/bsd_license
*/ */
#include "common.h" #include "common.h"
@ -14,86 +14,84 @@ static PyObject *NoBlocksError;
/* avgdiff/maxdiff has been called with 2 block lists of different size. */ /* avgdiff/maxdiff has been called with 2 block lists of different size. */
static PyObject *DifferentBlockCountError; static PyObject *DifferentBlockCountError;
/* Returns a 3 sized tuple containing the mean color of 'image'. /* Returns a 3 sized tuple containing the mean color of 'image'.
* image: a PIL image or crop. * image: a PIL image or crop.
*/ */
static PyObject* getblock(PyObject *image) static PyObject *getblock(PyObject *image) {
{ int i, totr, totg, totb;
int i, totr, totg, totb; Py_ssize_t pixel_count;
Py_ssize_t pixel_count; PyObject *ppixels;
PyObject *ppixels;
totr = totg = totb = 0;
totr = totg = totb = 0; ppixels = PyObject_CallMethod(image, "getdata", NULL);
ppixels = PyObject_CallMethod(image, "getdata", NULL); if (ppixels == NULL) {
if (ppixels == NULL) { return NULL;
return NULL; }
}
pixel_count = PySequence_Length(ppixels);
pixel_count = PySequence_Length(ppixels); for (i = 0; i < pixel_count; i++) {
for (i=0; i<pixel_count; i++) { PyObject *ppixel, *pr, *pg, *pb;
PyObject *ppixel, *pr, *pg, *pb; int r, g, b;
int r, g, b;
ppixel = PySequence_ITEM(ppixels, i);
ppixel = PySequence_ITEM(ppixels, i); pr = PySequence_ITEM(ppixel, 0);
pr = PySequence_ITEM(ppixel, 0); pg = PySequence_ITEM(ppixel, 1);
pg = PySequence_ITEM(ppixel, 1); pb = PySequence_ITEM(ppixel, 2);
pb = PySequence_ITEM(ppixel, 2); Py_DECREF(ppixel);
Py_DECREF(ppixel); r = PyLong_AsLong(pr);
r = PyLong_AsLong(pr); g = PyLong_AsLong(pg);
g = PyLong_AsLong(pg); b = PyLong_AsLong(pb);
b = PyLong_AsLong(pb); Py_DECREF(pr);
Py_DECREF(pr); Py_DECREF(pg);
Py_DECREF(pg); Py_DECREF(pb);
Py_DECREF(pb);
totr += r;
totr += r; totg += g;
totg += g; totb += b;
totb += b; }
}
Py_DECREF(ppixels);
Py_DECREF(ppixels);
if (pixel_count) {
if (pixel_count) { totr /= pixel_count;
totr /= pixel_count; totg /= pixel_count;
totg /= pixel_count; totb /= pixel_count;
totb /= pixel_count; }
}
return inttuple(3, totr, totg, totb);
return inttuple(3, totr, totg, totb);
} }
/* Returns the difference between the first block and the second. /* Returns the difference between the first block and the second.
* It returns an absolute sum of the 3 differences (RGB). * It returns an absolute sum of the 3 differences (RGB).
*/ */
static int diff(PyObject *first, PyObject *second) static int diff(PyObject *first, PyObject *second) {
{ int r1, g1, b1, r2, b2, g2;
int r1, g1, b1, r2, b2, g2; PyObject *pr, *pg, *pb;
PyObject *pr, *pg, *pb; pr = PySequence_ITEM(first, 0);
pr = PySequence_ITEM(first, 0); pg = PySequence_ITEM(first, 1);
pg = PySequence_ITEM(first, 1); pb = PySequence_ITEM(first, 2);
pb = PySequence_ITEM(first, 2); r1 = PyLong_AsLong(pr);
r1 = PyLong_AsLong(pr); g1 = PyLong_AsLong(pg);
g1 = PyLong_AsLong(pg); b1 = PyLong_AsLong(pb);
b1 = PyLong_AsLong(pb); Py_DECREF(pr);
Py_DECREF(pr); Py_DECREF(pg);
Py_DECREF(pg); Py_DECREF(pb);
Py_DECREF(pb);
pr = PySequence_ITEM(second, 0);
pr = PySequence_ITEM(second, 0); pg = PySequence_ITEM(second, 1);
pg = PySequence_ITEM(second, 1); pb = PySequence_ITEM(second, 2);
pb = PySequence_ITEM(second, 2); r2 = PyLong_AsLong(pr);
r2 = PyLong_AsLong(pr); g2 = PyLong_AsLong(pg);
g2 = PyLong_AsLong(pg); b2 = PyLong_AsLong(pb);
b2 = PyLong_AsLong(pb); Py_DECREF(pr);
Py_DECREF(pr); Py_DECREF(pg);
Py_DECREF(pg); Py_DECREF(pb);
Py_DECREF(pb);
return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2);
return abs(r1 - r2) + abs(g1 - g2) + abs(b1 - b2);
} }
PyDoc_STRVAR(block_getblocks2_doc, PyDoc_STRVAR(block_getblocks2_doc,
"Returns a list of blocks (3 sized tuples).\n\ "Returns a list of blocks (3 sized tuples).\n\
\n\ \n\
image: A PIL image to base the blocks on.\n\ image: A PIL image to base the blocks on.\n\
block_count_per_side: This integer determine the number of blocks the function will return.\n\ block_count_per_side: This integer determine the number of blocks the function will return.\n\
@ -101,153 +99,150 @@ If it is 10, for example, 100 blocks will be returns (10 width, 10 height). The
necessarely cover square areas. The area covered by each block will be proportional to the image\n\ necessarely cover square areas. The area covered by each block will be proportional to the image\n\
itself.\n"); itself.\n");
static PyObject* block_getblocks2(PyObject *self, PyObject *args) static PyObject *block_getblocks2(PyObject *self, PyObject *args) {
{ int block_count_per_side, width, height, block_width, block_height, ih;
int block_count_per_side, width, height, block_width, block_height, ih; PyObject *image;
PyObject *image; PyObject *pimage_size, *pwidth, *pheight;
PyObject *pimage_size, *pwidth, *pheight; PyObject *result;
PyObject *result;
if (!PyArg_ParseTuple(args, "Oi", &image, &block_count_per_side)) {
if (!PyArg_ParseTuple(args, "Oi", &image, &block_count_per_side)) { return NULL;
}
pimage_size = PyObject_GetAttrString(image, "size");
pwidth = PySequence_ITEM(pimage_size, 0);
pheight = PySequence_ITEM(pimage_size, 1);
width = PyLong_AsLong(pwidth);
height = PyLong_AsLong(pheight);
Py_DECREF(pimage_size);
Py_DECREF(pwidth);
Py_DECREF(pheight);
if (!(width && height)) {
return PyList_New(0);
}
block_width = max(width / block_count_per_side, 1);
block_height = max(height / block_count_per_side, 1);
result = PyList_New((Py_ssize_t)block_count_per_side * block_count_per_side);
if (result == NULL) {
return NULL;
}
for (ih = 0; ih < block_count_per_side; ih++) {
int top, bottom, iw;
top = min(ih * block_height, height - block_height);
bottom = top + block_height;
for (iw = 0; iw < block_count_per_side; iw++) {
int left, right;
PyObject *pbox;
PyObject *pmethodname;
PyObject *pcrop;
PyObject *pblock;
left = min(iw * block_width, width - block_width);
right = left + block_width;
pbox = inttuple(4, left, top, right, bottom);
pmethodname = PyUnicode_FromString("crop");
pcrop = PyObject_CallMethodObjArgs(image, pmethodname, pbox, NULL);
Py_DECREF(pmethodname);
Py_DECREF(pbox);
if (pcrop == NULL) {
Py_DECREF(result);
return NULL; return NULL;
} }
pblock = getblock(pcrop);
pimage_size = PyObject_GetAttrString(image, "size"); Py_DECREF(pcrop);
pwidth = PySequence_ITEM(pimage_size, 0); if (pblock == NULL) {
pheight = PySequence_ITEM(pimage_size, 1); Py_DECREF(result);
width = PyLong_AsLong(pwidth);
height = PyLong_AsLong(pheight);
Py_DECREF(pimage_size);
Py_DECREF(pwidth);
Py_DECREF(pheight);
if (!(width && height)) {
return PyList_New(0);
}
block_width = max(width / block_count_per_side, 1);
block_height = max(height / block_count_per_side, 1);
result = PyList_New(block_count_per_side * block_count_per_side);
if (result == NULL) {
return NULL; return NULL;
}
PyList_SET_ITEM(result, ih * block_count_per_side + iw, pblock);
} }
}
for (ih=0; ih<block_count_per_side; ih++) {
int top, bottom, iw; return result;
top = min(ih*block_height, height-block_height);
bottom = top + block_height;
for (iw=0; iw<block_count_per_side; iw++) {
int left, right;
PyObject *pbox;
PyObject *pmethodname;
PyObject *pcrop;
PyObject *pblock;
left = min(iw*block_width, width-block_width);
right = left + block_width;
pbox = inttuple(4, left, top, right, bottom);
pmethodname = PyUnicode_FromString("crop");
pcrop = PyObject_CallMethodObjArgs(image, pmethodname, pbox, NULL);
Py_DECREF(pmethodname);
Py_DECREF(pbox);
if (pcrop == NULL) {
Py_DECREF(result);
return NULL;
}
pblock = getblock(pcrop);
Py_DECREF(pcrop);
if (pblock == NULL) {
Py_DECREF(result);
return NULL;
}
PyList_SET_ITEM(result, ih*block_count_per_side+iw, pblock);
}
}
return result;
} }
PyDoc_STRVAR(block_avgdiff_doc, PyDoc_STRVAR(block_avgdiff_doc,
"Returns the average diff between first blocks and seconds.\n\ "Returns the average diff between first blocks and seconds.\n\
\n\ \n\
If the result surpasses limit, limit + 1 is returned, except if less than min_iterations\n\ If the result surpasses limit, limit + 1 is returned, except if less than min_iterations\n\
iterations have been made in the blocks.\n"); iterations have been made in the blocks.\n");
static PyObject* block_avgdiff(PyObject *self, PyObject *args) static PyObject *block_avgdiff(PyObject *self, PyObject *args) {
{ PyObject *first, *second;
PyObject *first, *second; int limit, min_iterations;
int limit, min_iterations; Py_ssize_t count;
Py_ssize_t count; int sum, i, result;
int sum, i, result;
if (!PyArg_ParseTuple(args, "OOii", &first, &second, &limit,
if (!PyArg_ParseTuple(args, "OOii", &first, &second, &limit, &min_iterations)) { &min_iterations)) {
return NULL; return NULL;
}
count = PySequence_Length(first);
if (count != PySequence_Length(second)) {
PyErr_SetString(DifferentBlockCountError, "");
return NULL;
}
if (!count) {
PyErr_SetString(NoBlocksError, "");
return NULL;
}
sum = 0;
for (i = 0; i < count; i++) {
int iteration_count;
PyObject *item1, *item2;
iteration_count = i + 1;
item1 = PySequence_ITEM(first, i);
item2 = PySequence_ITEM(second, i);
sum += diff(item1, item2);
Py_DECREF(item1);
Py_DECREF(item2);
if ((sum > limit * iteration_count) &&
(iteration_count >= min_iterations)) {
return PyLong_FromLong(limit + 1);
} }
}
count = PySequence_Length(first);
if (count != PySequence_Length(second)) { result = sum / count;
PyErr_SetString(DifferentBlockCountError, ""); if (!result && sum) {
return NULL; result = 1;
} }
if (!count) { return PyLong_FromLong(result);
PyErr_SetString(NoBlocksError, "");
return NULL;
}
sum = 0;
for (i=0; i<count; i++) {
int iteration_count;
PyObject *item1, *item2;
iteration_count = i + 1;
item1 = PySequence_ITEM(first, i);
item2 = PySequence_ITEM(second, i);
sum += diff(item1, item2);
Py_DECREF(item1);
Py_DECREF(item2);
if ((sum > limit*iteration_count) && (iteration_count >= min_iterations)) {
return PyLong_FromLong(limit + 1);
}
}
result = sum / count;
if (!result && sum) {
result = 1;
}
return PyLong_FromLong(result);
} }
static PyMethodDef BlockMethods[] = { static PyMethodDef BlockMethods[] = {
{"getblocks2", block_getblocks2, METH_VARARGS, block_getblocks2_doc}, {"getblocks2", block_getblocks2, METH_VARARGS, block_getblocks2_doc},
{"avgdiff", block_avgdiff, METH_VARARGS, block_avgdiff_doc}, {"avgdiff", block_avgdiff, METH_VARARGS, block_avgdiff_doc},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };
static struct PyModuleDef BlockDef = { static struct PyModuleDef BlockDef = {PyModuleDef_HEAD_INIT,
PyModuleDef_HEAD_INIT, "_block",
"_block", NULL,
NULL, -1,
-1, BlockMethods,
BlockMethods, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL};
NULL
};
PyObject * PyObject *PyInit__block(void) {
PyInit__block(void) PyObject *m = PyModule_Create(&BlockDef);
{ if (m == NULL) {
PyObject *m = PyModule_Create(&BlockDef); return NULL;
if (m == NULL) { }
return NULL;
}
NoBlocksError = PyErr_NewException("_block.NoBlocksError", NULL, NULL);
PyModule_AddObject(m, "NoBlocksError", NoBlocksError);
DifferentBlockCountError = PyErr_NewException("_block.DifferentBlockCountError", NULL, NULL);
PyModule_AddObject(m, "DifferentBlockCountError", DifferentBlockCountError);
return m; NoBlocksError = PyErr_NewException("_block.NoBlocksError", NULL, NULL);
PyModule_AddObject(m, "NoBlocksError", NoBlocksError);
DifferentBlockCountError =
PyErr_NewException("_block.DifferentBlockCountError", NULL, NULL);
PyModule_AddObject(m, "DifferentBlockCountError", DifferentBlockCountError);
return m;
} }

View File

@ -2,178 +2,165 @@
* Created On: 2010-01-31 * Created On: 2010-01-31
* Copyright 2014 Hardcoded Software (http://www.hardcoded.net) * Copyright 2014 Hardcoded Software (http://www.hardcoded.net)
* *
* This software is licensed under the "BSD" License as described in the "LICENSE" file, * This software is licensed under the "BSD" License as described in the
* which should be included with this package. The terms are also available at *"LICENSE" file, which should be included with this package. The terms are also
* http://www.hardcoded.net/licenses/bsd_license *available at http://www.hardcoded.net/licenses/bsd_license
**/ **/
#define PY_SSIZE_T_CLEAN #define PY_SSIZE_T_CLEAN
#include "Python.h" #include "Python.h"
/* It seems like MS VC defines min/max already */ /* It seems like MS VC defines min/max already */
#ifndef _MSC_VER #ifndef _MSC_VER
static int static int max(int a, int b) { return b > a ? b : a; }
max(int a, int b)
{
return b > a ? b : a;
}
static int static int min(int a, int b) { return b < a ? b : a; }
min(int a, int b)
{
return b < a ? b : a;
}
#endif #endif
static PyObject* static PyObject *getblock(PyObject *image, int width, int height) {
getblock(PyObject *image, int width, int height) int pixel_count, red, green, blue, bytes_per_line;
{ PyObject *pred, *pgreen, *pblue;
int pixel_count, red, green, blue, bytes_per_line; PyObject *result;
PyObject *pred, *pgreen, *pblue;
PyObject *result; red = green = blue = 0;
pixel_count = width * height;
red = green = blue = 0; if (pixel_count) {
pixel_count = width * height; PyObject *sipptr, *bits_capsule, *pi;
if (pixel_count) { char *s;
PyObject *sipptr, *bits_capsule, *pi; int i;
char *s;
int i; pi = PyObject_CallMethod(image, "bytesPerLine", NULL);
bytes_per_line = PyLong_AsLong(pi);
pi = PyObject_CallMethod(image, "bytesPerLine", NULL); Py_DECREF(pi);
bytes_per_line = PyLong_AsLong(pi);
Py_DECREF(pi); sipptr = PyObject_CallMethod(image, "bits", NULL);
bits_capsule = PyObject_CallMethod(sipptr, "ascapsule", NULL);
sipptr = PyObject_CallMethod(image, "bits", NULL); Py_DECREF(sipptr);
bits_capsule = PyObject_CallMethod(sipptr, "ascapsule", NULL); s = (char *)PyCapsule_GetPointer(bits_capsule, NULL);
Py_DECREF(sipptr); Py_DECREF(bits_capsule);
s = (char *)PyCapsule_GetPointer(bits_capsule, NULL); /* Qt aligns all its lines on 32bit, which means that if the number of bytes
Py_DECREF(bits_capsule); *per line for image is not divisible by 4, there's going to be crap
/* Qt aligns all its lines on 32bit, which means that if the number of bytes per *inserted in "s" We have to take this into account when calculating offsets
* line for image is not divisible by 4, there's going to be crap inserted in "s" **/
* We have to take this into account when calculating offsets for (i = 0; i < height; i++) {
**/ int j;
for (i=0; i<height; i++) { for (j = 0; j < width; j++) {
int j; int offset;
for (j=0; j<width; j++) { unsigned char r, g, b;
int offset;
unsigned char r, g, b; offset = i * bytes_per_line + j * 3;
r = s[offset];
offset = i * bytes_per_line + j * 3; g = s[offset + 1];
r = s[offset]; b = s[offset + 2];
g = s[offset + 1]; red += r;
b = s[offset + 2]; green += g;
red += r; blue += b;
green += g; }
blue += b;
}
}
red /= pixel_count;
green /= pixel_count;
blue /= pixel_count;
} }
pred = PyLong_FromLong(red); red /= pixel_count;
pgreen = PyLong_FromLong(green); green /= pixel_count;
pblue = PyLong_FromLong(blue); blue /= pixel_count;
result = PyTuple_Pack(3, pred, pgreen, pblue); }
Py_DECREF(pred);
Py_DECREF(pgreen); pred = PyLong_FromLong(red);
Py_DECREF(pblue); pgreen = PyLong_FromLong(green);
pblue = PyLong_FromLong(blue);
return result; result = PyTuple_Pack(3, pred, pgreen, pblue);
Py_DECREF(pred);
Py_DECREF(pgreen);
Py_DECREF(pblue);
return result;
} }
/* block_getblocks(QImage image, int block_count_per_side) -> [(int r, int g, int b), ...] /* block_getblocks(QImage image, int block_count_per_side) -> [(int r, int g,
*int b), ...]
* *
* Compute blocks out of `image`. Note the use of min/max when compes the time of computing widths * Compute blocks out of `image`. Note the use of min/max when compes the time
* and heights and positions. This is to cover the case where the width or height of the image is *of computing widths and heights and positions. This is to cover the case where
* smaller than `block_count_per_side`. In these cases, blocks will be, of course, 1 pixel big. But *the width or height of the image is smaller than `block_count_per_side`. In
* also, because all compared block lists are required to be of the same size, any block that has *these cases, blocks will be, of course, 1 pixel big. But also, because all
* no pixel to be assigned to will simply be assigned the last pixel. This is why we have *compared block lists are required to be of the same size, any block that has
* min(..., height-block_height-1) and stuff like that. * no pixel to be assigned to will simply be assigned the last pixel. This is
**/ *why we have min(..., height-block_height-1) and stuff like that.
static PyObject* **/
block_getblocks(PyObject *self, PyObject *args) static PyObject *block_getblocks(PyObject *self, PyObject *args) {
{ int block_count_per_side, width, height, block_width, block_height, ih;
int block_count_per_side, width, height, block_width, block_height, ih; PyObject *image;
PyObject *image; PyObject *pi;
PyObject *pi; PyObject *result;
PyObject *result;
if (!PyArg_ParseTuple(args, "Oi", &image, &block_count_per_side)) {
if (!PyArg_ParseTuple(args, "Oi", &image, &block_count_per_side)) { return NULL;
}
pi = PyObject_CallMethod(image, "width", NULL);
width = PyLong_AsLong(pi);
Py_DECREF(pi);
pi = PyObject_CallMethod(image, "height", NULL);
height = PyLong_AsLong(pi);
Py_DECREF(pi);
if (!(width && height)) {
return PyList_New(0);
}
block_width = max(width / block_count_per_side, 1);
block_height = max(height / block_count_per_side, 1);
result = PyList_New((Py_ssize_t)block_count_per_side * block_count_per_side);
if (result == NULL) {
return NULL;
}
for (ih = 0; ih < block_count_per_side; ih++) {
int top, iw;
top = min(ih * block_height, height - block_height - 1);
for (iw = 0; iw < block_count_per_side; iw++) {
int left;
PyObject *pcrop;
PyObject *pblock;
left = min(iw * block_width, width - block_width - 1);
pcrop = PyObject_CallMethod(image, "copy", "iiii", left, top, block_width,
block_height);
if (pcrop == NULL) {
Py_DECREF(result);
return NULL; return NULL;
} }
pblock = getblock(pcrop, block_width, block_height);
pi = PyObject_CallMethod(image, "width", NULL); Py_DECREF(pcrop);
width = PyLong_AsLong(pi); if (pblock == NULL) {
Py_DECREF(pi); Py_DECREF(result);
pi = PyObject_CallMethod(image, "height", NULL);
height = PyLong_AsLong(pi);
Py_DECREF(pi);
if (!(width && height)) {
return PyList_New(0);
}
block_width = max(width / block_count_per_side, 1);
block_height = max(height / block_count_per_side, 1);
result = PyList_New(block_count_per_side * block_count_per_side);
if (result == NULL) {
return NULL; return NULL;
}
PyList_SET_ITEM(result, ih * block_count_per_side + iw, pblock);
} }
}
for (ih=0; ih<block_count_per_side; ih++) {
int top, iw; return result;
top = min(ih*block_height, height-block_height-1);
for (iw=0; iw<block_count_per_side; iw++) {
int left;
PyObject *pcrop;
PyObject *pblock;
left = min(iw*block_width, width-block_width-1);
pcrop = PyObject_CallMethod(image, "copy", "iiii", left, top, block_width, block_height);
if (pcrop == NULL) {
Py_DECREF(result);
return NULL;
}
pblock = getblock(pcrop, block_width, block_height);
Py_DECREF(pcrop);
if (pblock == NULL) {
Py_DECREF(result);
return NULL;
}
PyList_SET_ITEM(result, ih*block_count_per_side+iw, pblock);
}
}
return result;
} }
static PyMethodDef BlockMethods[] = { static PyMethodDef BlockMethods[] = {
{"getblocks", block_getblocks, METH_VARARGS, ""}, {"getblocks", block_getblocks, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */ {NULL, NULL, 0, NULL} /* Sentinel */
}; };
static struct PyModuleDef BlockDef = { static struct PyModuleDef BlockDef = {PyModuleDef_HEAD_INIT,
PyModuleDef_HEAD_INIT, "_block_qt",
"_block_qt", NULL,
NULL, -1,
-1, BlockMethods,
BlockMethods, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL};
NULL
};
PyObject * PyObject *PyInit__block_qt(void) {
PyInit__block_qt(void) PyObject *m = PyModule_Create(&BlockDef);
{ if (m == NULL) {
PyObject *m = PyModule_Create(&BlockDef); return NULL;
if (m == NULL) { }
return NULL; return m;
}
return m;
} }