summaryrefslogtreecommitdiffstats
path: root/contrib/python/Pillow/py3/libImaging/AlphaComposite.c
diff options
context:
space:
mode:
authorshumkovnd <[email protected]>2023-11-10 14:39:34 +0300
committershumkovnd <[email protected]>2023-11-10 16:42:24 +0300
commit77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch)
treec51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/Pillow/py3/libImaging/AlphaComposite.c
parentdd6d20cadb65582270ac23f4b3b14ae189704b9d (diff)
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/Pillow/py3/libImaging/AlphaComposite.c')
-rw-r--r--contrib/python/Pillow/py3/libImaging/AlphaComposite.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/contrib/python/Pillow/py3/libImaging/AlphaComposite.c b/contrib/python/Pillow/py3/libImaging/AlphaComposite.c
new file mode 100644
index 00000000000..6d728f9088b
--- /dev/null
+++ b/contrib/python/Pillow/py3/libImaging/AlphaComposite.c
@@ -0,0 +1,85 @@
+/*
+ * The Python Imaging Library
+ * $Id$
+ *
+ * Alpha composite imSrc over imDst.
+ * https://en.wikipedia.org/wiki/Alpha_compositing
+ *
+ * See the README file for details on usage and redistribution.
+ */
+
+#include "Imaging.h"
+
+#define PRECISION_BITS 7
+
+typedef struct {
+ UINT8 r;
+ UINT8 g;
+ UINT8 b;
+ UINT8 a;
+} rgba8;
+
+Imaging
+ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {
+ Imaging imOut;
+ int x, y;
+
+ /* Check arguments */
+ if (!imDst || !imSrc || strcmp(imDst->mode, "RGBA") ||
+ imDst->type != IMAGING_TYPE_UINT8 || imDst->bands != 4) {
+ return ImagingError_ModeError();
+ }
+
+ if (strcmp(imDst->mode, imSrc->mode) || imDst->type != imSrc->type ||
+ imDst->bands != imSrc->bands || imDst->xsize != imSrc->xsize ||
+ imDst->ysize != imSrc->ysize) {
+ return ImagingError_Mismatch();
+ }
+
+ imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);
+ if (!imOut) {
+ return NULL;
+ }
+
+ for (y = 0; y < imDst->ysize; y++) {
+ rgba8 *dst = (rgba8 *)imDst->image[y];
+ rgba8 *src = (rgba8 *)imSrc->image[y];
+ rgba8 *out = (rgba8 *)imOut->image[y];
+
+ for (x = 0; x < imDst->xsize; x++) {
+ if (src->a == 0) {
+ // Copy 4 bytes at once.
+ *out = *dst;
+ } else {
+ // Integer implementation with increased precision.
+ // Each variable has extra meaningful bits.
+ // Divisions are rounded.
+
+ UINT32 tmpr, tmpg, tmpb;
+ UINT32 blend = dst->a * (255 - src->a);
+ UINT32 outa255 = src->a * 255 + blend;
+ // There we use 7 bits for precision.
+ // We could use more, but we go beyond 32 bits.
+ UINT32 coef1 = src->a * 255 * 255 * (1 << PRECISION_BITS) / outa255;
+ UINT32 coef2 = 255 * (1 << PRECISION_BITS) - coef1;
+
+ tmpr = src->r * coef1 + dst->r * coef2;
+ tmpg = src->g * coef1 + dst->g * coef2;
+ tmpb = src->b * coef1 + dst->b * coef2;
+ out->r =
+ SHIFTFORDIV255(tmpr + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
+ out->g =
+ SHIFTFORDIV255(tmpg + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
+ out->b =
+ SHIFTFORDIV255(tmpb + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
+ out->a = SHIFTFORDIV255(outa255 + 0x80);
+ }
+
+ dst++;
+ src++;
+ out++;
+ }
+ }
+
+ return imOut;
+}