diff options
| author | shumkovnd <[email protected]> | 2023-11-10 14:39:34 +0300 |
|---|---|---|
| committer | shumkovnd <[email protected]> | 2023-11-10 16:42:24 +0300 |
| commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
| tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/Pillow/py3/libImaging/AlphaComposite.c | |
| parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (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.c | 85 |
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; +} |
