summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2016-02-08 22:25:59 +0100
committerTor Lillqvist <tml@collabora.com>2016-02-09 08:41:03 +0000
commitad8d6d9ef53717e072005fe518ba8ded61e96711 (patch)
tree9681383d67e4ec4169ade0d91d413e0bb0dd9084
parent8455fe462a5a0e82ed2f98d303d36623b5920f9d (diff)
tdf#97666 -opengl: convert the bitmap to 8bit grays using GL shader
Change-Id: I4d48d29ab752814f71c697a201e70a26ae937775 Reviewed-on: https://gerrit.libreoffice.org/22223 Reviewed-by: Tor Lillqvist <tml@collabora.com> Tested-by: Tor Lillqvist <tml@collabora.com>
-rw-r--r--vcl/Package_opengl.mk1
-rw-r--r--vcl/inc/impbmp.hxx1
-rw-r--r--vcl/inc/opengl/salbmp.hxx1
-rw-r--r--vcl/inc/salbmp.hxx4
-rw-r--r--vcl/opengl/greyscaleFragmentShader.glsl18
-rw-r--r--vcl/opengl/salbmp.cxx36
-rw-r--r--vcl/source/gdi/bitmap3.cxx17
-rw-r--r--vcl/source/gdi/impbmp.cxx10
-rw-r--r--vcl/workben/vcldemo.cxx13
9 files changed, 101 insertions, 0 deletions
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index 9d4250279bd9..b8851df57625 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
blendedTextureVertexShader.glsl \
dumbVertexShader.glsl \
diffTextureFragmentShader.glsl \
+ greyscaleFragmentShader.glsl \
invert50FragmentShader.glsl \
convolutionFragmentShader.glsl \
linearGradientFragmentShader.glsl \
diff --git a/vcl/inc/impbmp.hxx b/vcl/inc/impbmp.hxx
index feb94a8d6fd3..5787b3f0f755 100644
--- a/vcl/inc/impbmp.hxx
+++ b/vcl/inc/impbmp.hxx
@@ -72,6 +72,7 @@ public:
bool ImplScale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag );
bool ImplReplace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol );
+ bool ImplConvert( BmpConversion eConversion );
};
#endif // INCLUDED_VCL_INC_IMPBMP_HXX
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index 98e09b3c16eb..7577f9f2c3c8 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -80,6 +80,7 @@ public:
bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) override;
bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) override;
+ bool ConvertToGreyscale() override;
public:
diff --git a/vcl/inc/salbmp.hxx b/vcl/inc/salbmp.hxx
index 574b11c79f1a..305f8a63f74d 100644
--- a/vcl/inc/salbmp.hxx
+++ b/vcl/inc/salbmp.hxx
@@ -69,6 +69,10 @@ public:
virtual bool Scale( const double& rScaleX, const double& rScaleY, BmpScaleFlag nScaleFlag ) = 0;
virtual bool Replace( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) = 0;
+ virtual bool ConvertToGreyscale()
+ {
+ return false;
+ }
void GetChecksum(ChecksumType& rChecksum) const
{
diff --git a/vcl/opengl/greyscaleFragmentShader.glsl b/vcl/opengl/greyscaleFragmentShader.glsl
new file mode 100644
index 000000000000..758109e98678
--- /dev/null
+++ b/vcl/opengl/greyscaleFragmentShader.glsl
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+varying vec2 tex_coord;
+uniform sampler2D sampler;
+
+void main() {
+ vec4 texel = texture2D(sampler, tex_coord);
+ gl_FragColor = vec4(vec3(dot(texel.rgb, vec3(0.301, 0.591, 0.108))), 1.0);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 703aedc10b98..683ca5fe5ac0 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -902,4 +902,40 @@ bool OpenGLSalBitmap::Replace( const Color& rSearchColor, const Color& rReplaceC
return true;
}
+// Convert texture to greyscale and adjust bitmap metadata
+bool OpenGLSalBitmap::ConvertToGreyscale()
+{
+ VCL_GL_INFO("::ConvertToGreyscale");
+
+ // avoid re-converting to 8bits.
+ if ( mnBits == 8 && maPalette == Bitmap::GetGreyPalette(256) )
+ return false;
+
+ OpenGLZone aZone;
+ rtl::Reference<OpenGLContext> xContext = OpenGLContext::getVCLContext();
+
+ OpenGLFramebuffer* pFramebuffer;
+ OpenGLProgram* pProgram;
+
+ GetTexture();
+ pProgram = xContext->UseProgram("textureVertexShader", "greyscaleFragmentShader");
+
+ if (!pProgram)
+ return false;
+
+ OpenGLTexture aNewTex(mnWidth, mnHeight);
+ pFramebuffer = xContext->AcquireFramebuffer(aNewTex);
+ pProgram->SetTexture("sampler", maTexture);
+ pProgram->DrawTexture(maTexture);
+ pProgram->Clean();
+
+ OpenGLContext::ReleaseFramebuffer( pFramebuffer );
+ maTexture = aNewTex;
+ mnBits = 8;
+ maPalette = Bitmap::GetGreyPalette(256);
+
+ CHECK_GL_ERROR();
+ return true;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/source/gdi/bitmap3.cxx b/vcl/source/gdi/bitmap3.cxx
index 9251af18a766..53dd598de1c2 100644
--- a/vcl/source/gdi/bitmap3.cxx
+++ b/vcl/source/gdi/bitmap3.cxx
@@ -244,6 +244,23 @@ void ImplCreateDitherMatrix( sal_uInt8 (*pDitherMatrix)[16][16] )
bool Bitmap::Convert( BmpConversion eConversion )
{
+ // try to convert in backend
+ if (mpImpBmp)
+ {
+ ImpBitmap* pImpBmp = new ImpBitmap;
+
+ if (pImpBmp->ImplCreate(*mpImpBmp) && pImpBmp->ImplConvert(eConversion))
+ {
+ ImplSetImpBitmap(pImpBmp);
+ SAL_INFO( "vcl.opengl", "Ref count: " << mpImpBmp->ImplGetRefCount() );
+ return true;
+ }
+ else
+ {
+ delete pImpBmp;
+ }
+ }
+
const sal_uInt16 nBitCount = GetBitCount ();
bool bRet = false;
diff --git a/vcl/source/gdi/impbmp.cxx b/vcl/source/gdi/impbmp.cxx
index ad1eca9515be..416fa29a3df0 100644
--- a/vcl/source/gdi/impbmp.cxx
+++ b/vcl/source/gdi/impbmp.cxx
@@ -115,4 +115,14 @@ bool ImpBitmap::ImplReplace( const Color& rSearchColor, const Color& rReplaceCol
return mpSalBitmap->Replace( rSearchColor, rReplaceColor, nTol );
}
+bool ImpBitmap::ImplConvert( BmpConversion eConversion )
+{
+ // avoid large chunk of obsolete and hopefully rarely used conversions.
+ if (eConversion != BMP_CONVERSION_8BIT_GREYS)
+ return false;
+
+ // frequently used conversion for creating alpha masks
+ return mpSalBitmap->ConvertToGreyscale();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/workben/vcldemo.cxx b/vcl/workben/vcldemo.cxx
index 889db52d08a9..3726e00b7dd1 100644
--- a/vcl/workben/vcldemo.cxx
+++ b/vcl/workben/vcldemo.cxx
@@ -1215,6 +1215,19 @@ public:
aBelow.Move(0,aResult.GetSizePixel().Height());
rDev.DrawBitmapEx(aBelow, aResult);
+ // mini convert test.
+ aBelow.Move(aResult.GetSizePixel().Width()+4,0);
+ rDev.DrawBitmapEx(aBelow, aResult);
+
+ Bitmap aGrey = aSrc.GetBitmap();
+ aGrey.Convert(BMP_CONVERSION_8BIT_GREYS);
+ rDev.DrawBitmap(aBelow, aGrey);
+
+ aBelow.Move(aGrey.GetSizePixel().Width(),0);
+ BitmapEx aGreyMask(aSrc.GetBitmap(),
+ AlphaMask(aSrc.GetMask()));
+ rDev.DrawBitmapEx(aBelow, aGreyMask);
+
aLocation.Move(aSrc.GetSizePixel().Width()*6,0);
if (aLocation.X() > r.Right())
aLocation = Point(0,aLocation.Y()+aSrc.GetSizePixel().Height()*3+4);