[frameworks/kimageformats] src/imageformats: jxl: Do not rewind after reading final frame
Daniel Novomeský <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 458257b7a32417c995d3a95a65b38586eee7a91a by Daniel Novomeský.
Committed on 18/08/2026 at 08:48.
Pushed by novomeskyd into branch 'master'.
jxl: Do not rewind after reading final frame
M +32 -33 src/imageformats/jxl.cpp
M +0 -1 src/imageformats/jxl_p.h
https://invent.kde.org/frameworks/kimageformats/-/commit/458257b7a32417c995d3a95a65b38586eee7a91a
diff --git a/src/imageformats/jxl.cpp b/src/imageformats/jxl.cpp
index 9b23fc82..dbac0f67 100644
--- a/src/imageformats/jxl.cpp
+++ b/src/imageformats/jxl.cpp
@@ -60,7 +60,7 @@ Q_LOGGING_CATEGORY(LOG_JXLPLUGIN, "kf.imageformats.plugins.jxl", QtWarningMsg)
void *QtJXLMemoryManagerAlloc(void *opaque, size_t size)
{
if (opaque) {
- size_t maxBytes = *(size_t*)opaque;
+ size_t maxBytes = *(size_t *)opaque;
if (maxBytes && size > maxBytes)
return NULL;
}
@@ -75,8 +75,7 @@ void QtJXLMemoryManagerFree(void *, void *address)
QJpegXLHandler::QJpegXLHandler()
: m_parseState(ParseJpegXLNotParsed)
, m_quality(90)
- , m_currentimage_index(0)
- , m_previousimage_index(-1)
+ , m_currentimage_index(-1)
, m_transformations(QImageIOHandler::TransformationNone)
, m_decoder(nullptr)
, m_runner(nullptr)
@@ -183,11 +182,7 @@ bool QJpegXLHandler::ensureDecoder()
}
// Creating a simple memory manager
- JxlMemoryManager memory_manager = {
- .opaque = &m_maxBytes,
- .alloc = QtJXLMemoryManagerAlloc,
- .free = QtJXLMemoryManagerFree
- };
+ JxlMemoryManager memory_manager = {.opaque = &m_maxBytes, .alloc = QtJXLMemoryManagerAlloc, .free = QtJXLMemoryManagerFree};
// Creating the decoder (it makes a deep copy of memory manager)
m_decoder = JxlDecoderCreate(&memory_manager);
if (!m_decoder) {
@@ -817,17 +812,11 @@ bool QJpegXLHandler::decode_one_frame()
exif.updateImageMetadata(m_current_image);
}
+ m_currentimage_index++;
m_next_image_delay = m_framedelays[m_currentimage_index];
- m_previousimage_index = m_currentimage_index;
if (m_framedelays.count() > 1) {
- m_currentimage_index++;
-
- if (m_currentimage_index >= m_framedelays.count()) {
- if (!rewind()) {
- return false;
- }
-
+ if (m_currentimage_index >= m_framedelays.count() - 1) {
// all frames in animation have been read
m_parseState = ParseJpegXLFinished;
} else {
@@ -847,9 +836,9 @@ bool QJpegXLHandler::read(QImage *image)
return false;
}
- if (m_currentimage_index == m_previousimage_index) {
- *image = m_current_image;
- return jumpToNextImage();
+ if (m_parseState == ParseJpegXLFinished) {
+ // at the end already
+ return false;
}
if (decode_one_frame()) {
@@ -1757,19 +1746,26 @@ bool QJpegXLHandler::jumpToNextImage()
}
if (m_framedelays.count() > 1) {
- m_currentimage_index++;
-
- if (m_currentimage_index >= m_framedelays.count()) {
- if (!rewind()) {
- return false;
- }
+ if (m_currentimage_index >= (m_framedelays.count() - 1)) {
+ // we are already at the last frame
+ return false;
} else {
+ m_currentimage_index++;
+ m_next_image_delay = m_framedelays[m_currentimage_index];
JxlDecoderSkipFrames(m_decoder, 1);
+ if (m_currentimage_index >= (m_framedelays.count() - 1)) {
+ // last frame reached but no more reading is possible
+ m_parseState = ParseJpegXLFinished;
+ } else {
+ m_parseState = ParseJpegXLSuccess;
+ }
+
+ return true;
}
}
- m_parseState = ParseJpegXLSuccess;
- return true;
+ // static image, there is no next frame
+ return false;
}
bool QJpegXLHandler::jumpToImage(int imageNumber)
@@ -1782,14 +1778,17 @@ bool QJpegXLHandler::jumpToImage(int imageNumber)
return false;
}
- if (imageNumber == m_currentimage_index) {
+ const int next_image_index = m_currentimage_index + 1;
+
+ if (imageNumber == next_image_index) {
+ // This the already the next image to read, no action
m_parseState = ParseJpegXLSuccess;
return true;
}
- if (imageNumber > m_currentimage_index) {
- JxlDecoderSkipFrames(m_decoder, imageNumber - m_currentimage_index);
- m_currentimage_index = imageNumber;
+ if (imageNumber > next_image_index) {
+ JxlDecoderSkipFrames(m_decoder, imageNumber - next_image_index);
+ m_currentimage_index = imageNumber - 1;
m_parseState = ParseJpegXLSuccess;
return true;
}
@@ -1801,7 +1800,7 @@ bool QJpegXLHandler::jumpToImage(int imageNumber)
if (imageNumber > 0) {
JxlDecoderSkipFrames(m_decoder, imageNumber);
}
- m_currentimage_index = imageNumber;
+ m_currentimage_index = imageNumber - 1;
m_parseState = ParseJpegXLSuccess;
return true;
}
@@ -1834,7 +1833,7 @@ int QJpegXLHandler::loopCount() const
bool QJpegXLHandler::rewind()
{
- m_currentimage_index = 0;
+ m_currentimage_index = -1;
JxlDecoderReleaseInput(m_decoder);
JxlDecoderRewind(m_decoder);
diff --git a/src/imageformats/jxl_p.h b/src/imageformats/jxl_p.h
index 5c7300d6..09463f8a 100644
--- a/src/imageformats/jxl_p.h
+++ b/src/imageformats/jxl_p.h
@@ -65,7 +65,6 @@ private:
ParseJpegXLState m_parseState;
int m_quality;
int m_currentimage_index;
- int m_previousimage_index;
QImageIOHandler::Transformations m_transformations;
QByteArray m_rawData;