Ensure that the palette does not have more than 256 values

This commit is contained in:
Mirco Miranda
2026-10-30 14:29:57 +01:00
committed by Mirco Miranda
parent e2c6317079
commit 59157971e8
6 changed files with 62 additions and 6 deletions
+2 -2
View File
@@ -565,13 +565,13 @@ QList<QRgb> CMAPChunk::palette(bool halfbride) const
{
auto p = innerPalette();
if (!halfbride) {
return p;
return truncTo8BitColorTable(p);
}
auto tmp = p;
for (auto &&v : tmp) {
p << qRgb(qRed(v) / 2, qGreen(v) / 2, qBlue(v) / 2);
}
return p;
return truncTo8BitColorTable(p);
}
bool CMAPChunk::innerReadStructure(QIODevice *d)
+1 -1
View File
@@ -1146,7 +1146,7 @@ bool PSDHandler::read(QImage *image)
}
img.fill(qRgb(0, 0, 0));
if (!cmds.palette.isEmpty()) {
img.setColorTable(cmds.palette);
img.setColorTable(truncTo8BitColorTable(cmds.palette));
setTransparencyIndex(img, irs);
}
+1 -1
View File
@@ -652,7 +652,7 @@ static bool LoadTGA(QIODevice *dev, const TgaHeader &tga, QImage &img)
return false;
}
img.setColorTable(colorTable);
img.setColorTable(truncTo8BitColorTable(colorTable));
}
// Convert image to internal format.
+1 -1
View File
@@ -184,7 +184,7 @@ public:
// where there shouldn't be any (so, disabled for now)
clut << qRgba((v & 0x1F) * 255 / 31, ((v >> 5) & 0x1F) * 255 / 31, ((v >> 10) & 0x1F) * 255 / 31, 255);
}
return clut;
return truncTo8BitColorTable(clut);
}
bool read(QIODevice *d)
+56
View File
@@ -138,6 +138,62 @@ inline QImage imageAlloc(qint32 width, qint32 height, const QImage::Format &form
return imageAlloc(QSize(width, height), format, init);
}
/*!
* \brief fixIndexedColorTable
* Helper function to return a color table with the wanted size.
*
* A copy of the color table is truncated or padded (with transparent entries)
* until it has exactly \a wantedSize entries, clamped to the range [2, 256].
* A color table larger than 256 entries could crash on conversion to
* Format_Grayscale8, Format_Mono, Format_MonoLSB or Format_Alpha8, while one
* with fewer entries than the maximum possible pixel index would leave some
* indexes undefined.
* \param colorTable The color table to copy and resize.
* \param wantedSize The wanted number of color table entries, by default 256.
* \return The resized copy of the color table.
*/
inline QList<QRgb> fixIndexedColorTable(const QList<QRgb> &colorTable, qint32 wantedSize = 256)
{
QList<QRgb> list = colorTable;
// color table larger than 256 items could crash on conversion to
// Format_Grayscale8, Format_Mono, Format_MonoLSB, Format_Alpha8
wantedSize = qBound(2, 256, wantedSize);
if (list.size() == wantedSize) {
return list;
}
// ensure that it is no larger than required
if (list.size() > wantedSize) {
list.resize(wantedSize);
}
// ensure that it is no smaller than required
while (list.size() < wantedSize) {
list << QRgb();
}
return list;
}
/*!
* \brief truncTo8BitColorTable
* Helper function to limit a color table to 256 entries.
*
* A copy of the color table is returned, truncated to 256 entries if it has
* more. Color tables with more than 256 entries could crash on conversion to
* Format_Grayscale8, Format_Mono, Format_MonoLSB or Format_Alpha8, and indexes
* beyond 255 cannot be stored in an 8-bit indexed pixel format. Color tables
* with at most 256 entries are returned unchanged.
* \param colorTable The color table to copy.
* \return A copy of the color table limited to 256 entries.
*/
inline QList<QRgb> truncTo8BitColorTable(const QList<QRgb> &colorTable)
{
return(fixIndexedColorTable(colorTable, colorTable.size()));
}
/*!
* \brief checkImageSize
* Helper function to make sure the image size does not exceed the limit set in Qt.
+1 -1
View File
@@ -1561,7 +1561,7 @@ void XCFImageFormat::setPalette(XCFImage &xcf_image, QImage &image)
{
Q_ASSERT(xcf_image.num_colors == xcf_image.palette.size());
image.setColorTable(xcf_image.palette);
image.setColorTable(truncTo8BitColorTable(xcf_image.palette));
}
/*!