static void premultiplyAlpha(wxBitmap& bitmap) { const int width = bitmap.GetWidth(); const int height = bitmap.GetHeight(); wxAlphaPixelData pixData(bitmap, wxPoint(0,0), wxSize(width, height)); wxAlphaPixelData::Iterator p(pixData); for (int y=0; y<height; y++) { wxAlphaPixelData::Iterator rowStart = p; for (int x=0; x<width; x++) { if (p.Red() || p.Green() || p.Blue() || p.Alpha()) { byte a = p.Alpha(); p.Red() = PREMULTIPLY(p.Red(), a); p.Green() = PREMULTIPLY(p.Green(), a); p.Blue() = PREMULTIPLY(p.Blue(), a); } ++p; } p = rowStart; p.OffsetY(pixData, 1); } }
static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first, int w, int h, int stride) { const __m128i zero = _mm_setzero_si128(); const int kSpan = 2; const int w2 = w & ~(kSpan - 1); while (h-- > 0) { uint32_t* const rgbx = (uint32_t*)rgba; int i; if (!alpha_first) { const __m128i kMask = _mm_set_epi16(0xff, 0, 0, 0, 0xff, 0, 0, 0); const __m128i kMult = _mm_set_epi16(0, 0x8081, 0x8081, 0x8081, 0, 0x8081, 0x8081, 0x8081); for (i = 0; i < w2; i += kSpan) { APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(0, 3, 3, 3), kMask, kMult); } } else { const __m128i kMask = _mm_set_epi16(0, 0, 0, 0xff, 0, 0, 0, 0xff); const __m128i kMult = _mm_set_epi16(0x8081, 0x8081, 0x8081, 0, 0x8081, 0x8081, 0x8081, 0); for (i = 0; i < w2; i += kSpan) { APPLY_ALPHA(rgbx[i], _MM_SHUFFLE(0, 0, 0, 3), kMask, kMult); } } // Finish with left-overs. for (; i < w; ++i) { uint8_t* const rgb = rgba + (alpha_first ? 1 : 0); const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3); const uint32_t a = alpha[4 * i]; if (a != 0xff) { const uint32_t mult = MULTIPLIER(a); rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult); rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult); rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult); } } rgba += stride; } }