summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/gdi/dibtools.cxx66
1 files changed, 49 insertions, 17 deletions
diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx
index 424408434ecd..5416da44699a 100644
--- a/vcl/source/gdi/dibtools.cxx
+++ b/vcl/source/gdi/dibtools.cxx
@@ -332,6 +332,22 @@ bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, bool bQuad )
return( rIStm.GetError() == 0UL );
}
+namespace
+{
+ sal_uInt8 SanitizePaletteIndex(sal_uInt8 nIndex, bool bHasPalette, sal_uInt16 nPaletteEntryCount)
+ {
+ if (bHasPalette && nIndex >= nPaletteEntryCount)
+ {
+ auto nSanitizedIndex = nIndex % nPaletteEntryCount;
+ SAL_WARN_IF(nIndex != nSanitizedIndex, "vcl", "invalid colormap index: "
+ << static_cast<unsigned int>(nIndex) << ", colormap len is: "
+ << nPaletteEntryCount);
+ nIndex = nSanitizedIndex;
+ }
+ return nIndex;
+ }
+}
+
bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, bool bRLE4 )
{
Scanline pRLE = pBuffer;
@@ -343,6 +359,8 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess&
sal_uLong nX = 0UL;
sal_uInt8 cTmp;
bool bEndDecoding = false;
+ const bool bHasPalette = rAcc.HasPalette();
+ const sal_uInt16 nPaletteEntryCount = rAcc.GetPaletteEntryCount();
do
{
@@ -368,10 +386,10 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess&
cTmp = *pRLE++;
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp >> 4, bHasPalette, nPaletteEntryCount));
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp & 0x0f, bHasPalette, nPaletteEntryCount));
}
if( nRunByte & 1 )
@@ -380,7 +398,7 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess&
return false;
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, *pRLE >> 4 );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(*pRLE >> 4, bHasPalette, nPaletteEntryCount));
pRLE++;
}
@@ -401,7 +419,7 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess&
return false;
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, *pRLE );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(*pRLE, bHasPalette, nPaletteEntryCount));
pRLE++;
}
@@ -448,19 +466,19 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess&
for( sal_uLong i = 0UL; i < nRunByte; i++ )
{
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp >> 4, bHasPalette, nPaletteEntryCount));
if( nX < nWidth )
- rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp & 0x0f, bHasPalette, nPaletteEntryCount));
}
if( ( nCountByte & 1 ) && ( nX < nWidth ) )
- rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp >> 4, bHasPalette, nPaletteEntryCount));
}
else
{
for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ )
- rAcc.SetPixelIndex( nY, nX++, cTmp );
+ rAcc.SetPixelIndex(nY, nX++, SanitizePaletteIndex(cTmp, bHasPalette, nPaletteEntryCount));
}
}
}
@@ -482,10 +500,10 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
switch(rAcc.GetScanlineFormat())
{
case( BMP_FORMAT_1BIT_MSB_PAL ):
- case( BMP_FORMAT_4BIT_MSN_PAL ):
- case( BMP_FORMAT_8BIT_PAL ):
case( BMP_FORMAT_24BIT_TC_BGR ):
{
+ // we can't trust arbitrary-sourced index based formats to have correct indexes, so we exclude the pal formats
+ // from raw read and force checking their colormap indexes
bNative = ( ( static_cast< bool >(rAcc.IsBottomUp()) != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) );
break;
}
@@ -497,7 +515,7 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
}
// Read data
- if(bNative)
+ if (bNative)
{
if (nAlignedWidth
> std::numeric_limits<sal_Size>::max() / rHeader.nHeight)
@@ -521,7 +539,7 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
rIStm.ReadUInt32( nBMask );
}
- if(bRLE)
+ if (bRLE)
{
if(!rHeader.nSizeImage)
{
@@ -551,6 +569,9 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
{
case( 1 ):
{
+ const bool bHasPalette = rAcc.HasPalette();
+ const sal_uInt16 nPaletteEntryCount = rAcc.GetPaletteEntryCount();
+
for( ; nCount--; nY += nI )
{
sal_uInt8* pTmp;
@@ -565,11 +586,12 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
{
if( !nShift )
{
- nShift = 8L,
+ nShift = 8L;
cTmp = *pTmp++;
}
- rAcc.SetPixelIndex( nY, nX, (cTmp >> --nShift) & 1);
+ auto nIndex = (cTmp >> --nShift) & 1;
+ rAcc.SetPixelIndex(nY, nX, SanitizePaletteIndex(nIndex, bHasPalette, nPaletteEntryCount));
}
}
}
@@ -577,6 +599,9 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
case( 4 ):
{
+ const bool bHasPalette = rAcc.HasPalette();
+ const sal_uInt16 nPaletteEntryCount = rAcc.GetPaletteEntryCount();
+
for( ; nCount--; nY += nI )
{
sal_uInt8* pTmp;
@@ -595,7 +620,8 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
cTmp = *pTmp++;
}
- rAcc.SetPixelIndex( nY, nX, (cTmp >> ( --nShift << 2UL ) ) & 0x0f);
+ auto nIndex = (cTmp >> ( --nShift << 2UL ) ) & 0x0f;
+ rAcc.SetPixelIndex(nY, nX, SanitizePaletteIndex(nIndex, bHasPalette, nPaletteEntryCount));
}
}
}
@@ -603,6 +629,9 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
case( 8 ):
{
+ const bool bHasPalette = rAcc.HasPalette();
+ const sal_uInt16 nPaletteEntryCount = rAcc.GetPaletteEntryCount();
+
for( ; nCount--; nY += nI )
{
sal_uInt8* pTmp;
@@ -613,7 +642,10 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
}
for( long nX = 0L; nX < nWidth; nX++ )
- rAcc.SetPixelIndex( nY, nX, *pTmp++ );
+ {
+ auto nIndex = *pTmp++;
+ rAcc.SetPixelIndex(nY, nX, SanitizePaletteIndex(nIndex, bHasPalette, nPaletteEntryCount));
+ }
}
}
break;
@@ -897,7 +929,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_u
}
// read palette
- if(nColors)
+ if (nColors)
{
pAcc->SetPaletteEntryCount(nColors);
ImplReadDIBPalette(*pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE);