[graphics/krita/krita/6.0] libs/ui/animation: Allow iterating encoder frames multiple times
Carsten Hartenfels <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 34760a7870b00ba4baa9dd5c208ee473ad340229 by Carsten Hartenfels.
Committed on 27/07/2026 at 17:19.
Pushed by hartenfels into branch 'krita/6.0'.
Allow iterating encoder frames multiple times
GIF needs this because it must iterate the frames twice: once to create
a palette and then again to actually render the animated image. This
commit allows rewinding the iterator and specifying a ratio for the
progress slider so that it doesn't show 100% when the encoding is only
halfway done.
M +14 -2 libs/ui/animation/KisMediaEncoderWrapper.cpp
M +8 -1 libs/ui/animation/KisMediaEncoderWrapper.h
https://invent.kde.org/graphics/krita/-/commit/34760a7870b00ba4baa9dd5c208ee473ad340229
diff --git a/libs/ui/animation/KisMediaEncoderWrapper.cpp b/libs/ui/animation/KisMediaEncoderWrapper.cpp
index 67c8c95a613..2a2344dcd51 100644
--- a/libs/ui/animation/KisMediaEncoderWrapper.cpp
+++ b/libs/ui/animation/KisMediaEncoderWrapper.cpp
@@ -96,8 +96,12 @@ bool KisMediaEncoderRunnable::nextFrame(Frame &outFrame)
}
if (instances != 0) {
- m_outputFrameNo += instances;
- Q_EMIT sigProgressUpdated(m_outputFrameNo);
+ // GIF must spin through the input frames twice, once to generate a
+ // palette and then again to actually render the animated image. It
+ // sets the multiplier to 0.5 so that the progress bar shows values
+ // that make sense for the user, rather than reaching 100% halfway.
+ m_outputFrameNo += double(instances) * m_outputFrameNoMultiplier;
+ Q_EMIT sigProgressUpdated(int(m_outputFrameNo));
// If we're on the last frame, we can append the linger time.
if (fileIndex == lastIndex && m_needsLingerAfter) {
@@ -122,6 +126,14 @@ bool KisMediaEncoderRunnable::nextFrame(Frame &outFrame)
return false;
}
+void KisMediaEncoderRunnable::rewindFrames()
+{
+ m_inputTime = 0;
+ m_inputFileIndex = 0;
+ m_needsPreviewBefore = true;
+ m_needsLingerAfter = true;
+}
+
KisMediaEncoderRunnable::EncodeResult KisMediaEncoderRunnable::prepareAndEncode(QString &outErrorMessage)
{
if (m_cancel) {
diff --git a/libs/ui/animation/KisMediaEncoderWrapper.h b/libs/ui/animation/KisMediaEncoderWrapper.h
index 2e0a7126fc4..062654d8bfb 100644
--- a/libs/ui/animation/KisMediaEncoderWrapper.h
+++ b/libs/ui/animation/KisMediaEncoderWrapper.h
@@ -111,7 +111,13 @@ protected:
return m_cancel;
}
+ void setOutputFrameNoMultiplier(double outputFrameNoMultiplier)
+ {
+ m_outputFrameNoMultiplier = outputFrameNoMultiplier;
+ }
+
bool nextFrame(Frame &outFrame);
+ void rewindFrames();
private:
EncodeResult prepareAndEncode(QString &outErrorMessage);
@@ -119,7 +125,8 @@ private:
KisMediaEncoderWrapperSettings m_settings;
double m_inputTime = 0.0;
int m_inputFileIndex = 0;
- int m_outputFrameNo = 0;
+ double m_outputFrameNo = 0.0;
+ double m_outputFrameNoMultiplier = 1.0;
bool m_needsPreviewBefore = true;
bool m_needsLingerAfter = true;
bool m_cancel = false;