summaryrefslogtreecommitdiff
path: root/vcl/source/filter/jpeg/JpegReader.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/filter/jpeg/JpegReader.cxx')
-rw-r--r--vcl/source/filter/jpeg/JpegReader.cxx214
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;