Kaydet (Commit) bb3715b6 authored tarafından Caolán McNamara's avatar Caolán McNamara

ofz#967 optimize tiff import if line is the same as previous line

Change-Id: Ided61679a579a73481320f85c05b03e3ce3d762a
üst 30d58306
......@@ -624,18 +624,17 @@ void CCIDecompressor::StartDecompression( SvStream & rIStream )
return;
}
bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTargetBits, bool bLastLine )
DecompressStatus CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTargetBits, bool bLastLine )
{
//Read[1|2]DScanlineData take a sal_uInt16, so its either limit here or expand there
if (nTargetBits > SAL_MAX_UINT16)
return false;
return DecompressStatus(false, true);
if ( nEOLCount >= 5 ) // RTC (Return To Controller)
return true;
return DecompressStatus(true, true);
if ( !bStatus )
return false;
return DecompressStatus(false, true);
// If EOL-Codes exist, the EOL-Code also appeared in front of the first line.
// (and I thought it means 'End of Line'...)
......@@ -660,13 +659,13 @@ bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTarget
{
if ( !ReadEOL( nTargetBits ) )
{
return bStatus;
return DecompressStatus(bStatus, true);
}
}
}
if ( nEOLCount >= 5 ) // RTC (Return To Controller)
return true;
return DecompressStatus(true, true);
// should the situation arise, generate a white previous line for 2D:
if ( nOptions & CCI_OPTION_2D )
......@@ -696,11 +695,12 @@ bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTarget
else
b2D = false;
bool bUnchanged;
// read scanline:
if ( b2D )
Read2DScanlineData( pTarget, (sal_uInt16)nTargetBits );
bUnchanged = Read2DScanlineData(pTarget, nTargetBits);
else
Read1DScanlineData( pTarget, (sal_uInt16)nTargetBits );
bUnchanged = Read1DScanlineData(pTarget, nTargetBits);
// if we're in 2D mode we have to remember the line:
if ( nOptions & CCI_OPTION_2D && bStatus )
......@@ -717,7 +717,7 @@ bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTarget
if ( pIStream->GetError() )
bStatus = false;
return bStatus;
return DecompressStatus(bStatus, bUnchanged);
}
......@@ -923,8 +923,9 @@ sal_uInt16 CCIDecompressor::CountBits(const sal_uInt8 * pData, sal_uInt16 nDataS
return nPos-nBitPos;
}
void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
bool CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nBitsToRead)
{
sal_uInt16 nTargetBits = nBitsToRead;
sal_uInt16 nCode,nCodeBits,nDataBits,nTgtFreeByteBits;
sal_uInt8 nByte;
sal_uInt8 nBlackOrWhite; // is 0xff for black or 0x00 for white
......@@ -962,11 +963,11 @@ void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTarget
// is that an invalid code?
if ( nDataBits == 9999 )
{
return;
return nTargetBits == nBitsToRead;
}
if ( nCodeBits == 0 )
{
return; // could be filling bits now
return nTargetBits == nBitsToRead; // could be filling bits now
}
nEOLCount = 0;
// too much data?
......@@ -1017,10 +1018,11 @@ void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTarget
if (bTerminatingCode) nBlackOrWhite = ~nBlackOrWhite;
} while (nTargetBits>0 || !bTerminatingCode);
}
return nTargetBits == nBitsToRead;
}
void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
bool CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
{
sal_uInt16 n2DMode,nBitPos,nUncomp,nRun,nRun2,nt;
sal_uInt8 nBlackOrWhite;
......@@ -1032,7 +1034,7 @@ void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTarget
n2DMode=ReadCodeAndDecode(p2DModeLookUp,10);
if (!bStatus)
return;
return nBitPos == 0;
if (n2DMode==CCI2DMODE_UNCOMP) {
for (;;) {
......@@ -1114,7 +1116,8 @@ void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTarget
nBlackOrWhite=~nBlackOrWhite;
}
}
}
return nBitPos == 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -45,6 +45,16 @@ struct CCILookUpTableEntry {
class SvStream;
struct DecompressStatus
{
bool m_bSuccess;
bool m_bBufferUnchanged;
DecompressStatus(bool bSuccess, bool bBufferUnchanged)
: m_bSuccess(bSuccess), m_bBufferUnchanged(bBufferUnchanged)
{
}
};
class CCIDecompressor {
public:
......@@ -54,7 +64,7 @@ public:
void StartDecompression( SvStream & rIStream );
bool DecompressScanline(sal_uInt8 * pTarget, sal_uLong nTargetBits, bool bLastLine );
DecompressStatus DecompressScanline(sal_uInt8 * pTarget, sal_uLong nTargetBits, bool bLastLine);
private:
......@@ -80,9 +90,9 @@ private:
static sal_uInt16 CountBits(const sal_uInt8 * pData, sal_uInt16 nDataSizeBits,
sal_uInt16 nBitPos, sal_uInt8 nBlackOrWhite);
void Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits);
void Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits);
//returns true if pTarget was unmodified
bool Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits);
bool Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits);
bool bTableBad;
......
......@@ -598,8 +598,10 @@ bool TIFFReader::ReadMap()
aCCIDecom.StartDecompression( *pTIFF );
bool bDifferentToPrev;
for (sal_Int32 ny = 0; ny < nImageLength; ++ny)
{
bDifferentToPrev = ny == 0;
for (sal_uLong np = 0; np < nPlanes; np++ )
{
if ( ny / GetRowsPerStrip() + np * nStripsPerPlane > nStrip )
......@@ -615,13 +617,27 @@ bool TIFFReader::ReadMap()
}
if (np >= SAL_N_ELEMENTS(pMap))
return false;
if ( !aCCIDecom.DecompressScanline( pMap[ np ], nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes, np + 1 == nPlanes ) )
DecompressStatus aResult = aCCIDecom.DecompressScanline(pMap[np],nImageWidth * nBitsPerSample * nSamplesPerPixel / nPlanes, np + 1 == nPlanes);
if (!aResult.m_bSuccess)
return false;
bDifferentToPrev |= !aResult.m_bBufferUnchanged;
if ( pTIFF->GetError() )
return false;
}
if ( !ConvertScanline( ny ) )
return false;
if (!bDifferentToPrev)
{
//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
pAcc->CopyScanline(ny, pAcc->GetScanline(ny-1),
pAcc->GetScanlineFormat(),
pAcc->GetScanlineSize());
}
else
{
if (!ConvertScanline(ny))
return false;
}
}
}
else if ( nCompression == 5 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment