summaryrefslogtreecommitdiff
path: root/vcl/source/gdi
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-03-27 12:31:00 +0100
committerCaolán McNamara <caolanm@redhat.com>2017-03-27 13:47:48 +0100
commitec1015430dcfd5a6e20a13d878bc34ce3149b8ea (patch)
tree59bced339329b25aa60188867c152b6bd5072397 /vcl/source/gdi
parentaad792b3720957e715cf10d9bfa648a3905497ed (diff)
return early on error
no logc change intended Change-Id: I9a000ccc53b13d2948264b18ae0abf29a6ddc33c
Diffstat (limited to 'vcl/source/gdi')
-rw-r--r--vcl/source/gdi/dibtools.cxx370
1 files changed, 184 insertions, 186 deletions
diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx
index 7486b59da9e3..a05f90932cab 100644
--- a/vcl/source/gdi/dibtools.cxx
+++ b/vcl/source/gdi/dibtools.cxx
@@ -761,230 +761,228 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_u
{
DIBV5Header aHeader;
const sal_uLong nStmPos = rIStm.Tell();
- bool bRet(false);
bool bTopDown(false);
- if(ImplReadDIBInfoHeader(rIStm, aHeader, bTopDown, bMSOFormat) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount)
+ if (!ImplReadDIBInfoHeader(rIStm, aHeader, bTopDown, bMSOFormat) && aHeader.nWidth && aHeader.nHeight && aHeader.nBitCount)
+ return false;
+
+ // In case ImplReadDIB() didn't call ImplReadDIBFileHeader() before
+ // this method, nOffset is 0, that's OK.
+ if (nOffset && aHeader.nSize > nOffset)
{
- // In case ImplReadDIB() didn't call ImplReadDIBFileHeader() before
- // this method, nOffset is 0, that's OK.
- if (nOffset && aHeader.nSize > nOffset)
- {
- // Header size claims to extend into the image data.
- // Looks like an error.
- return false;
- }
+ // Header size claims to extend into the image data.
+ // Looks like an error.
+ return false;
+ }
- const sal_uInt16 nBitCount(discretizeBitcount(aHeader.nBitCount));
+ const sal_uInt16 nBitCount(discretizeBitcount(aHeader.nBitCount));
- sal_uInt16 nColors(0);
- SvStream* pIStm;
- std::unique_ptr<SvMemoryStream> pMemStm;
- std::vector<sal_uInt8> aData;
+ sal_uInt16 nColors(0);
+ SvStream* pIStm;
+ std::unique_ptr<SvMemoryStream> pMemStm;
+ std::vector<sal_uInt8> aData;
- if (aHeader.nBitCount <= 8)
+ if (aHeader.nBitCount <= 8)
+ {
+ if(aHeader.nColsUsed)
{
- if(aHeader.nColsUsed)
- {
- nColors = (sal_uInt16)aHeader.nColsUsed;
- }
- else
- {
- nColors = ( 1 << aHeader.nBitCount );
- }
+ nColors = (sal_uInt16)aHeader.nColsUsed;
+ }
+ else
+ {
+ nColors = ( 1 << aHeader.nBitCount );
}
+ }
+
+ if (ZCOMPRESS == aHeader.nCompression)
+ {
+ sal_uInt32 nCodedSize(0);
+ sal_uInt32 nUncodedSize(0);
+
+ // read coding information
+ rIStm.ReadUInt32( nCodedSize ).ReadUInt32( nUncodedSize ).ReadUInt32( aHeader.nCompression );
+ if (nCodedSize > rIStm.remainingSize())
+ nCodedSize = sal_uInt32(rIStm.remainingSize());
+ size_t nSizeInc(4 * rIStm.remainingSize());
+ if (nUncodedSize < nSizeInc)
+ nSizeInc = nUncodedSize;
- if(ZCOMPRESS == aHeader.nCompression)
+ if (nSizeInc > 0)
{
- sal_uInt32 nCodedSize(0);
- sal_uInt32 nUncodedSize(0);
-
- // read coding information
- rIStm.ReadUInt32( nCodedSize ).ReadUInt32( nUncodedSize ).ReadUInt32( aHeader.nCompression );
- if (nCodedSize > rIStm.remainingSize())
- nCodedSize = sal_uInt32(rIStm.remainingSize());
- size_t nSizeInc(4 * rIStm.remainingSize());
- if (nUncodedSize < nSizeInc)
- nSizeInc = nUncodedSize;
-
- if (nSizeInc > 0)
+ // decode buffer
+ const sal_uLong nCodedPos = rIStm.Tell();
+ ZCodec aCodec;
+ aCodec.BeginCompression();
+ aData.resize(nSizeInc);
+ size_t nDataPos(0);
+ while (nUncodedSize > nDataPos)
{
- // decode buffer
- const sal_uLong nCodedPos = rIStm.Tell();
- ZCodec aCodec;
- aCodec.BeginCompression();
- aData.resize(nSizeInc);
- size_t nDataPos(0);
- while (nUncodedSize > nDataPos)
+ assert(aData.size() > nDataPos);
+ const size_t nToRead(std::min<size_t>(nUncodedSize - nDataPos, aData.size() - nDataPos));
+ assert(nToRead > 0);
+ assert(!aData.empty());
+ const long nRead = aCodec.Read(rIStm, aData.data() + nDataPos, sal_uInt32(nToRead));
+ if (nRead > 0)
{
- assert(aData.size() > nDataPos);
- const size_t nToRead(std::min<size_t>(nUncodedSize - nDataPos, aData.size() - nDataPos));
- assert(nToRead > 0);
- assert(!aData.empty());
- const long nRead = aCodec.Read(rIStm, aData.data() + nDataPos, sal_uInt32(nToRead));
- if (nRead > 0)
- {
- nDataPos += static_cast<unsigned long>(nRead);
- // we haven't read everything yet: resize buffer and continue
- if (nDataPos < nUncodedSize)
- aData.resize(aData.size() + nSizeInc);
- }
- else
- {
- break;
- }
+ nDataPos += static_cast<unsigned long>(nRead);
+ // we haven't read everything yet: resize buffer and continue
+ if (nDataPos < nUncodedSize)
+ aData.resize(aData.size() + nSizeInc);
+ }
+ else
+ {
+ break;
}
- // truncate the data buffer to actually read size
- aData.resize(nDataPos);
- // set the real uncoded size
- nUncodedSize = sal_uInt32(aData.size());
- aCodec.EndCompression();
-
- // Seek behind the encoded block. There might have been bytes left or the codec might have read more than necessary.
- rIStm.Seek(nCodedSize + nCodedPos);
- }
-
- if (aData.empty())
- {
- // add something so we can take address of the first element
- aData.resize(1);
- nUncodedSize = 0;
}
-
- // set decoded bytes to memory stream,
- // from which we will read the bitmap data
- pMemStm.reset(new SvMemoryStream);
- pIStm = pMemStm.get();
- assert(!aData.empty());
- pMemStm->SetBuffer(aData.data(), nUncodedSize, nUncodedSize);
- nOffset = 0;
+ // truncate the data buffer to actually read size
+ aData.resize(nDataPos);
+ // set the real uncoded size
+ nUncodedSize = sal_uInt32(aData.size());
+ aCodec.EndCompression();
+
+ // Seek behind the encoded block. There might have been bytes left or the codec might have read more than necessary.
+ rIStm.Seek(nCodedSize + nCodedPos);
}
- else
+
+ if (aData.empty())
{
- pIStm = &rIStm;
+ // add something so we can take address of the first element
+ aData.resize(1);
+ nUncodedSize = 0;
}
- const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(aHeader.nWidth) * static_cast<sal_Int64>(aHeader.nBitCount));
- if (nBitsPerLine > SAL_MAX_UINT32)
- return false;
- const sal_uInt64 nAlignedWidth(AlignedWidth4Bytes(static_cast<sal_uLong>(nBitsPerLine)));
+ // set decoded bytes to memory stream,
+ // from which we will read the bitmap data
+ pMemStm.reset(new SvMemoryStream);
+ pIStm = pMemStm.get();
+ assert(!aData.empty());
+ pMemStm->SetBuffer(aData.data(), nUncodedSize, nUncodedSize);
+ nOffset = 0;
+ }
+ else
+ {
+ pIStm = &rIStm;
+ }
+
+ const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(aHeader.nWidth) * static_cast<sal_Int64>(aHeader.nBitCount));
+ if (nBitsPerLine > SAL_MAX_UINT32)
+ return false;
+ const sal_uInt64 nAlignedWidth(AlignedWidth4Bytes(static_cast<sal_uLong>(nBitsPerLine)));
- switch (aHeader.nCompression)
+ switch (aHeader.nCompression)
+ {
+ case RLE_8:
+ if (aHeader.nBitCount != 8)
+ return false;
+ break;
+ case RLE_4:
+ if (aHeader.nBitCount != 4)
+ return false;
+ break;
+ case BITFIELDS:
+ break;
+ case ZCOMPRESS:
+ case COMPRESS_NONE:
{
- case RLE_8:
- if (aHeader.nBitCount != 8)
- return false;
- break;
- case RLE_4:
- if (aHeader.nBitCount != 4)
- return false;
- break;
- case BITFIELDS:
- break;
- case ZCOMPRESS:
- case COMPRESS_NONE:
- {
- // (partially) check the image dimensions to avoid potential large bitmap allocation if the input is damaged
- sal_uInt64 nMaxWidth = pIStm->remainingSize();
- if (aHeader.nHeight != 0)
- nMaxWidth /= aHeader.nHeight;
- if (nMaxWidth < nAlignedWidth)
- return false;
- break;
- }
- default:
+ // (partially) check the image dimensions to avoid potential large bitmap allocation if the input is damaged
+ sal_uInt64 nMaxWidth = pIStm->remainingSize();
+ if (aHeader.nHeight != 0)
+ nMaxWidth /= aHeader.nHeight;
+ if (nMaxWidth < nAlignedWidth)
return false;
+ break;
}
-
- const Size aSizePixel(aHeader.nWidth, aHeader.nHeight);
- BitmapPalette aPalette;
- Bitmap aNewBmp(aSizePixel, nBitCount, &aPalette);
- Bitmap::ScopedWriteAccess pAcc(aNewBmp);
- if (!pAcc)
- return false;
- if (pAcc->Width() != aHeader.nWidth || pAcc->Height() != aHeader.nHeight)
- {
+ default:
return false;
- }
- AlphaMask aNewBmpAlpha;
- AlphaMask::ScopedWriteAccess pAccAlpha;
- bool bAlphaPossible(pBmpAlpha && aHeader.nBitCount == 32);
+ }
- if (bAlphaPossible)
- {
- const bool bRedSet(0 != aHeader.nV5RedMask);
- const bool bGreenSet(0 != aHeader.nV5GreenMask);
- const bool bBlueSet(0 != aHeader.nV5BlueMask);
-
- // some clipboard entries have alpha mask on zero to say that there is
- // no alpha; do only use this when the other masks are set. The MS docu
- // says that masks are only to be set when bV5Compression is set to
- // BI_BITFIELDS, but there seem to exist a wild variety of usages...
- if((bRedSet || bGreenSet || bBlueSet) && (0 == aHeader.nV5AlphaMask))
- {
- bAlphaPossible = false;
- }
- }
+ const Size aSizePixel(aHeader.nWidth, aHeader.nHeight);
+ BitmapPalette aPalette;
+ Bitmap aNewBmp(aSizePixel, nBitCount, &aPalette);
+ Bitmap::ScopedWriteAccess pAcc(aNewBmp);
+ if (!pAcc)
+ return false;
+ if (pAcc->Width() != aHeader.nWidth || pAcc->Height() != aHeader.nHeight)
+ {
+ return false;
+ }
+ AlphaMask aNewBmpAlpha;
+ AlphaMask::ScopedWriteAccess pAccAlpha;
+ bool bAlphaPossible(pBmpAlpha && aHeader.nBitCount == 32);
- if (bAlphaPossible)
+ if (bAlphaPossible)
+ {
+ const bool bRedSet(0 != aHeader.nV5RedMask);
+ const bool bGreenSet(0 != aHeader.nV5GreenMask);
+ const bool bBlueSet(0 != aHeader.nV5BlueMask);
+
+ // some clipboard entries have alpha mask on zero to say that there is
+ // no alpha; do only use this when the other masks are set. The MS docu
+ // says that masks are only to be set when bV5Compression is set to
+ // BI_BITFIELDS, but there seem to exist a wild variety of usages...
+ if((bRedSet || bGreenSet || bBlueSet) && (0 == aHeader.nV5AlphaMask))
{
- aNewBmpAlpha = AlphaMask(aSizePixel);
- pAccAlpha = AlphaMask::ScopedWriteAccess(aNewBmpAlpha);
+ bAlphaPossible = false;
}
+ }
- // read palette
- if (nColors)
- {
- aPalette.SetEntryCount(nColors);
- ImplReadDIBPalette(*pIStm, aPalette, aHeader.nSize != DIBCOREHEADERSIZE);
- pAcc->SetPalette(aPalette);
- }
+ if (bAlphaPossible)
+ {
+ aNewBmpAlpha = AlphaMask(aSizePixel);
+ pAccAlpha = AlphaMask::ScopedWriteAccess(aNewBmpAlpha);
+ }
- // read bits
- bool bAlphaUsed(false);
+ // read palette
+ if (nColors)
+ {
+ aPalette.SetEntryCount(nColors);
+ ImplReadDIBPalette(*pIStm, aPalette, aHeader.nSize != DIBCOREHEADERSIZE);
+ pAcc->SetPalette(aPalette);
+ }
- if(!pIStm->GetError())
- {
- if(nOffset)
- {
- pIStm->SeekRel(nOffset - (pIStm->Tell() - nStmPos));
- }
+ if (pIStm->GetError())
+ return false;
- bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha.get(), bTopDown, bAlphaUsed, nAlignedWidth);
+ if(nOffset)
+ {
+ pIStm->SeekRel(nOffset - (pIStm->Tell() - nStmPos));
+ }
- if(bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter)
- {
- MapMode aMapMode(
- MapUnit::MapMM,
- Point(),
- Fraction(1000, aHeader.nXPelsPerMeter),
- Fraction(1000, aHeader.nYPelsPerMeter));
-
- aNewBmp.SetPrefMapMode(aMapMode);
- aNewBmp.SetPrefSize(Size(aHeader.nWidth, aHeader.nHeight));
- }
- }
+ // read bits
+ bool bAlphaUsed(false);
+ bool bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha.get(), bTopDown, bAlphaUsed, nAlignedWidth);
- pAcc.reset();
+ if (bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter)
+ {
+ MapMode aMapMode(
+ MapUnit::MapMM,
+ Point(),
+ Fraction(1000, aHeader.nXPelsPerMeter),
+ Fraction(1000, aHeader.nYPelsPerMeter));
+
+ aNewBmp.SetPrefMapMode(aMapMode);
+ aNewBmp.SetPrefSize(Size(aHeader.nWidth, aHeader.nHeight));
+ }
- if(bAlphaPossible)
- {
- pAccAlpha.reset();
+ pAcc.reset();
- if(!bAlphaUsed)
- {
- bAlphaPossible = false;
- }
- }
+ if (bAlphaPossible)
+ {
+ pAccAlpha.reset();
- if(bRet)
+ if(!bAlphaUsed)
{
- rBmp = aNewBmp;
+ bAlphaPossible = false;
+ }
+ }
- if(bAlphaPossible)
- {
- *pBmpAlpha = aNewBmpAlpha;
- }
+ if (bRet)
+ {
+ rBmp = aNewBmp;
+
+ if(bAlphaPossible)
+ {
+ *pBmpAlpha = aNewBmpAlpha;
}
}