mirror of
https://invent.kde.org/frameworks/kimageformats.git
synced 2025-05-28 00:30:23 -04:00
avif: new quality settings
Prior libavif 1.0, quality was set using two numbers (minQuantizer and maxQuantizer). New versions of libavif recommend using new/single quality parameter instead. Compression using the new settings is different compared to the old. For example, new quality 68 gives similar compression like old default 52.
This commit is contained in:
parent
ce8383e5fd
commit
da8ed31aec
@ -16,9 +16,34 @@
|
||||
|
||||
#include <cfloat>
|
||||
|
||||
/*
|
||||
Quality range - compression/subsampling
|
||||
100 - lossless RGB compression
|
||||
< KIMG_AVIF_QUALITY_BEST, 100 ) - YUV444 color subsampling
|
||||
< KIMG_AVIF_QUALITY_HIGH, KIMG_AVIF_QUALITY_BEST ) - YUV422 color subsampling
|
||||
< 0, KIMG_AVIF_QUALITY_HIGH ) - YUV420 color subsampling
|
||||
< 0, KIMG_AVIF_QUALITY_LOW ) - lossy compression of alpha channel
|
||||
*/
|
||||
|
||||
#ifndef KIMG_AVIF_DEFAULT_QUALITY
|
||||
#define KIMG_AVIF_DEFAULT_QUALITY 68
|
||||
#endif
|
||||
|
||||
#ifndef KIMG_AVIF_QUALITY_BEST
|
||||
#define KIMG_AVIF_QUALITY_BEST 90
|
||||
#endif
|
||||
|
||||
#ifndef KIMG_AVIF_QUALITY_HIGH
|
||||
#define KIMG_AVIF_QUALITY_HIGH 80
|
||||
#endif
|
||||
|
||||
#ifndef KIMG_AVIF_QUALITY_LOW
|
||||
#define KIMG_AVIF_QUALITY_LOW 51
|
||||
#endif
|
||||
|
||||
QAVIFHandler::QAVIFHandler()
|
||||
: m_parseState(ParseAvifNotParsed)
|
||||
, m_quality(52)
|
||||
, m_quality(KIMG_AVIF_DEFAULT_QUALITY)
|
||||
, m_container_width(0)
|
||||
, m_container_height(0)
|
||||
, m_rawAvifData(AVIF_DATA_EMPTY)
|
||||
@ -519,9 +544,17 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_quality > 100) {
|
||||
m_quality = 100;
|
||||
} else if (m_quality < 0) {
|
||||
m_quality = KIMG_AVIF_DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
#if AVIF_VERSION < 1000000
|
||||
int maxQuantizer = AVIF_QUANTIZER_WORST_QUALITY * (100 - qBound(0, m_quality, 100)) / 100;
|
||||
int minQuantizer = 0;
|
||||
int maxQuantizerAlpha = 0;
|
||||
#endif
|
||||
avifResult res;
|
||||
|
||||
bool save_grayscale; // true - monochrome, false - colors
|
||||
@ -567,13 +600,15 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
break;
|
||||
}
|
||||
|
||||
// quality settings
|
||||
#if AVIF_VERSION < 1000000
|
||||
// deprecated quality settings
|
||||
if (maxQuantizer > 20) {
|
||||
minQuantizer = maxQuantizer - 20;
|
||||
if (maxQuantizer > 40) { // we decrease quality of alpha channel here
|
||||
maxQuantizerAlpha = maxQuantizer - 40;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (save_grayscale && !image.hasAlphaChannel()) { // we are going to save grayscale image without alpha channel
|
||||
if (save_depth > 8) {
|
||||
@ -646,8 +681,8 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
QImage tmpcolorimage = image.convertToFormat(tmpformat);
|
||||
|
||||
avifPixelFormat pixel_format = AVIF_PIXEL_FORMAT_YUV420;
|
||||
if (maxQuantizer < 20) {
|
||||
if (maxQuantizer < 10) {
|
||||
if (m_quality >= KIMG_AVIF_QUALITY_HIGH) {
|
||||
if (m_quality >= KIMG_AVIF_QUALITY_BEST) {
|
||||
pixel_format = AVIF_PIXEL_FORMAT_YUV444; // best quality
|
||||
} else {
|
||||
pixel_format = AVIF_PIXEL_FORMAT_YUV422; // high quality
|
||||
@ -807,6 +842,8 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
avifRWData raw = AVIF_DATA_EMPTY;
|
||||
avifEncoder *encoder = avifEncoderCreate();
|
||||
encoder->maxThreads = qBound(1, QThread::idealThreadCount(), 64);
|
||||
|
||||
#if AVIF_VERSION < 1000000
|
||||
encoder->minQuantizer = minQuantizer;
|
||||
encoder->maxQuantizer = maxQuantizer;
|
||||
|
||||
@ -814,6 +851,17 @@ bool QAVIFHandler::write(const QImage &image)
|
||||
encoder->minQuantizerAlpha = AVIF_QUANTIZER_LOSSLESS;
|
||||
encoder->maxQuantizerAlpha = maxQuantizerAlpha;
|
||||
}
|
||||
#else
|
||||
encoder->quality = m_quality;
|
||||
|
||||
if (image.hasAlphaChannel()) {
|
||||
if (m_quality >= KIMG_AVIF_QUALITY_LOW) {
|
||||
encoder->qualityAlpha = 100;
|
||||
} else {
|
||||
encoder->qualityAlpha = 100 - (KIMG_AVIF_QUALITY_LOW - m_quality) / 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
encoder->speed = 6;
|
||||
|
||||
@ -870,7 +918,7 @@ void QAVIFHandler::setOption(ImageOption option, const QVariant &value)
|
||||
if (m_quality > 100) {
|
||||
m_quality = 100;
|
||||
} else if (m_quality < 0) {
|
||||
m_quality = 52;
|
||||
m_quality = KIMG_AVIF_DEFAULT_QUALITY;
|
||||
}
|
||||
return;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user