r17065 by jghali - #10415 : crash when loading a multipage TIFF into an image frame
scribus-commit
scribus-commit at lists.scribus.net
Sat Dec 10 16:40:23 UTC 2011
Author: jghali
Date: Sat Dec 10 16:40:23 2011
New Revision: 17065
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17065
Log:
#10415 : crash when loading a multipage TIFF into an image frame
Modified:
branches/Version135/Scribus/scribus/scimgdataloader_tiff.cpp
Modified: branches/Version135/Scribus/scribus/scimgdataloader_tiff.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17065&path=/branches/Version135/Scribus/scribus/scimgdataloader_tiff.cpp
==============================================================================
--- branches/Version135/Scribus/scribus/scimgdataloader_tiff.cpp (original)
+++ branches/Version135/Scribus/scribus/scimgdataloader_tiff.cpp Sat Dec 10 16:40:23 2011
@@ -109,7 +109,7 @@
struct PSDLayer lay;
TIFFSetTagExtender(TagExtender);
TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
- if(tif)
+ if (tif)
{
do
{
@@ -300,7 +300,7 @@
{
bool gotData = false;
uint32* bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
- uint16 extrasamples, *extratypes;
+ uint16 extrasamples(0), *extratypes(0);
if (!TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &extratypes))
extrasamples = 0;
if(bits)
@@ -617,7 +617,6 @@
random_table[swap] = tmp;
}
int test;
- int layerNum = 0;
bool valid = m_imageInfoRecord.isRequest;
QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
initialize();
@@ -627,7 +626,7 @@
getLayers(fn, page);
TIFFSetTagExtender(TagExtender);
TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
- if(tif)
+ if (tif)
{
bool isCMYK = false;
unsigned int widtht, heightt, size;
@@ -974,7 +973,7 @@
return false;
}
r_image.fill(0);
- bool firstL = true;
+ int layerNum = 0;
do
{
RawImage tmpImg;
@@ -983,58 +982,67 @@
TIFFClose(tif);
return false;
}
+
+ tmpImg.fill(0);
+ if (!getImageData(tif, &tmpImg, widtht, heightt, size, photometric, bitspersample, samplesperpixel, bilevel, isCMYK))
+ {
+ TIFFClose(tif);
+ return false;
+ }
+ bool visible = true;
+ bool useMask = true;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
+ visible = m_imageInfoRecord.RequestProps[layerNum].visible;
+ QString layBlend = "norm";
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
+ layBlend = m_imageInfoRecord.RequestProps[layerNum].blend;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
+ useMask = m_imageInfoRecord.RequestProps[layerNum].useMask;
+ int layOpa = 255;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
+ layOpa = m_imageInfoRecord.RequestProps[layerNum].opacity;
+ if (visible)
+ {
+ if ((layerNum == 0) && (layBlend != "diss"))
+ r_image = tmpImg;
+ else
+ blendOntoTarget(&tmpImg, layOpa, layBlend, isCMYK, useMask);
+ }
+ //JG Copy should not be necessary as QImage is implicitly shared in Qt4
+ QImage imt; //QImage imt = tmpImg.copy();
+ double sx = tmpImg.width() / 40.0;
+ double sy = tmpImg.height() / 40.0;
+ imt = tmpImg.convertToQImage((chans > 4) ? true : false);
+ imt = sy < sx ? imt.scaled(qRound(imt.width() / sx), qRound(imt.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
+ imt.scaled(qRound(imt.width() / sy), qRound(imt.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ m_imageInfoRecord.layerInfo[layerNum].thumb = imt.copy();
+ if (chans > 4)
+ {
+ QImage imt2 = imt.createAlphaMask();
+ imt2.invertPixels();
+ m_imageInfoRecord.layerInfo[layerNum].thumb_mask = imt2.copy();
+ }
else
- {
- tmpImg.fill(0);
- if (!getImageData(tif, &tmpImg, widtht, heightt, size, photometric, bitspersample, samplesperpixel, bilevel, isCMYK))
- {
- TIFFClose(tif);
- return false;
- }
- bool visible = true;
- bool useMask = true;
- if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
- visible = m_imageInfoRecord.RequestProps[layerNum].visible;
- QString layBlend = "norm";
- if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
- layBlend = m_imageInfoRecord.RequestProps[layerNum].blend;
- if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
- useMask = m_imageInfoRecord.RequestProps[layerNum].useMask;
- int layOpa = 255;
- if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
- layOpa = m_imageInfoRecord.RequestProps[layerNum].opacity;
- if (visible)
- {
- if ((firstL) && (layBlend != "diss"))
- r_image = tmpImg;
- else
- blendOntoTarget(&tmpImg, layOpa, layBlend, isCMYK, useMask);
- firstL = false;
- }
- //JG Copy should not be necessary as QImage is implicitly shared in Qt4
- QImage imt; //QImage imt = tmpImg.copy();
- if (chans > 4)
- imt = tmpImg.convertToQImage(true);
- else
- imt = tmpImg.convertToQImage(false);
- double sx = tmpImg.width() / 40.0;
- double sy = tmpImg.height() / 40.0;
- imt = sy < sx ? imt.scaled(qRound(imt.width() / sx), qRound(imt.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
- imt.scaled(qRound(imt.width() / sy), qRound(imt.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
- m_imageInfoRecord.layerInfo[layerNum].thumb = imt.copy();
- if (chans > 4)
- {
- QImage imt2 = imt.createAlphaMask();
- imt2.invertPixels();
- m_imageInfoRecord.layerInfo[layerNum].thumb_mask = imt2.copy();
- }
- else
- m_imageInfoRecord.layerInfo[layerNum].thumb_mask = QImage();
- layerNum++;
- }
+ m_imageInfoRecord.layerInfo[layerNum].thumb_mask = QImage();
+ layerNum++;
+
if ((m_imageInfoRecord.layerInfo.count() == 1) && (chans < 5))
m_imageInfoRecord.layerInfo.clear();
test = TIFFReadDirectory(tif);
+
+ // #10415 : check that image size for the current directory is the same as the main one
+ // Some progs use tiff directory to store previews, we do not handle such case
+ // and may perform reads in non allocated blocks if we continue
+ while (test == 1)
+ {
+ unsigned int dirWidth(0), dirHeight(0);
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &dirWidth);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &dirHeight);
+ if (dirWidth == widtht && dirHeight == heightt)
+ break;
+ test = TIFFReadDirectory(tif);
+ layerNum++;
+ }
}
while (test == 1);
TIFFClose(tif);
More information about the scribus-commit
mailing list