AlphaComposite.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. #include "Imaging.h"
  11. #define PRECISION_BITS 7
  12. typedef struct {
  13. UINT8 r;
  14. UINT8 g;
  15. UINT8 b;
  16. UINT8 a;
  17. } rgba8;
  18. Imaging
  19. ImagingAlphaComposite(Imaging imDst, Imaging imSrc) {
  20. Imaging imOut;
  21. int x, y;
  22. /* Check arguments */
  23. if (!imDst || !imSrc || strcmp(imDst->mode, "RGBA") ||
  24. imDst->type != IMAGING_TYPE_UINT8 || imDst->bands != 4) {
  25. return ImagingError_ModeError();
  26. }
  27. if (strcmp(imDst->mode, imSrc->mode) || imDst->type != imSrc->type ||
  28. imDst->bands != imSrc->bands || imDst->xsize != imSrc->xsize ||
  29. imDst->ysize != imSrc->ysize) {
  30. return ImagingError_Mismatch();
  31. }
  32. imOut = ImagingNewDirty(imDst->mode, imDst->xsize, imDst->ysize);
  33. if (!imOut) {
  34. return NULL;
  35. }
  36. for (y = 0; y < imDst->ysize; y++) {
  37. rgba8 *dst = (rgba8 *)imDst->image[y];
  38. rgba8 *src = (rgba8 *)imSrc->image[y];
  39. rgba8 *out = (rgba8 *)imOut->image[y];
  40. for (x = 0; x < imDst->xsize; x++) {
  41. if (src->a == 0) {
  42. // Copy 4 bytes at once.
  43. *out = *dst;
  44. } else {
  45. // Integer implementation with increased precision.
  46. // Each variable has extra meaningful bits.
  47. // Divisions are rounded.
  48. UINT32 tmpr, tmpg, tmpb;
  49. UINT32 blend = dst->a * (255 - src->a);
  50. UINT32 outa255 = src->a * 255 + blend;
  51. // There we use 7 bits for precision.
  52. // We could use more, but we go beyond 32 bits.
  53. UINT32 coef1 = src->a * 255 * 255 * (1 << PRECISION_BITS) / outa255;
  54. UINT32 coef2 = 255 * (1 << PRECISION_BITS) - coef1;
  55. tmpr = src->r * coef1 + dst->r * coef2;
  56. tmpg = src->g * coef1 + dst->g * coef2;
  57. tmpb = src->b * coef1 + dst->b * coef2;
  58. out->r =
  59. SHIFTFORDIV255(tmpr + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
  60. out->g =
  61. SHIFTFORDIV255(tmpg + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
  62. out->b =
  63. SHIFTFORDIV255(tmpb + (0x80 << PRECISION_BITS)) >> PRECISION_BITS;
  64. out->a = SHIFTFORDIV255(outa255 + 0x80);
  65. }
  66. dst++;
  67. src++;
  68. out++;
  69. }
  70. }
  71. return imOut;
  72. }