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