diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-03-15 14:18:06 +0200 |
---|---|---|
committer | Michael Meeks <michael.meeks@collabora.com> | 2018-03-15 20:22:28 +0100 |
commit | bd594ac19aac89a31243e8b4bd043e1d614daa7a (patch) | |
tree | ae3626fc78fde71c01ed03ec5c4e5dcacf9a3779 | |
parent | 4defe28e5f28a68a23317e1d50c51d29cf58226e (diff) |
move swffilter use of BitmapEx::GetAlpha inside vcl
Change-Id: I22f489a26b8566ddc00c0c77f95127adb8eb2489
Reviewed-on: https://gerrit.libreoffice.org/51324
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Jenkins <ci@libreoffice.org>
-rw-r--r-- | filter/source/flash/swfwriter1.cxx | 87 | ||||
-rw-r--r-- | include/vcl/bitmapex.hxx | 5 | ||||
-rw-r--r-- | vcl/source/gdi/bitmapex.cxx | 63 |
3 files changed, 80 insertions, 75 deletions
diff --git a/filter/source/flash/swfwriter1.cxx b/filter/source/flash/swfwriter1.cxx index 09ed4f647efc..57923f8dbd13 100644 --- a/filter/source/flash/swfwriter1.cxx +++ b/filter/source/flash/swfwriter1.cxx @@ -694,71 +694,6 @@ void Writer::Impl_writeText( const Point& rPos, const OUString& rText, const lon } } -// AS: Because JPEGs require the alpha channel provided separately (JPEG does not -// natively support alpha channel, but SWF lets you provide it separately), we -// extract the alpha channel into a separate array here. -void getBitmapData( const BitmapEx& aBmpEx, sal_uInt8*& tgadata, sal_uInt8*& tgaAlphadata, sal_uInt32& nWidth, sal_uInt32& nHeight ) -{ - if( !aBmpEx.IsEmpty() ) - { - Bitmap aBmp( aBmpEx.GetBitmap() ); - Bitmap::ScopedReadAccess pRAcc(aBmp); - - if( pRAcc ) - { - AlphaMask aAlpha; - nWidth = pRAcc->Width(); - nHeight = pRAcc->Height(); - tgadata = new sal_uInt8[nWidth*nHeight*4]; - tgaAlphadata = new sal_uInt8[nWidth*nHeight]; - sal_uInt8* p = tgadata, *pAlpha = tgaAlphadata; - - - if( aBmpEx.IsAlpha() ) - aAlpha = aBmpEx.GetAlpha(); - else if( aBmpEx.IsTransparent() ) - aAlpha = aBmpEx.GetMask(); - else - { - sal_uInt8 cAlphaVal = 0; - aAlpha = AlphaMask( aBmp.GetSizePixel(), &cAlphaVal ); - } - - AlphaMask::ScopedReadAccess pAAcc(aAlpha); - - if( pAAcc ) - { - for( sal_uInt32 nY = 0; nY < nHeight; nY++ ) - { - Scanline pScanlineAA = pAAcc->GetScanline( nY ); - for( sal_uInt32 nX = 0; nX < nWidth; nX++ ) - { - const sal_uInt8 nAlpha = pAAcc->GetIndexFromData( pScanlineAA, nX ); - const BitmapColor aPixelColor( pRAcc->GetColor( nY, nX ) ); - - if( nAlpha == 0xff ) - { - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - } - else - { - *p++ = 0xff-nAlpha; - *p++ = aPixelColor.GetRed(); - *p++ = aPixelColor.GetGreen(); - *p++ = aPixelColor.GetBlue(); - } - *pAlpha++ = 0xff - nAlpha; - } - } - } - } - } -} - - sal_uInt16 Writer::defineBitmap( const BitmapEx &bmpSource, sal_Int32 nJPEGQualityLevel ) { BitmapChecksum bmpChecksum = bmpSource.GetChecksum(); @@ -776,21 +711,22 @@ sal_uInt16 Writer::defineBitmap( const BitmapEx &bmpSource, sal_Int32 nJPEGQuali // or Lossless compress it. // Figure out lossless size - sal_uInt8 *pImageData, *pAlphaData; - sal_uInt32 width(0), height(0); + std::vector<sal_uInt8> aImageData, aAlphaData; - getBitmapData( bmpSource, pImageData, pAlphaData, width, height ); + sal_uInt32 width = bmpSource.GetPrefSize().Width(); + sal_uInt32 height = bmpSource.GetPrefSize().Height(); + bmpSource.GetSplitData(aImageData, aAlphaData ); sal_uInt32 raw_size = width * height * 4; uLongf compressed_size = raw_size + static_cast<sal_uInt32>(raw_size/100) + 12; std::unique_ptr<sal_uInt8[]> pCompressed(new sal_uInt8[ compressed_size ]); #ifdef DBG_UTIL - if(compress2(pCompressed.get(), &compressed_size, pImageData, raw_size, Z_BEST_COMPRESSION) != Z_OK) + if(compress2(pCompressed.get(), &compressed_size, aImageData.data(), raw_size, Z_BEST_COMPRESSION) != Z_OK) { SAL_WARN( "filter.flash", "compress2 failed!" ); ((void)0); } #else - compress2(pCompressed.get(), &compressed_size, pImageData, raw_size, Z_BEST_COMPRESSION); + compress2(pCompressed.get(), &compressed_size, aImageData.data(), raw_size, Z_BEST_COMPRESSION); #endif // AS: SWF files let you provide an Alpha mask for JPEG images, but we have @@ -803,15 +739,19 @@ sal_uInt16 Writer::defineBitmap( const BitmapEx &bmpSource, sal_Int32 nJPEGQuali pAlphaCompressed.reset(new sal_uInt8[ compressed_size ]); #ifdef DBG_UTIL - if(compress2(pAlphaCompressed.get(), &alpha_compressed_size, pAlphaData, width * height, Z_BEST_COMPRESSION) != Z_OK) + if(compress2(pAlphaCompressed.get(), &alpha_compressed_size, aAlphaData.data(), width * height, Z_BEST_COMPRESSION) != Z_OK) { SAL_WARN( "filter.flash", "compress2 failed!" ); ((void)0); } #else - compress2(pAlphaCompressed.get(), &alpha_compressed_size, pAlphaData, width * height, Z_BEST_COMPRESSION); + compress2(pAlphaCompressed.get(), &alpha_compressed_size, aAlphaData.data(), width * height, Z_BEST_COMPRESSION); #endif } + // clear these early for less peak memory usage + aImageData.resize(0); + aAlphaData.resize(0); + // Figure out JPEG size const sal_uInt8* pJpgData = nullptr; sal_uInt32 nJpgDataLength = 0xffffffff; @@ -843,9 +783,6 @@ sal_uInt16 Writer::defineBitmap( const BitmapEx &bmpSource, sal_Int32 nJPEGQuali else Impl_writeBmp( nBitmapId, width, height, pCompressed.get(), compressed_size ); - delete[] pImageData; - delete[] pAlphaData; - return nBitmapId; } diff --git a/include/vcl/bitmapex.hxx b/include/vcl/bitmapex.hxx index 9ab88686df36..4876180e10c4 100644 --- a/include/vcl/bitmapex.hxx +++ b/include/vcl/bitmapex.hxx @@ -95,6 +95,11 @@ public: public: + /** + * @brief extract the bitmap and alpha data separately. Used by the SWF filter. + */ + void GetSplitData( std::vector<sal_uInt8>& rvColorData, std::vector<sal_uInt8>& rvAlphaData ) const; + /** Convert bitmap format @param eConversion diff --git a/vcl/source/gdi/bitmapex.cxx b/vcl/source/gdi/bitmapex.cxx index 07d5d19e7869..1dcc72befeaf 100644 --- a/vcl/source/gdi/bitmapex.cxx +++ b/vcl/source/gdi/bitmapex.cxx @@ -1378,4 +1378,67 @@ void BitmapEx::AdjustTransparency(sal_uInt8 cTrans) } *this = BitmapEx( GetBitmap(), aAlpha ); } + +// AS: Because JPEGs require the alpha channel provided separately (JPEG does not +// natively support alpha channel, but SWF lets you provide it separately), we +// extract the alpha channel into a separate array here. +void BitmapEx::GetSplitData( std::vector<sal_uInt8>& rvColorData, std::vector<sal_uInt8>& rvAlphaData ) const +{ + if( IsEmpty() ) + return; + + Bitmap aBmp( GetBitmap() ); + Bitmap::ScopedReadAccess pRAcc(aBmp); + + assert( pRAcc ); + + AlphaMask aAlpha; + sal_uInt32 nWidth = pRAcc->Width(); + sal_uInt32 nHeight = pRAcc->Height(); + rvColorData.resize(nWidth*nHeight*4); + rvAlphaData.resize(nWidth*nHeight); + sal_uInt8* p = rvColorData.data(), *pAlpha = rvAlphaData.data(); + + + if( IsAlpha() ) + aAlpha = GetAlpha(); + else if( IsTransparent() ) + aAlpha = GetMask(); + else + { + sal_uInt8 cAlphaVal = 0; + aAlpha = AlphaMask( aBmp.GetSizePixel(), &cAlphaVal ); + } + + AlphaMask::ScopedReadAccess pAAcc(aAlpha); + + assert( pAAcc ); + + for( sal_uInt32 nY = 0; nY < nHeight; nY++ ) + { + Scanline pScanlineAA = pAAcc->GetScanline( nY ); + for( sal_uInt32 nX = 0; nX < nWidth; nX++ ) + { + const sal_uInt8 nAlpha = pAAcc->GetIndexFromData( pScanlineAA, nX ); + const BitmapColor aPixelColor( pRAcc->GetColor( nY, nX ) ); + + if( nAlpha == 0xff ) + { + *p++ = 0; + *p++ = 0; + *p++ = 0; + *p++ = 0; + } + else + { + *p++ = 0xff-nAlpha; + *p++ = aPixelColor.GetRed(); + *p++ = aPixelColor.GetGreen(); + *p++ = aPixelColor.GetBlue(); + } + *pAlpha++ = 0xff - nAlpha; + } + } +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |