make ConvertBGRABufferToBitmapEx work properly also on non-win32
Windows uses GL_BGRA, but e.g. on Linux OpenGL stores as GL_RGBA. Change-Id: I00820f7b7a16a54b10c682ba332627ec04648508 Reviewed-on: https://gerrit.libreoffice.org/70772 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
This commit is contained in:
@@ -55,10 +55,15 @@ public:
|
|||||||
static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName);
|
static GLint LoadShaders(const OUString& rVertexShaderName, const OUString& rFragmentShaderName);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The caller is responsible for allocate the memory for the RGBA buffer, before call
|
* The caller is responsible for allocating the memory for the buffer before calling
|
||||||
* this method. RGBA buffer size is assumed to be 4*width*height.
|
* this method. The buffer size is assumed to be 4*width*height and the format
|
||||||
|
* to be OptimalBufferFormat().
|
||||||
**/
|
**/
|
||||||
static BitmapEx ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight);
|
static BitmapEx ConvertBufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight);
|
||||||
|
/**
|
||||||
|
* Returns the optimal buffer format for OpenGL (GL_BGRA or GL_RGBA).
|
||||||
|
**/
|
||||||
|
static GLenum OptimalBufferFormat();
|
||||||
static void renderToFile(long nWidth, long nHeight, const OUString& rFileName);
|
static void renderToFile(long nWidth, long nHeight, const OUString& rFileName);
|
||||||
|
|
||||||
static const char* GLErrorString(GLenum errorCode);
|
static const char* GLErrorString(GLenum errorCode);
|
||||||
|
@@ -498,8 +498,8 @@ void OpenGLTexture::Unbind()
|
|||||||
void OpenGLTexture::SaveToFile(const OUString& rFileName)
|
void OpenGLTexture::SaveToFile(const OUString& rFileName)
|
||||||
{
|
{
|
||||||
std::vector<sal_uInt8> aBuffer(GetWidth() * GetHeight() * 4);
|
std::vector<sal_uInt8> aBuffer(GetWidth() * GetHeight() * 4);
|
||||||
Read(GL_BGRA, GL_UNSIGNED_BYTE, aBuffer.data());
|
Read(OpenGLHelper::OptimalBufferFormat(), GL_UNSIGNED_BYTE, aBuffer.data());
|
||||||
BitmapEx aBitmap = OpenGLHelper::ConvertBGRABufferToBitmapEx(aBuffer.data(), GetWidth(), GetHeight());
|
BitmapEx aBitmap = OpenGLHelper::ConvertBufferToBitmapEx(aBuffer.data(), GetWidth(), GetHeight());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vcl::PNGWriter aWriter(aBitmap);
|
vcl::PNGWriter aWriter(aBitmap);
|
||||||
|
@@ -541,8 +541,8 @@ void OpenGLHelper::renderToFile(long nWidth, long nHeight, const OUString& rFile
|
|||||||
OpenGLZone aZone;
|
OpenGLZone aZone;
|
||||||
|
|
||||||
std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nWidth*nHeight*4]);
|
std::unique_ptr<sal_uInt8[]> pBuffer(new sal_uInt8[nWidth*nHeight*4]);
|
||||||
glReadPixels(0, 0, nWidth, nHeight, GL_BGRA, GL_UNSIGNED_BYTE, pBuffer.get());
|
glReadPixels(0, 0, nWidth, nHeight, OptimalBufferFormat(), GL_UNSIGNED_BYTE, pBuffer.get());
|
||||||
BitmapEx aBitmap = ConvertBGRABufferToBitmapEx(pBuffer.get(), nWidth, nHeight);
|
BitmapEx aBitmap = ConvertBufferToBitmapEx(pBuffer.get(), nWidth, nHeight);
|
||||||
try {
|
try {
|
||||||
vcl::PNGWriter aWriter( aBitmap );
|
vcl::PNGWriter aWriter( aBitmap );
|
||||||
SvFileStream sOutput( rFileName, StreamMode::WRITE );
|
SvFileStream sOutput( rFileName, StreamMode::WRITE );
|
||||||
@@ -555,7 +555,16 @@ void OpenGLHelper::renderToFile(long nWidth, long nHeight, const OUString& rFile
|
|||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
BitmapEx OpenGLHelper::ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight)
|
GLenum OpenGLHelper::OptimalBufferFormat()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return GL_BGRA; // OpenGLSalBitmap is internally ScanlineFormat::N24BitTcBgr
|
||||||
|
#else
|
||||||
|
return GL_RGBA; // OpenGLSalBitmap is internally ScanlineFormat::N24BitTcRgb
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapEx OpenGLHelper::ConvertBufferToBitmapEx(const sal_uInt8* const pBuffer, long nWidth, long nHeight)
|
||||||
{
|
{
|
||||||
assert(pBuffer);
|
assert(pBuffer);
|
||||||
Bitmap aBitmap( Size(nWidth, nHeight), 24 );
|
Bitmap aBitmap( Size(nWidth, nHeight), 24 );
|
||||||
@@ -564,12 +573,27 @@ BitmapEx OpenGLHelper::ConvertBGRABufferToBitmapEx(const sal_uInt8* const pBuffe
|
|||||||
{
|
{
|
||||||
BitmapScopedWriteAccess pWriteAccess( aBitmap );
|
BitmapScopedWriteAccess pWriteAccess( aBitmap );
|
||||||
AlphaScopedWriteAccess pAlphaWriteAccess( aAlpha );
|
AlphaScopedWriteAccess pAlphaWriteAccess( aAlpha );
|
||||||
|
#ifdef _WIN32
|
||||||
|
assert(pWriteAccess->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr);
|
||||||
|
assert(pWriteAccess->IsTopDown());
|
||||||
|
assert(pAlphaWriteAccess->IsTopDown());
|
||||||
|
#else
|
||||||
|
assert(pWriteAccess->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb);
|
||||||
|
assert(!pWriteAccess->IsTopDown());
|
||||||
|
assert(!pAlphaWriteAccess->IsTopDown());
|
||||||
|
#endif
|
||||||
|
assert(pAlphaWriteAccess->GetScanlineFormat() == ScanlineFormat::N8BitPal);
|
||||||
|
|
||||||
size_t nCurPos = 0;
|
size_t nCurPos = 0;
|
||||||
for( long y = 0; y < nHeight; ++y)
|
for( long y = 0; y < nHeight; ++y)
|
||||||
{
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
Scanline pScan = pWriteAccess->GetScanline(y);
|
Scanline pScan = pWriteAccess->GetScanline(y);
|
||||||
Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(y);
|
Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(y);
|
||||||
|
#else
|
||||||
|
Scanline pScan = pWriteAccess->GetScanline(nHeight-1-y);
|
||||||
|
Scanline pAlphaScan = pAlphaWriteAccess->GetScanline(nHeight-1-y);
|
||||||
|
#endif
|
||||||
for( long x = 0; x < nWidth; ++x )
|
for( long x = 0; x < nWidth; ++x )
|
||||||
{
|
{
|
||||||
*pScan++ = pBuffer[nCurPos];
|
*pScan++ = pBuffer[nCurPos];
|
||||||
|
Reference in New Issue
Block a user