File D122159-FF117.patch of Package firefox

diff -urN firefox-117.0.1-orig/image/decoders/nsJXLDecoder.cpp firefox-117.0.1/image/decoders/nsJXLDecoder.cpp
--- firefox-117.0.1-orig/image/decoders/nsJXLDecoder.cpp	2023-09-23 16:41:18.941986704 +0900
+++ firefox-117.0.1/image/decoders/nsJXLDecoder.cpp	2023-09-23 17:34:55.551908170 +0900
@@ -111,6 +111,7 @@
       input = mBuffer.begin();
       length = mBuffer.length();
     }
+
     JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length));
   }
   mContinue = false;
@@ -126,6 +127,34 @@
         size_t remaining = JxlDecoderReleaseInput(mDecoder.get());
         mBuffer.clear();
         JXL_TRY_BOOL(mBuffer.append(aData + aLength - remaining, remaining));
+
+        if (mNumFrames == 0 && InFrame()) {
+          // If an image was flushed by JxlDecoderFlushImage, then we know that
+          // JXL_DEC_FRAME has already been run and there is a pipe.
+          if (JxlDecoderFlushImage(mDecoder.get()) == JXL_DEC_SUCCESS) {
+            // A full frame partial image is written to the buffer.
+            mPipe.ResetToFirstRow();
+            for (uint8_t* rowPtr = mOutBuffer.begin();
+                 rowPtr < mOutBuffer.end(); rowPtr += mInfo.xsize * mChannels) {
+              uint8_t* rowToWrite = rowPtr;
+
+              if (!mUsePipeTransform && mTransform) {
+                qcms_transform_data(mTransform, rowToWrite, mCMSLine,
+                                    mInfo.xsize);
+                rowToWrite = mCMSLine;
+              }
+
+              mPipe.WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
+            }
+
+            if (Maybe<SurfaceInvalidRect> invalidRect =
+                    mPipe.TakeInvalidRect()) {
+              PostInvalidation(invalidRect->mInputSpaceRect,
+                               Some(invalidRect->mOutputSpaceRect));
+            }
+          }
+        }
+
         return Transition::ContinueUnbuffered(State::JXL_DATA);
       }
 
@@ -231,21 +260,6 @@
           return Transition::TerminateSuccess();
         }
 
-        break;
-      }
-
-      case JXL_DEC_NEED_IMAGE_OUT_BUFFER: {
-        size_t size = 0;
-        JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &mFormat, &size));
-
-        mOutBuffer.clear();
-        JXL_TRY_BOOL(mOutBuffer.growBy(size));
-        JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &mFormat,
-                                            mOutBuffer.begin(), size));
-        break;
-      }
-
-      case JXL_DEC_FULL_IMAGE: {
         OrientedIntSize size(mInfo.xsize, mInfo.ysize);
 
         Maybe<AnimationParams> animParams;
@@ -256,6 +270,11 @@
 
         SurfacePipeFlags pipeFlags = SurfacePipeFlags();
 
+        if (mNumFrames == 0) {
+          // The first frame may be displayed progressively.
+          pipeFlags |= SurfacePipeFlags::PROGRESSIVE_DISPLAY;
+        }
+
         if (mSurfaceFormat == SurfaceFormat::OS_RGBA &&
             !(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) {
           pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA;
@@ -274,6 +293,24 @@
           return Transition::TerminateFailure();
         }
 
+        mPipe = std::move(*pipe);
+
+        break;
+      }
+
+      case JXL_DEC_NEED_IMAGE_OUT_BUFFER: {
+        size_t size = 0;
+        JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &mFormat, &size));
+
+        mOutBuffer.clear();
+        JXL_TRY_BOOL(mOutBuffer.growBy(size));
+        JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &mFormat,
+                                            mOutBuffer.begin(), size));
+        break;
+      }
+
+      case JXL_DEC_FULL_IMAGE: {
+        mPipe.ResetToFirstRow();
         for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end();
              rowPtr += mInfo.xsize * mChannels) {
           uint8_t* rowToWrite = rowPtr;
@@ -283,10 +320,10 @@
             rowToWrite = mCMSLine;
           }
 
-          pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
+          mPipe.WriteBuffer(reinterpret_cast<uint32_t*>(rowToWrite));
         }
 
-        if (Maybe<SurfaceInvalidRect> invalidRect = pipe->TakeInvalidRect()) {
+        if (Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect()) {
           PostInvalidation(invalidRect->mInputSpaceRect,
                            Some(invalidRect->mOutputSpaceRect));
         }
diff -urN firefox-117.0.1-orig/image/decoders/nsJXLDecoder.h firefox-117.0.1/image/decoders/nsJXLDecoder.h
--- firefox-117.0.1-orig/image/decoders/nsJXLDecoder.h	2023-09-23 16:41:18.941986704 +0900
+++ firefox-117.0.1/image/decoders/nsJXLDecoder.h	2023-09-23 17:34:55.551908170 +0900
@@ -58,6 +58,7 @@
   uint32_t mNumFrames;
   FrameTimeout mTimeout;
   gfx::SurfaceFormat mSurfaceFormat;
+  SurfacePipe mPipe;
   bool mContinue;
 };
 
openSUSE Build Service is sponsored by