diff options
Diffstat (limited to 'vcl/source/filter/jpeg/JpegReader.cxx')
-rw-r--r-- | vcl/source/filter/jpeg/JpegReader.cxx | 214 |
1 files changed, 37 insertions, 177 deletions
diff --git a/vcl/source/filter/jpeg/JpegReader.cxx b/vcl/source/filter/jpeg/JpegReader.cxx index 8959e4e8bd99..cd00518dcf44 100644 --- a/vcl/source/filter/jpeg/JpegReader.cxx +++ b/vcl/source/filter/jpeg/JpegReader.cxx @@ -178,9 +178,6 @@ void jpeg_svstream_src (j_decompress_ptr cinfo, void* input) JPEGReader::JPEGReader( SvStream& rStream, void* /*pCallData*/, bool bSetLogSize ) : mrStream ( rStream ), - mpAcc ( nullptr ), - mpAcc1 ( nullptr ), - mpBuffer ( nullptr ), mnLastPos ( rStream.Tell() ), mnLastLines ( 0 ), mbSetLogSize ( bSetLogSize ) @@ -191,46 +188,32 @@ JPEGReader::JPEGReader( SvStream& rStream, void* /*pCallData*/, bool bSetLogSize JPEGReader::~JPEGReader() { - delete[] mpBuffer; - - if( mpAcc ) - Bitmap::ReleaseAccess( mpAcc ); - - if( mpAcc1 ) - Bitmap::ReleaseAccess( mpAcc1 ); } -unsigned char * JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam) +bool JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam) { if (rParam.nWidth > SAL_MAX_INT32 / 8 || rParam.nHeight > SAL_MAX_INT32 / 8) - return nullptr; // avoid overflows later + return false; // avoid overflows later if (rParam.nWidth == 0 || rParam.nHeight == 0) - return nullptr; + return false; - Size aSize(rParam.nWidth, rParam.nHeight ); - bool bGray = rParam.bGray != 0; + Size aSize(rParam.nWidth, rParam.nHeight); + bool bGray = rParam.bGray; - unsigned char * pBmpBuf = nullptr; + maBitmap = Bitmap(); - if( mpAcc ) - { - Bitmap::ReleaseAccess( mpAcc ); - maBmp = Bitmap(); - mpAcc = nullptr; - } + sal_uInt64 nSize = aSize.Width() * aSize.Height(); - sal_uInt64 nSize = aSize.Width(); - nSize *= aSize.Height(); if (nSize > SAL_MAX_INT32 / (bGray?1:3)) - return nullptr; + return false; // Check if the bitmap is atypically large. if (nSize*(bGray?1:3) > MAX_BITMAP_BYTE_SIZE) { // Do not try to acquire resources for the large bitmap or to // read the bitmap into memory. - return nullptr; + return false; } if( bGray ) @@ -243,18 +226,18 @@ unsigned char * JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam) aGrayPal[ n ] = BitmapColor( cGray, cGray, cGray ); } - maBmp = Bitmap( aSize, 8, &aGrayPal ); + maBitmap = Bitmap(aSize, 8, &aGrayPal); } else { - maBmp = Bitmap( aSize, 24 ); + maBitmap = Bitmap(aSize, 24); } - if ( mbSetLogSize ) + if (mbSetLogSize) { unsigned long nUnit = rParam.density_unit; - if( ( ( 1 == nUnit ) || ( 2 == nUnit ) ) && rParam.X_density && rParam.Y_density ) + if (((1 == nUnit) || (2 == nUnit)) && rParam.X_density && rParam.Y_density ) { Point aEmptyPoint; Fraction aFractX( 1, rParam.X_density ); @@ -262,161 +245,48 @@ unsigned char * JPEGReader::CreateBitmap(JPEGCreateBitmapParam& rParam) MapMode aMapMode( nUnit == 1 ? MAP_INCH : MAP_CM, aEmptyPoint, aFractX, aFractY ); Size aPrefSize = OutputDevice::LogicToLogic( aSize, aMapMode, MAP_100TH_MM ); - maBmp.SetPrefSize( aPrefSize ); - maBmp.SetPrefMapMode( MapMode( MAP_100TH_MM ) ); + maBitmap.SetPrefSize(aPrefSize); + maBitmap.SetPrefMapMode(MapMode(MAP_100TH_MM)); } } - mpAcc = maBmp.AcquireWriteAccess(); - - if( mpAcc ) - { - const ScanlineFormat nFormat = mpAcc->GetScanlineFormat(); - - if( - ( bGray && ( ScanlineFormat::N8BitPal == nFormat ) ) || - ( !bGray && ( ScanlineFormat::N24BitTcRgb == nFormat ) ) - ) - { - pBmpBuf = mpAcc->GetBuffer(); - rParam.nAlignedWidth = mpAcc->GetScanlineSize(); - rParam.bTopDown = mpAcc->IsTopDown(); - } - else - { - rParam.nAlignedWidth = AlignedWidth4Bytes( aSize.Width() * ( bGray ? 8 : 24 ) ); - rParam.bTopDown = true; - pBmpBuf = mpBuffer = new unsigned char[rParam.nAlignedWidth * aSize.Height()]; - } - } - - // clean up, if no Bitmap buffer can be provided. - if ( !pBmpBuf ) - { - Bitmap::ReleaseAccess( mpAcc ); - maBmp = Bitmap(); - mpAcc = nullptr; - } - - return pBmpBuf; -} - -void JPEGReader::FillBitmap() -{ - if( mpBuffer && mpAcc ) - { - unsigned char * pTmp; - BitmapColor aColor; - long nAlignedWidth; - long nWidth = mpAcc->Width(); - long nHeight = mpAcc->Height(); - - if( mpAcc->GetBitCount() == 8 ) - { - std::unique_ptr<BitmapColor[]> pCols(new BitmapColor[ 256 ]); - - for( sal_uInt16 n = 0; n < 256; n++ ) - { - const sal_uInt8 cGray = (sal_uInt8) n; - pCols[ n ] = mpAcc->GetBestMatchingColor( BitmapColor( cGray, cGray, cGray ) ); - } - - nAlignedWidth = AlignedWidth4Bytes( mpAcc->Width() * 8L ); - - for( long nY = 0L; nY < nHeight; nY++ ) - { - pTmp = mpBuffer + nY * nAlignedWidth; - - for( long nX = 0L; nX < nWidth; nX++ ) - { - mpAcc->SetPixel( nY, nX, pCols[ *pTmp++ ] ); - } - } - } - else - { - nAlignedWidth = AlignedWidth4Bytes( mpAcc->Width() * 24L ); - - for( long nY = 0L; nY < nHeight; nY++ ) - { - // #i122985# Added fast-lane implementations using CopyScanline with direct supported mem formats - static bool bCheckOwnReader(true); - - if(bCheckOwnReader) - { - // #i122985# Trying to copy the RGB data from jpeg import to make things faster. Unfortunately - // it has no GBR format, so RGB three-byte groups need to be 'flipped' to GBR first, - // then CopyScanline can use a memcpy to do the data transport. CopyScanline can also - // do the needed conversion from ScanlineFormat::N24BitTcRgb (and it works well), but this - // is not faster that the old loop below using SetPixel. - sal_uInt8* aSource(mpBuffer + nY * nAlignedWidth); - sal_uInt8* aEnd(aSource + (nWidth * 3)); - - for(sal_uInt8* aTmp(aSource); aTmp < aEnd; aTmp += 3) - { - ::std::swap(*aTmp, *(aTmp + 2)); - } - - mpAcc->CopyScanline(nY, aSource, ScanlineFormat::N24BitTcBgr, nWidth * 3); - } - else - { - // old version: WritePixel - pTmp = mpBuffer + nY * nAlignedWidth; - - for( long nX = 0L; nX < nWidth; nX++ ) - { - aColor.SetRed( *pTmp++ ); - aColor.SetGreen( *pTmp++ ); - aColor.SetBlue( *pTmp++ ); - mpAcc->SetPixel( nY, nX, aColor ); - } - } - } - } - } + return true; } -Graphic JPEGReader::CreateIntermediateGraphic( const Bitmap& rBitmap, long nLines ) +Graphic JPEGReader::CreateIntermediateGraphic(long nLines) { - Graphic aGraphic; - const Size aSizePixel( rBitmap.GetSizePixel() ); + Graphic aGraphic; + const Size aSizePixel(maBitmap.GetSizePixel()); - if( !mnLastLines ) + if (!mnLastLines) { - if( mpAcc1 ) - { - Bitmap::ReleaseAccess( mpAcc1 ); - } - - maBmp1 = Bitmap( rBitmap.GetSizePixel(), 1 ); - maBmp1.Erase( Color( COL_WHITE ) ); - mpAcc1 = maBmp1.AcquireWriteAccess(); + maIncompleteAlpha = Bitmap(aSizePixel, 1); + maIncompleteAlpha.Erase(Color(COL_WHITE)); } - if( nLines && ( nLines < aSizePixel.Height() ) ) + if (nLines && (nLines < aSizePixel.Height())) { - if( mpAcc1 ) - { - const long nNewLines = nLines - mnLastLines; + const long nNewLines = nLines - mnLastLines; - if( nNewLines ) + if (nNewLines > 0) + { { - mpAcc1->SetFillColor( Color( COL_BLACK ) ); - mpAcc1->FillRect( Rectangle( Point( 0, mnLastLines ), Size( mpAcc1->Width(), nNewLines ) ) ); + Bitmap::ScopedWriteAccess pAccess(maIncompleteAlpha); + pAccess->SetFillColor(Color(COL_BLACK)); + pAccess->FillRect(Rectangle(Point(0, mnLastLines), Size(pAccess->Width(), nNewLines))); } - Bitmap::ReleaseAccess( mpAcc1 ); - aGraphic = BitmapEx( rBitmap, maBmp1 ); - mpAcc1 = maBmp1.AcquireWriteAccess(); + aGraphic = BitmapEx(maBitmap, maIncompleteAlpha); } else { - aGraphic = rBitmap; + aGraphic = maBitmap; } } else - aGraphic = rBitmap; + { + aGraphic = maBitmap; + } mnLastLines = nLines; @@ -454,25 +324,15 @@ ReadState JPEGReader::Read( Graphic& rGraphic ) // read the (partial) image ReadJPEG( this, &mrStream, &nLines, GetPreviewSize() ); - if( mpAcc ) + if (!maBitmap.IsEmpty()) { - if( mpBuffer ) - { - FillBitmap(); - delete[] mpBuffer; - mpBuffer = nullptr; - } - - Bitmap::ReleaseAccess( mpAcc ); - mpAcc = nullptr; - if( mrStream.GetError() == ERRCODE_IO_PENDING ) { - rGraphic = CreateIntermediateGraphic( maBmp, nLines ); + rGraphic = CreateIntermediateGraphic(nLines); } else { - rGraphic = maBmp; + rGraphic = maBitmap; } bRet = true; |