From 761fe24089bfe95028b0da02a12650351b244165 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 29 Jan 2014 17:00:36 +0100 Subject: [PATCH] Add ability to directly convert between two pixel formats This is a lot easier and cheaper than having to set up a complete PixelTransformer object. --- common/rfb/PixelFormat.cxx | 50 ++++++++++++++++++++++++++++++++++++++ common/rfb/PixelFormat.h | 8 ++++++ tests/pixelconv.cxx | 7 ++++++ 3 files changed, 65 insertions(+) diff --git a/common/rfb/PixelFormat.cxx b/common/rfb/PixelFormat.cxx index 366c0a33..53b7ea50 100644 --- a/common/rfb/PixelFormat.cxx +++ b/common/rfb/PixelFormat.cxx @@ -343,6 +343,56 @@ void PixelFormat::rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, } +Pixel PixelFormat::pixelFromPixel(const PixelFormat &srcPF, Pixel src) const +{ + rdr::U16 r, g, b; + srcPF.rgbFromPixel(src, &r, &g, &b); + return pixelFromRGB(r, g, b); +} + + +void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF, + const rdr::U8* src, int pixels) const +{ + bufferFromBuffer(dst, srcPF, src, pixels, 1, pixels, pixels); +} + +void PixelFormat::bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF, + const rdr::U8* src, int w, int h, + int dstStride, int srcStride) const +{ + if (equal(srcPF)) { + // Trivial case + while (h--) { + memcpy(dst, src, w * bpp/8); + dst += dstStride * bpp/8; + src += srcStride * srcPF.bpp/8; + } + } else { + // Generic code + int dstPad = (dstStride - w) * bpp/8; + int srcPad = (srcStride - w) * srcPF.bpp/8; + while (h--) { + int w_ = w; + while (w_--) { + Pixel p; + rdr::U8 r, g, b; + + p = srcPF.pixelFromBuffer(src); + srcPF.rgbFromPixel(p, &r, &g, &b); + p = pixelFromRGB(r, g, b); + bufferFromPixel(dst, p); + + dst += bpp/8; + src += srcPF.bpp/8; + } + dst += dstPad; + src += srcPad; + } + } +} + + void PixelFormat::print(char* str, int len) const { // Unfortunately snprintf is not widely available so we build the string up diff --git a/common/rfb/PixelFormat.h b/common/rfb/PixelFormat.h index db129883..b18045f7 100644 --- a/common/rfb/PixelFormat.h +++ b/common/rfb/PixelFormat.h @@ -75,6 +75,14 @@ namespace rfb { void rgbFromBuffer(rdr::U8* dst, const rdr::U8* src, int w, int stride, int h) const; + Pixel pixelFromPixel(const PixelFormat &srcPF, Pixel src) const; + + void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF, + const rdr::U8* src, int pixels) const; + void bufferFromBuffer(rdr::U8* dst, const PixelFormat &srcPF, + const rdr::U8* src, int w, int h, + int dstStride, int srcStride) const; + void print(char* str, int len) const; bool parse(const char* str); diff --git a/tests/pixelconv.cxx b/tests/pixelconv.cxx index 92011d3e..a30ed909 100644 --- a/tests/pixelconv.cxx +++ b/tests/pixelconv.cxx @@ -42,6 +42,12 @@ static void testPixelTransformer(rfb::PixelFormat &dstpf, dst, fbsize, rfb::Point(0, 0)); } +static void testBuffer(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf, + rdr::U8 *dst, rdr::U8 *src) +{ + dstpf.bufferFromBuffer(dst, srcpf, src, tile, tile, fbsize, fbsize); +} + static void testToRGB(rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf, rdr::U8 *dst, rdr::U8 *src) { @@ -86,6 +92,7 @@ static void doTest(testfn fn, rfb::PixelFormat &dstpf, rfb::PixelFormat &srcpf) struct TestEntry tests[] = { {"memcpy", testMemcpy}, {"PixelTransformer", testPixelTransformer}, + {"bufferFromBuffer", testBuffer}, {"rgbFromBuffer", testToRGB}, {"bufferFromRGB", testFromRGB}, }; -- 2.39.5