diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-02-13 13:41:55 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2018-02-14 07:29:01 +0100 |
commit | 6b4d3815a612b688cc5714f8b828a9cc9b109429 (patch) | |
tree | 87ee64a86a8af3bbff113fe1a41d35d4121857c7 /filter | |
parent | use RawBitmap in PSDReader (diff) | |
download | core-6b4d3815a612b688cc5714f8b828a9cc9b109429.tar.gz core-6b4d3815a612b688cc5714f8b828a9cc9b109429.zip |
use BitmapTools in TIFFReader
part of making Bitmap an internal detail of vcl.
This one is a little trickier because it constructs the palette after it
reads the pixel data, so I couldn't use RawBitmap
Change-Id: I2f501260beebb541ee451e78d551e13f182a01b1
Reviewed-on: https://gerrit.libreoffice.org/49665
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'filter')
-rw-r--r-- | filter/source/graphicfilter/itiff/itiff.cxx | 199 |
1 files changed, 106 insertions, 93 deletions
diff --git a/filter/source/graphicfilter/itiff/itiff.cxx b/filter/source/graphicfilter/itiff/itiff.cxx index 0449cdff7e2b..d86d2912804d 100644 --- a/filter/source/graphicfilter/itiff/itiff.cxx +++ b/filter/source/graphicfilter/itiff/itiff.cxx @@ -22,7 +22,7 @@ #include <vcl/FilterConfigItem.hxx> #include <vcl/graph.hxx> -#include <vcl/bitmapaccess.hxx> +#include <vcl/BitmapTools.hxx> #include <vcl/animate.hxx> #include <tools/fract.hxx> #include "lzwdecom.hxx" @@ -50,13 +50,13 @@ private: Animation aAnimation; SvStream* pTIFF; // the TIFF file that should be read - Bitmap aBitmap; - Bitmap::ScopedWriteAccess xAcc; + std::unique_ptr<sal_uInt8[]> mpBitmap; + Size maBitmapPixelSize; + std::vector<Color> mvPalette; + MapMode maBitmapPrefMapMode; + Size maBitmapPrefSize; sal_uInt16 nDstBitsPerPixel; int nLargestPixelIndex; - std::unique_ptr<AlphaMask> - pAlphaMask; - AlphaMask::ScopedWriteAccess xMaskAcc; sal_uInt64 nOrigPos; // start position in pTIFF sal_uInt64 nEndOfFile; // end of file position in pTIFF @@ -124,7 +124,9 @@ private: bool HasAlphaChannel() const; - void SetPixelOnData(BitmapWriteAccess *pWriteAcc, sal_uInt8* pData, long nX, sal_uInt8 cIndex); + void SetPixel(long nY, long nX, sal_uInt8 cIndex); + void SetPixel(long nY, long nX, Color c); + void SetPixelAlpha(long nY, long nX, sal_uInt8 nAlpha); public: @@ -133,7 +135,6 @@ public: , pTIFF(nullptr) , nDstBitsPerPixel(0) , nLargestPixelIndex(-1) - , pAlphaMask(nullptr) , nOrigPos(0) , nEndOfFile(0) , nDataType(0) @@ -616,9 +617,9 @@ bool TIFFReader::ReadMap() //if the buffer for this line didn't change, then just copy the //previous scanline instead of painfully decoding and setting //each pixel one by one again - Scanline pScanline = xAcc->GetScanline(ny); - Scanline pPrevline = xAcc->GetScanline(ny-1); - memcpy(pScanline, pPrevline, xAcc->GetScanlineSize()); + memcpy( mpBitmap.get() + (ny * maBitmapPixelSize.Width()) * 4, + mpBitmap.get() + ((ny-1) * maBitmapPixelSize.Width()) * 4, + maBitmapPixelSize.Width() * 4); } else { @@ -780,20 +781,38 @@ sal_uInt32 TIFFReader::GetBits( const sal_uInt8 * pSrc, sal_uInt32 nBitsPos, sal return nRes; } -void TIFFReader::SetPixelOnData(BitmapWriteAccess *pWriteAcc, sal_uInt8* pData, long nX, sal_uInt8 cIndex) +void TIFFReader::SetPixel(long nY, long nX, sal_uInt8 cIndex) { - pWriteAcc->SetPixelOnData(pData, nX, BitmapColor(cIndex)); + mpBitmap[(maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3)] = cIndex; nLargestPixelIndex = std::max<int>(nLargestPixelIndex, cIndex); } +void TIFFReader::SetPixel(long nY, long nX, Color c) +{ + auto p = mpBitmap.get() + ((maBitmapPixelSize.Width() * nY + nX) * (HasAlphaChannel() ? 4 : 3)); + *p = c.GetRed(); + p++; + *p = c.GetGreen(); + p++; + *p = c.GetBlue(); + if (HasAlphaChannel()) + { + p++; + *p = 0xff; // alpha + } +} + +void TIFFReader::SetPixelAlpha(long nY, long nX, sal_uInt8 nAlpha) +{ + assert(HasAlphaChannel()); + mpBitmap[((maBitmapPixelSize.Width() * nY + nX) * 4) + 3] = nAlpha; +} + bool TIFFReader::ConvertScanline(sal_Int32 nY) { sal_uInt32 nRed, nGreen, nBlue, ns, nVal; sal_uInt8 nByteVal; - BitmapWriteAccess* pAcc = xAcc.get(); - Scanline pScanLine = pAcc->GetScanline(nY); - if ( nDstBitsPerPixel == 24 ) { if ( nBitsPerSample == 8 && nSamplesPerPixel >= 3 && @@ -801,10 +820,6 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) { sal_uInt8* pt = getMapData(0); - Scanline pMaskScanLine = nullptr; - if (nSamplesPerPixel >= 4 && xMaskAcc) - pMaskScanLine = xMaskAcc->GetScanline(nY); - // are the values being saved as difference? if ( 2 == nPredictor ) { @@ -817,11 +832,11 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) nLRed = nLRed + pt[ 0 ]; nLGreen = nLGreen + pt[ 1 ]; nLBlue = nLBlue + pt[ 2 ]; - pAcc->SetPixelOnData(pScanLine, nx, Color(nLRed, nLGreen, nLBlue)); - if (pMaskScanLine) + SetPixel(nY, nx, Color(nLRed, nLGreen, nLBlue)); + if (HasAlphaChannel()) { nLAlpha = nLAlpha + pt[ 3 ]; - xMaskAcc->SetPixelOnData(pMaskScanLine, nx, BitmapColor(~nLAlpha)); + SetPixelAlpha(nY, nx, ~nLAlpha); } } } @@ -829,11 +844,11 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) { for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += nSamplesPerPixel) { - pAcc->SetPixelOnData(pScanLine, nx, Color(pt[0], pt[1], pt[2])); - if (pMaskScanLine) + SetPixel(nY, nx, Color(pt[0], pt[1], pt[2])); + if (HasAlphaChannel()) { sal_uInt8 nAlpha = pt[3]; - xMaskAcc->SetPixelOnData(pMaskScanLine, nx, BitmapColor(~nAlpha)); + SetPixelAlpha(nY, nx, ~nAlpha); } } } @@ -857,7 +872,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) nGreen = GetBits( getMapData(1), nx * nBitsPerSample, nBitsPerSample ); nBlue = GetBits( getMapData(2), nx * nBitsPerSample, nBitsPerSample ); } - pAcc->SetPixelOnData(pScanLine, nx, Color(static_cast<sal_uInt8>(nRed - nMinMax), static_cast<sal_uInt8>(nGreen - nMinMax), static_cast<sal_uInt8>(nBlue - nMinMax))); + SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed - nMinMax), static_cast<sal_uInt8>(nGreen - nMinMax), static_cast<sal_uInt8>(nBlue - nMinMax))); } } } @@ -883,7 +898,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) nRed = 255 - static_cast<sal_uInt8>( nRed - nMinMax ); nGreen = 255 - static_cast<sal_uInt8>( nGreen - nMinMax ); nBlue = 255 - static_cast<sal_uInt8>( nBlue - nMinMax ); - pAcc->SetPixelOnData(pScanLine, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue))); + SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue))); } } } @@ -925,7 +940,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) )); nBlue = static_cast<sal_uInt8>(std::max( 0L, 255L - ( ( static_cast<sal_Int32>(nSamp[ 2 ]) + nBlack - ( static_cast<sal_Int32>(nMinSampleValue) << 1 ) ) * 255L/static_cast<sal_Int32>(nMaxSampleValue-nMinSampleValue) ) )); - pAcc->SetPixelOnData(pScanLine, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue))); + SetPixel(nY, nx, Color(static_cast<sal_uInt8>(nRed), static_cast<sal_uInt8>(nGreen), static_cast<sal_uInt8>(nBlue))); } } } @@ -954,7 +969,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) { nLast += nx == 0 ? BYTESWAP( *pt++ ) : *pt++; - SetPixelOnData(pAcc, pScanLine, nx, nLast); + SetPixel(nY, nx, nLast); } } else @@ -962,7 +977,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) { sal_uInt8 nLast = *pt++; - SetPixelOnData(pAcc, pScanLine, nx, static_cast<sal_uInt8>( (BYTESWAP(static_cast<sal_uInt32>(nLast)) - nMinSampleValue) * nMinMax )); + SetPixel(nY, nx, static_cast<sal_uInt8>( (BYTESWAP(static_cast<sal_uInt32>(nLast)) - nMinSampleValue) * nMinMax )); } } } @@ -974,14 +989,14 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) { nLast += *pt++; - SetPixelOnData(pAcc, pScanLine, nx, nLast); + SetPixel(nY, nx, nLast); } } else { for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) { - SetPixelOnData(pAcc, pScanLine, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt++) - nMinSampleValue) * nMinMax )); + SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt++) - nMinSampleValue) * nMinMax )); } } } @@ -998,7 +1013,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) for (sal_Int32 nx = 0; nx < nImageWidth; ++nx) { nVal = ( GetBits( pt, nx * nBitsPerSample, nBitsPerSample ) - nMinSampleValue ) * nMinMax; - SetPixelOnData(pAcc, pScanLine, nx, static_cast<sal_uInt8>(nVal)); + SetPixel(nY, nx, static_cast<sal_uInt8>(nVal)); } } break; @@ -1019,28 +1034,28 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) while (nByteCount--) { nByteVal = *pt++; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal); + SetPixel(nY, nx++, nByteVal); } if ( nImageWidth & 7 ) { nByteVal = *pt++; while ( nx < nImageWidth ) { - SetPixelOnData(pAcc, pScanLine, nx++, nByteVal & 1); + SetPixel(nY, nx++, nByteVal & 1); nByteVal >>= 1; } } @@ -1051,21 +1066,21 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) while (nByteCount--) { nByteVal = *pt++; - SetPixelOnData(pAcc, pScanLine, nx, nByteVal & 1); + SetPixel(nY, nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal & 1); + SetPixel(nY, --nx, nByteVal & 1); nByteVal >>= 1; - SetPixelOnData(pAcc, pScanLine, --nx, nByteVal); + SetPixel(nY, --nx, nByteVal); nx += 15; } if ( nImageWidth & 7 ) @@ -1075,7 +1090,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) nShift = 7; while ( nx < nImageWidth ) { - SetPixelOnData(pAcc, pScanLine, nx++, ( nByteVal >> nShift ) & 1); + SetPixel(nY, nx++, ( nByteVal >> nShift ) & 1); } } } @@ -1096,7 +1111,7 @@ bool TIFFReader::ConvertScanline(sal_Int32 nY) sal_uInt8* pt = getMapData(0); for (sal_Int32 nx = 0; nx < nImageWidth; nx++, pt += 2 ) { - SetPixelOnData(pAcc, pScanLine, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt) - nMinSampleValue) * nMinMax)); + SetPixel(nY, nx, static_cast<sal_uInt8>( (static_cast<sal_uInt32>(*pt) - nMinSampleValue) * nMinMax)); } } } @@ -1133,11 +1148,11 @@ void TIFFReader::MakePalCol() aColorMap[nNumColors - i - 1] = n0RGB; } } - xAcc->SetPaletteEntryCount(std::max<sal_uInt16>(nNumColors, xAcc->GetPaletteEntryCount())); + mvPalette.resize(std::max<sal_uInt16>(nNumColors, mvPalette.size())); for (sal_uInt32 i = 0; i < nNumColors; ++i) { - xAcc->SetPaletteColor(i, BitmapColor( static_cast<sal_uInt8>( aColorMap[ i ] >> 16 ), - static_cast<sal_uInt8>( aColorMap[ i ] >> 8 ), static_cast<sal_uInt8>(aColorMap[ i ]) ) ); + mvPalette[i] = Color( static_cast<sal_uInt8>( aColorMap[ i ] >> 16 ), + static_cast<sal_uInt8>( aColorMap[ i ] >> 8 ), static_cast<sal_uInt8>(aColorMap[ i ]) ); } } @@ -1155,8 +1170,8 @@ void TIFFReader::MakePalCol() nRY=static_cast<sal_uInt32>(fYResolution*2.54+0.5); } MapMode aMapMode(MapUnit::MapInch,Point(0,0),Fraction(1,nRX),Fraction(1,nRY)); - aBitmap.SetPrefMapMode(aMapMode); - aBitmap.SetPrefSize(Size(nImageWidth,nImageLength)); + maBitmapPrefMapMode = aMapMode; + maBitmapPrefSize = Size(nImageWidth,nImageLength); } } @@ -1302,7 +1317,6 @@ bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) nPredictor = 1; nNumColors = 0; - xAcc.reset(); aStripOffsets.clear(); aStripByteCounts.clear(); for (auto& j : aMap) @@ -1506,44 +1520,43 @@ bool TIFFReader::ReadTIFF(SvStream & rTIFF, Graphic & rGraphic ) if ( bStatus ) { - pAlphaMask.reset(); - Size aTargetSize(nImageWidth, nImageLength); - aBitmap = Bitmap(aTargetSize, nDstBitsPerPixel); - xAcc = Bitmap::ScopedWriteAccess(aBitmap); - if (xAcc && xAcc->Width() == nImageWidth && xAcc->Height() == nImageLength) - { - if (bStatus && HasAlphaChannel()) - { - pAlphaMask.reset( new AlphaMask( aTargetSize ) ); - xMaskAcc = AlphaMask::ScopedWriteAccess(*pAlphaMask); - } + maBitmapPixelSize = Size(nImageWidth, nImageLength); + mpBitmap.reset(new sal_uInt8[nImageWidth * nImageLength * (HasAlphaChannel() ? 4 : 3)]); - if (bStatus && ReadMap()) - { - nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); - MakePalCol(); - nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); - } - else - bStatus = false; - - xAcc.reset(); - xMaskAcc.reset(); - - if ( bStatus ) - { - BitmapEx aImage; + if (bStatus && ReadMap()) + { + nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); + MakePalCol(); + nMaxPos = std::max( pTIFF->Tell(), nMaxPos ); + // convert palette-ized images to 24-bit color + if (!mvPalette.empty()) + for (long nY = 0; nY < nImageLength; ++nY) + for (long nX = 0; nX < nImageWidth; ++nX) + { + auto p = mpBitmap.get() + ((maBitmapPixelSize.Width() * nY + nX) * 3); + auto c = mvPalette[*p]; + *p = c.GetRed(); + p++; + *p = c.GetGreen(); + p++; + *p = c.GetBlue(); + } + } + else + bStatus = false; - if (pAlphaMask) - aImage = BitmapEx( aBitmap, *pAlphaMask ); - else - aImage = aBitmap; + if ( bStatus ) + { + BitmapEx aImage = vcl::bitmap::CreateFromData(mpBitmap.get(), nImageWidth, nImageLength, + nImageWidth * (HasAlphaChannel() ? 4 : 3), // scanline bytes + HasAlphaChannel() ? 32 : 24); + aImage.SetPrefMapMode(maBitmapPrefMapMode); + aImage.SetPrefSize(maBitmapPrefSize); - AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), aBitmap.GetSizePixel(), - ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back ); + AnimationBitmap aAnimationBitmap( aImage, Point( 0, 0 ), maBitmapPixelSize, + ANIMATION_TIMEOUT_ON_CLICK, Disposal::Back ); - aAnimation.Insert( aAnimationBitmap ); - } + aAnimation.Insert( aAnimationBitmap ); } } |