AlphaComposite.c 2.5 KB

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