mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2026-05-25 13:08:28 -04:00
Improve size limits for AVIF, HEIF, and RAW plugins
This commit is contained in:
@@ -248,18 +248,19 @@ Anyway, all plugins are also limited by the
|
|||||||
|
|
||||||
> [!note]
|
> [!note]
|
||||||
> You can change the maximum limit of 300000 pixels by setting the constant
|
> You can change the maximum limit of 300000 pixels by setting the constant
|
||||||
> `KIF_LARGE_IMAGE_PIXEL_LIMIT` to the desired value in the cmake file.
|
> `KIF_LARGE_IMAGE_PIXEL_LIMIT` to the desired value in the cmake file. It
|
||||||
|
> cannot be less than 65536.
|
||||||
|
|
||||||
Below are the maximum sizes for each plugin ('n/a' means no limit, i.e. the
|
Below are the maximum sizes for each plugin ('n/a' means no limit, i.e. the
|
||||||
limit depends on the format encoding).
|
limit depends on the format encoding).
|
||||||
- ANI: n/a
|
- ANI: same size as Qt's ICO plugin
|
||||||
- AVIF: 32,768 x 32,768 pixels, in any case no larger than 256 megapixels
|
- AVIF: 32,768 x 32,768 pixels, in any case no larger than 256 megapixels
|
||||||
- DDS: 300,000 x 300,000 pixels
|
- DDS: 300,000 x 300,000 pixels
|
||||||
- EXR: 300,000 x 300,000 pixels
|
- EXR: 300,000 x 300,000 pixels
|
||||||
- EPS: same size as Qt's JPG plugin
|
- EPS: same size as Qt's JPG plugin
|
||||||
- FF: 300,000 x 300,000 pixels
|
- FF: 300,000 x 300,000 pixels
|
||||||
- HDR: 300,000 x 300,000 pixels
|
- HDR: 300,000 x 300,000 pixels
|
||||||
- HEIF: n/a
|
- HEIF: 65,535 x 65,535 pixels
|
||||||
- IFF: 65,535 x 65,535 pixels
|
- IFF: 65,535 x 65,535 pixels
|
||||||
- JP2: 300,000 x 300,000 pixels, in any case no larger than 2 gigapixels
|
- JP2: 300,000 x 300,000 pixels, in any case no larger than 2 gigapixels
|
||||||
- JXL: 262,144 x 262,144 pixels, in any case no larger than 256 megapixels
|
- JXL: 262,144 x 262,144 pixels, in any case no larger than 256 megapixels
|
||||||
|
|||||||
@@ -49,6 +49,16 @@ Quality range - compression/subsampling
|
|||||||
#define KIMG_AVIF_QUALITY_LOW 51
|
#define KIMG_AVIF_QUALITY_LOW 51
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* *** AVIF_MAX_IMAGE_WIDTH and AVIF_MAX_IMAGE_HEIGHT ***
|
||||||
|
* The maximum size in pixel allowed by the plugin.
|
||||||
|
*/
|
||||||
|
#ifndef AVIF_MAX_IMAGE_WIDTH
|
||||||
|
#define AVIF_MAX_IMAGE_WIDTH KIF_64K_IMAGE_PIXEL_LIMIT
|
||||||
|
#endif
|
||||||
|
#ifndef AVIF_MAX_IMAGE_HEIGHT
|
||||||
|
#define AVIF_MAX_IMAGE_HEIGHT AVIF_MAX_IMAGE_WIDTH
|
||||||
|
#endif
|
||||||
|
|
||||||
QAVIFHandler::QAVIFHandler()
|
QAVIFHandler::QAVIFHandler()
|
||||||
: m_parseState(ParseAvifNotParsed)
|
: m_parseState(ParseAvifNotParsed)
|
||||||
, m_quality(KIMG_AVIF_DEFAULT_QUALITY)
|
, m_quality(KIMG_AVIF_DEFAULT_QUALITY)
|
||||||
@@ -168,7 +178,7 @@ bool QAVIFHandler::ensureDecoder()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if AVIF_VERSION >= 110000
|
#if AVIF_VERSION >= 110000
|
||||||
m_decoder->imageDimensionLimit = 65535;
|
m_decoder->imageDimensionLimit = std::max(AVIF_MAX_IMAGE_WIDTH, AVIF_MAX_IMAGE_HEIGHT) - 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
avifResult decodeResult;
|
avifResult decodeResult;
|
||||||
@@ -196,7 +206,7 @@ bool QAVIFHandler::ensureDecoder()
|
|||||||
m_container_width = m_decoder->image->width;
|
m_container_width = m_decoder->image->width;
|
||||||
m_container_height = m_decoder->image->height;
|
m_container_height = m_decoder->image->height;
|
||||||
|
|
||||||
if ((m_container_width > 65535) || (m_container_height > 65535)) {
|
if ((m_container_width >= AVIF_MAX_IMAGE_WIDTH) || (m_container_height >= AVIF_MAX_IMAGE_HEIGHT)) {
|
||||||
qCWarning(LOG_AVIFPLUGIN, "AVIF image (%dx%d) is too large!", m_container_width, m_container_height);
|
qCWarning(LOG_AVIFPLUGIN, "AVIF image (%dx%d) is too large!", m_container_width, m_container_height);
|
||||||
m_parseState = ParseAvifError;
|
m_parseState = ParseAvifError;
|
||||||
return false;
|
return false;
|
||||||
@@ -605,7 +615,7 @@ bool QAVIFHandler::write(const QImage &image)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((image.width() > 0) && (image.height() > 0)) {
|
if ((image.width() > 0) && (image.height() > 0)) {
|
||||||
if ((image.width() > 65535) || (image.height() > 65535)) {
|
if ((image.width() >= AVIF_MAX_IMAGE_WIDTH) || (image.height() >= AVIF_MAX_IMAGE_HEIGHT)) {
|
||||||
qCWarning(LOG_AVIFPLUGIN, "Image (%dx%d) is too large to save!", image.width(), image.height());
|
qCWarning(LOG_AVIFPLUGIN, "Image (%dx%d) is too large to save!", image.width(), image.height());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,16 @@ Q_LOGGING_CATEGORY(LOG_HEIFPLUGIN, "kf.imageformats.plugins.heif", QtWarningMsg)
|
|||||||
// #define HEIF_DISABLE_QT_TRANSFORMATION
|
// #define HEIF_DISABLE_QT_TRANSFORMATION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* *** HEIF_MAX_IMAGE_WIDTH and HEIF_MAX_IMAGE_HEIGHT ***
|
||||||
|
* The maximum size in pixel allowed by the plugin.
|
||||||
|
*/
|
||||||
|
#ifndef HEIF_MAX_IMAGE_WIDTH
|
||||||
|
#define HEIF_MAX_IMAGE_WIDTH KIF_64K_IMAGE_PIXEL_LIMIT
|
||||||
|
#endif
|
||||||
|
#ifndef HEIF_MAX_IMAGE_HEIGHT
|
||||||
|
#define HEIF_MAX_IMAGE_HEIGHT HEIF_MAX_IMAGE_WIDTH
|
||||||
|
#endif
|
||||||
|
|
||||||
size_t HEIFHandler::m_initialized_count = 0;
|
size_t HEIFHandler::m_initialized_count = 0;
|
||||||
bool HEIFHandler::m_plugins_queried = false;
|
bool HEIFHandler::m_plugins_queried = false;
|
||||||
bool HEIFHandler::m_heif_decoder_available = false;
|
bool HEIFHandler::m_heif_decoder_available = false;
|
||||||
@@ -137,6 +147,11 @@ bool HEIFHandler::write(const QImage &image)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (image.width() >= HEIF_MAX_IMAGE_WIDTH || image.height() >= HEIF_MAX_IMAGE_HEIGHT) {
|
||||||
|
qCWarning(LOG_HEIFPLUGIN) << "Image size invalid:" << image.width() << "x" << image.height();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
startHeifLib();
|
startHeifLib();
|
||||||
|
|
||||||
bool success = write_helper(image);
|
bool success = write_helper(image);
|
||||||
@@ -714,14 +729,17 @@ bool HEIFHandler::ensureDecoder()
|
|||||||
const int imageWidth = heif_image_get_width(img, heif_channel_interleaved);
|
const int imageWidth = heif_image_get_width(img, heif_channel_interleaved);
|
||||||
const int imageHeight = heif_image_get_height(img, heif_channel_interleaved);
|
const int imageHeight = heif_image_get_height(img, heif_channel_interleaved);
|
||||||
|
|
||||||
QSize imageSize(imageWidth, imageHeight);
|
QSize imageSize;
|
||||||
|
if (imageWidth < HEIF_MAX_IMAGE_WIDTH && imageHeight < HEIF_MAX_IMAGE_HEIGHT) {
|
||||||
|
imageSize = QSize(imageWidth, imageHeight);
|
||||||
|
}
|
||||||
|
|
||||||
if (!imageSize.isValid()) {
|
if (!imageSize.isValid()) {
|
||||||
heif_image_release(img);
|
heif_image_release(img);
|
||||||
heif_image_handle_release(handle);
|
heif_image_handle_release(handle);
|
||||||
heif_context_free(ctx);
|
heif_context_free(ctx);
|
||||||
m_parseState = ParseHeicError;
|
m_parseState = ParseHeicError;
|
||||||
qCWarning(LOG_HEIFPLUGIN) << "HEIC image size invalid:" << imageSize;
|
qCWarning(LOG_HEIFPLUGIN) << "HEIC image size invalid:" << imageWidth << "x" << imageHeight;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,11 +65,11 @@ public:
|
|||||||
|
|
||||||
inline int width() const
|
inline int width() const
|
||||||
{
|
{
|
||||||
return (XMax - XMin) + 1;
|
return int(XMax - XMin) + 1;
|
||||||
}
|
}
|
||||||
inline int height() const
|
inline int height() const
|
||||||
{
|
{
|
||||||
return (YMax - YMin) + 1;
|
return int(YMax - YMin) + 1;
|
||||||
}
|
}
|
||||||
inline bool isCompressed() const
|
inline bool isCompressed() const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
* The maximum size in pixel allowed by the plugin.
|
* The maximum size in pixel allowed by the plugin.
|
||||||
*/
|
*/
|
||||||
#ifndef RAW_MAX_IMAGE_WIDTH
|
#ifndef RAW_MAX_IMAGE_WIDTH
|
||||||
#define RAW_MAX_IMAGE_WIDTH std::min(65535, KIF_LARGE_IMAGE_PIXEL_LIMIT)
|
#define RAW_MAX_IMAGE_WIDTH KIF_64K_IMAGE_PIXEL_LIMIT
|
||||||
#endif
|
#endif
|
||||||
#ifndef RAW_MAX_IMAGE_HEIGHT
|
#ifndef RAW_MAX_IMAGE_HEIGHT
|
||||||
#define RAW_MAX_IMAGE_HEIGHT RAW_MAX_IMAGE_WIDTH
|
#define RAW_MAX_IMAGE_HEIGHT RAW_MAX_IMAGE_WIDTH
|
||||||
@@ -759,8 +759,8 @@ bool LoadRAW(QImageIOHandler *handler, QImage &img)
|
|||||||
|
|
||||||
// *** Limiting the maximum image size on a reasonable size
|
// *** Limiting the maximum image size on a reasonable size
|
||||||
auto size = rawImageSize(rawProcessor.get());
|
auto size = rawImageSize(rawProcessor.get());
|
||||||
if (size.width() > RAW_MAX_IMAGE_WIDTH || size.height() > RAW_MAX_IMAGE_HEIGHT) {
|
if (size.width() >= RAW_MAX_IMAGE_WIDTH || size.height() >= RAW_MAX_IMAGE_HEIGHT) {
|
||||||
qCWarning(LOG_RAWPLUGIN) << "The maximum image size is limited to" << RAW_MAX_IMAGE_WIDTH << "x" << RAW_MAX_IMAGE_HEIGHT << "px";
|
qCWarning(LOG_RAWPLUGIN) << "The maximum image size is limited to" << (RAW_MAX_IMAGE_WIDTH - 1) << "x" << (RAW_MAX_IMAGE_HEIGHT - 1) << "px";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,14 @@
|
|||||||
#define KIF_LARGE_IMAGE_PIXEL_LIMIT 300000
|
#define KIF_LARGE_IMAGE_PIXEL_LIMIT 300000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Maximum size for legacy image formats.
|
||||||
|
#define KIF_64K_IMAGE_PIXEL_LIMIT 65536
|
||||||
|
|
||||||
|
#if KIF_LARGE_IMAGE_PIXEL_LIMIT < KIF_64K_IMAGE_PIXEL_LIMIT
|
||||||
|
#undef KIF_LARGE_IMAGE_PIXEL_LIMIT
|
||||||
|
#define KIF_LARGE_IMAGE_PIXEL_LIMIT KIF_64K_IMAGE_PIXEL_LIMIT
|
||||||
|
#endif
|
||||||
|
|
||||||
// Image metadata keys to use in plugins (so they are consistent)
|
// Image metadata keys to use in plugins (so they are consistent)
|
||||||
#define META_KEY_ALTITUDE "Altitude"
|
#define META_KEY_ALTITUDE "Altitude"
|
||||||
#define META_KEY_AUTHOR "Author"
|
#define META_KEY_AUTHOR "Author"
|
||||||
|
|||||||
Reference in New Issue
Block a user