Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:user5664536:linux
firefox
D122158-FF117.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File D122158-FF117.patch of Package firefox
diff -urN firefox-117.0.1-orig/image/DecoderFactory.cpp firefox-117.0.1/image/DecoderFactory.cpp --- firefox-117.0.1-orig/image/DecoderFactory.cpp 2023-09-12 10:42:00.000000000 +0900 +++ firefox-117.0.1/image/DecoderFactory.cpp 2023-09-23 16:45:47.120595375 +0900 @@ -235,7 +235,12 @@ } MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG || - aType == DecoderType::WEBP || aType == DecoderType::AVIF, + aType == DecoderType::WEBP || aType == DecoderType::AVIF +#ifdef MOZ_JXL + || aType == DecoderType::JXL, +#else + , +#endif "Calling CreateAnimationDecoder for non-animating DecoderType"); // Create an anonymous decoder. Interaction with the SurfaceCache and the @@ -290,7 +295,12 @@ // rediscover it is animated). DecoderType type = aDecoder->GetType(); MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG || - type == DecoderType::WEBP || type == DecoderType::AVIF, + type == DecoderType::WEBP || type == DecoderType::AVIF +#ifdef MOZ_JXL + || type == DecoderType::JXL, +#else + , +#endif "Calling CloneAnimationDecoder for non-animating DecoderType"); RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true); 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:40:10.359785179 +0900 +++ firefox-117.0.1/image/decoders/nsJXLDecoder.cpp 2023-09-23 16:41:18.941986704 +0900 @@ -47,8 +47,12 @@ mParallelRunner( JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())), mUsePipeTransform(true), - mCMSLine(nullptr) { - int events = JXL_DEC_BASIC_INFO | JXL_DEC_FULL_IMAGE; + mCMSLine(nullptr), + mNumFrames(0), + mTimeout(FrameTimeout::Forever()), + mSurfaceFormat(SurfaceFormat::OS_RGBX), + mContinue(false) { + int events = JXL_DEC_BASIC_INFO | JXL_DEC_FRAME | JXL_DEC_FULL_IMAGE; if (mCMSMode != CMSMode::Off) { events |= JXL_DEC_COLOR_ENCODING; @@ -97,14 +101,19 @@ LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData( const char* aData, size_t aLength) { - const uint8_t* input = (const uint8_t*)aData; - size_t length = aLength; - if (mBuffer.length() != 0) { - JXL_TRY_BOOL(mBuffer.append(aData, aLength)); - input = mBuffer.begin(); - length = mBuffer.length(); + // Ignore data we have already read. + // This will only occur as a result of a yield for animation. + if (!mContinue) { + const uint8_t* input = (const uint8_t*)aData; + size_t length = aLength; + if (mBuffer.length() != 0) { + JXL_TRY_BOOL(mBuffer.append(aData, aLength)); + input = mBuffer.begin(); + length = mBuffer.length(); + } + JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length)); } - JXL_TRY(JxlDecoderSetInput(mDecoder.get(), input, length)); + mContinue = false; while (true) { JxlDecoderStatus status = JxlDecoderProcessInput(mDecoder.get()); @@ -125,10 +134,11 @@ PostSize(mInfo.xsize, mInfo.ysize); if (mInfo.alpha_bits > 0) { + mSurfaceFormat = SurfaceFormat::OS_RGBA; PostHasTransparency(); } - if (IsMetadataDecode()) { + if (!mInfo.have_animation && IsMetadataDecode()) { return Transition::TerminateSuccess(); } @@ -147,17 +157,6 @@ 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_COLOR_ENCODING: { size_t size = 0; JXL_TRY(JxlDecoderGetICCProfileSize( @@ -207,16 +206,73 @@ break; } + case JXL_DEC_FRAME: { + if (mInfo.have_animation) { + JXL_TRY(JxlDecoderGetFrameHeader(mDecoder.get(), &mFrameHeader)); + int32_t duration = (int32_t)(1000.0 * mFrameHeader.duration * + mInfo.animation.tps_denominator / + mInfo.animation.tps_numerator); + + mTimeout = FrameTimeout::FromRawMilliseconds(duration); + + if (!HasAnimation()) { + PostIsAnimated(mTimeout); + } + } + + bool is_last = mInfo.have_animation ? mFrameHeader.is_last : true; + MOZ_LOG(sJXLLog, LogLevel::Debug, + ("[this=%p] nsJXLDecoder::ReadJXLData - frame %d, is_last %d, " + "metadata decode %d, first frame decode %d\n", + this, mNumFrames, is_last, IsMetadataDecode(), + IsFirstFrameDecode())); + + if (IsMetadataDecode()) { + 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; + if (!IsFirstFrameDecode()) { + animParams.emplace(FullFrame().ToUnknownRect(), mTimeout, mNumFrames, + BlendMethod::SOURCE, DisposalMethod::CLEAR); + } + + SurfacePipeFlags pipeFlags = SurfacePipeFlags(); + + if (mSurfaceFormat == SurfaceFormat::OS_RGBA && + !(GetSurfaceFlags() & SurfaceFlags::NO_PREMULTIPLY_ALPHA)) { + pipeFlags |= SurfacePipeFlags::PREMULTIPLY_ALPHA; + } + qcms_transform* pipeTransform = mUsePipeTransform ? mTransform : nullptr; Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe( this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8, - SurfaceFormat::OS_RGBA, Nothing(), pipeTransform, - SurfacePipeFlags()); + mSurfaceFormat, animParams, pipeTransform, pipeFlags); + + if (!pipe) { + MOZ_LOG(sJXLLog, LogLevel::Debug, + ("[this=%p] nsJXLDecoder::ReadJXLData - no pipe\n", this)); + return Transition::TerminateFailure(); + } for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end(); rowPtr += mInfo.xsize * mChannels) { @@ -234,8 +290,26 @@ PostInvalidation(invalidRect->mInputSpaceRect, Some(invalidRect->mOutputSpaceRect)); } - PostFrameStop(); - PostDecodeDone(); + + Opacity opacity = mSurfaceFormat == SurfaceFormat::OS_RGBA + ? Opacity::SOME_TRANSPARENCY + : Opacity::FULLY_OPAQUE; + PostFrameStop(opacity); + + if (!IsFirstFrameDecode() && mInfo.have_animation && + !mFrameHeader.is_last) { + mNumFrames++; + mContinue = true; + // Notify for a new frame but there may be data in the current buffer + // that can immediately be processed. + return Transition::ToAfterYield(State::JXL_DATA); + } + [[fallthrough]]; // We are done. + } + + case JXL_DEC_SUCCESS: { + PostDecodeDone(HasAnimation() ? (int32_t)mInfo.animation.num_loops - 1 + : 0); return Transition::TerminateSuccess(); } } 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:40:10.359785179 +0900 +++ firefox-117.0.1/image/decoders/nsJXLDecoder.h 2023-09-23 16:41:18.941986704 +0900 @@ -49,10 +49,16 @@ Vector<uint8_t> mOutBuffer; JxlBasicInfo mInfo; JxlPixelFormat mFormat; + JxlFrameHeader mFrameHeader; bool mUsePipeTransform; uint8_t mChannels; uint8_t* mCMSLine; + + uint32_t mNumFrames; + FrameTimeout mTimeout; + gfx::SurfaceFormat mSurfaceFormat; + bool mContinue; }; } // namespace mozilla::image
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor