aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2020-02-15 12:47:29 +1100
committerNeil <nyamatongwe@gmail.com>2020-02-15 12:47:29 +1100
commitb82a2f50548c33bc6727a54e193a2cccaf4e12f7 (patch)
treecab786fc8fdce3580a68bd38e7dd5946e8def1aa
parent0eb0a3e5746f7d94c23337b24db9aa2d4871b739 (diff)
downloadscintilla-mirror-b82a2f50548c33bc6727a54e193a2cccaf4e12f7.tar.gz
Extract image conversion from RGBA to BGRA premultiplied into common function.
-rwxr-xr-xgtk/PlatGTK.cxx15
-rw-r--r--src/XPM.cxx15
-rw-r--r--src/XPM.h2
-rw-r--r--win32/PlatWin.cxx27
4 files changed, 28 insertions, 31 deletions
diff --git a/gtk/PlatGTK.cxx b/gtk/PlatGTK.cxx
index a319e31ba..2947ffa11 100755
--- a/gtk/PlatGTK.cxx
+++ b/gtk/PlatGTK.cxx
@@ -601,18 +601,13 @@ void SurfaceImpl::DrawRGBAImage(PRectangle rc, int width, int height, const unsi
rc.top += (rc.Height() - height) / 2;
rc.bottom = rc.top + height;
- int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
+ const int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
const int ucs = stride * height;
std::vector<unsigned char> image(ucs);
- for (int iy=0; iy<height; iy++) {
- for (int ix=0; ix<width; ix++) {
- unsigned char *pixel = &image[0] + iy*stride + ix * 4;
- const unsigned char alpha = pixelsImage[3];
- pixel[2] = (*pixelsImage++) * alpha / 255;
- pixel[1] = (*pixelsImage++) * alpha / 255;
- pixel[0] = (*pixelsImage++) * alpha / 255;
- pixel[3] = *pixelsImage++;
- }
+ for (ptrdiff_t iy=0; iy<height; iy++) {
+ unsigned char *pixel = &image[0] + iy*stride;
+ RGBAImage::BGRAFromRGBA(pixel, pixelsImage, width);
+ pixelsImage += RGBAImage::bytesPerPixel * width;
}
cairo_surface_t *psurfImage = cairo_image_surface_create_for_data(&image[0], CAIRO_FORMAT_ARGB32, width, height, stride);
diff --git a/src/XPM.cxx b/src/XPM.cxx
index f95580403..380ae14c4 100644
--- a/src/XPM.cxx
+++ b/src/XPM.cxx
@@ -264,6 +264,21 @@ void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
pixel[3] = static_cast<unsigned char>(alpha);
}
+// Transform a block of pixels from RGBA to BGRA with premultiplied alpha.
+// Used for DrawRGBAImage on some platforms.
+void RGBAImage::BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pixelsRGBA, size_t count) noexcept {
+ for (size_t i = 0; i < count; i++) {
+ const unsigned char alpha = pixelsRGBA[3];
+ // Input is RGBA, output is BGRA with premultiplied alpha
+ pixelsBGRA[2] = pixelsRGBA[0] * alpha / 255;
+ pixelsBGRA[1] = pixelsRGBA[1] * alpha / 255;
+ pixelsBGRA[0] = pixelsRGBA[2] * alpha / 255;
+ pixelsBGRA[3] = alpha;
+ pixelsRGBA += bytesPerPixel;
+ pixelsBGRA += bytesPerPixel;
+ }
+}
+
RGBAImageSet::RGBAImageSet() : height(-1), width(-1) {
}
diff --git a/src/XPM.h b/src/XPM.h
index b7b895cdd..f8c908ecb 100644
--- a/src/XPM.h
+++ b/src/XPM.h
@@ -50,6 +50,7 @@ class RGBAImage {
float scale;
std::vector<unsigned char> pixelBytes;
public:
+ static constexpr size_t bytesPerPixel = 4;
RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_);
explicit RGBAImage(const XPM &xpm);
RGBAImage(const RGBAImage &) = default;
@@ -65,6 +66,7 @@ public:
int CountBytes() const;
const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha);
+ static void BGRAFromRGBA(unsigned char *pixelsBGRA, const unsigned char *pixelsRGBA, size_t count) noexcept;
};
/**
diff --git a/win32/PlatWin.cxx b/win32/PlatWin.cxx
index 6e5859ca3..fadc7d0f0 100644
--- a/win32/PlatWin.cxx
+++ b/win32/PlatWin.cxx
@@ -780,15 +780,10 @@ void SurfaceGDI::DrawRGBAImage(PRectangle rc, int width, int height, const unsig
HBITMAP hbmOld = SelectBitmap(hMemDC, hbmMem);
for (int y=height-1; y>=0; y--) {
- for (int x=0; x<width; x++) {
- unsigned char *pixel = static_cast<unsigned char *>(image) + (y*width+x) * 4;
- const unsigned char alpha = pixelsImage[3];
- // Input is RGBA, output is BGRA with premultiplied alpha
- pixel[2] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255);
- pixel[1] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255);
- pixel[0] = static_cast<unsigned char>((*pixelsImage++) * alpha / 255);
- pixel[3] = *pixelsImage++;
- }
+ // Bits flipped vertically
+ unsigned char *pixel = static_cast<unsigned char *>(image) + RGBAImage::bytesPerPixel * y * width;
+ RGBAImage::BGRAFromRGBA(pixel, pixelsImage, width);
+ pixelsImage += RGBAImage::bytesPerPixel * width;
}
const BLENDFUNCTION merge = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
@@ -1445,18 +1440,8 @@ void SurfaceD2D::DrawRGBAImage(PRectangle rc, int width, int height, const unsig
rc.top += std::floor((rc.Height() - height) / 2);
rc.bottom = rc.top + height;
- std::vector<unsigned char> image(height * width * 4);
- for (int yPixel=0; yPixel<height; yPixel++) {
- for (int xPixel = 0; xPixel<width; xPixel++) {
- unsigned char *pixel = &image[0] + (yPixel*width + xPixel) * 4;
- const unsigned char alpha = pixelsImage[3];
- // Input is RGBA, output is BGRA with premultiplied alpha
- pixel[2] = (*pixelsImage++) * alpha / 255;
- pixel[1] = (*pixelsImage++) * alpha / 255;
- pixel[0] = (*pixelsImage++) * alpha / 255;
- pixel[3] = *pixelsImage++;
- }
- }
+ std::vector<unsigned char> image(RGBAImage::bytesPerPixel * height * width);
+ RGBAImage::BGRAFromRGBA(image.data(), pixelsImage, static_cast<ptrdiff_t>(height) * width);
ID2D1Bitmap *bitmap = nullptr;
const D2D1_SIZE_U size = D2D1::SizeU(width, height);