Pillow
85 строк · 2.5 Кб
1/*
2* The Python Imaging Library
3* $Id$
4*
5* Alpha composite imSrc over imDst.
6* https://en.wikipedia.org/wiki/Alpha_compositing
7*
8* See the README file for details on usage and redistribution.
9*/
10
11#include "Imaging.h"12
13#define PRECISION_BITS 714
15typedef struct {16UINT8 r;17UINT8 g;18UINT8 b;19UINT8 a;20} rgba8;21
22Imaging
23ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {24Imaging imOut;25int x, y;26
27/* Check arguments */28if (!imDst || !imSrc || strcmp(imDst->mode, "RGBA") ||29imDst->type != IMAGING_TYPE_UINT8 || imDst->bands != 4) {30return ImagingError_ModeError();31}32
33if (strcmp(imDst->mode, imSrc->mode) || imDst->type != imSrc->type ||34imDst->bands != imSrc->bands || imDst->xsize != imSrc->xsize ||35imDst->ysize != imSrc->ysize) {36return ImagingError_Mismatch();37}38
39imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);40if (!imOut) {41return NULL;42}43
44for (y = 0; y < imDst->ysize; y++) {45rgba8 *dst = (rgba8 *)imDst->image[y];46rgba8 *src = (rgba8 *)imSrc->image[y];47rgba8 *out = (rgba8 *)imOut->image[y];48
49for (x = 0; x < imDst->xsize; x++) {50if (src->a == 0) {51// Copy 4 bytes at once.52*out = *dst;53} else {54// Integer implementation with increased precision.55// Each variable has extra meaningful bits.56// Divisions are rounded.57
58UINT32 tmpr, tmpg, tmpb;59UINT32 blend = dst->a * (255 - src->a);60UINT32 outa255 = src->a * 255 + blend;61// There we use 7 bits for precision.62// We could use more, but we go beyond 32 bits.63UINT32 coef1 = src->a * 255 * 255 * (1 << PRECISION_BITS) / outa255;64UINT32 coef2 = 255 * (1 << PRECISION_BITS) - coef1;65
66tmpr = src->r * coef1 + dst->r * coef2;67tmpg = src->g * coef1 + dst->g * coef2;68tmpb = src->b * coef1 + dst->b * coef2;69out->r =70SHIFTFORDIV255(tmpr + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;71out->g =72SHIFTFORDIV255(tmpg + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;73out->b =74SHIFTFORDIV255(tmpb + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;75out->a = SHIFTFORDIV255(outa255 + 0x80);76}77
78dst++;79src++;80out++;81}82}83
84return imOut;85}
86