Merge remote-tracking branch 'origin/tracking' into custom

This commit is contained in:
2026-02-20 08:56:07 +08:00
40 changed files with 495 additions and 187 deletions
+51 -11
View File
@@ -375,6 +375,9 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
case TrackType::kVideoTrack: {
// Decoders use the layers backend to decide if they can use hardware decoding,
// so specify LAYERS_NONE if we want to forcibly disable it.
using Option = CreateDecoderParams::Option;
using OptionSet = CreateDecoderParams::OptionSet;
data.mDecoder = mOwner->mPlatform->CreateDecoder({
ownerData.mInfo
? *ownerData.mInfo->GetAsVideoInfo()
@@ -385,7 +388,10 @@ MediaFormatReader::DecoderFactory::DoCreateDecoder(TrackType aTrack)
mOwner->GetImageContainer(),
mOwner->mCrashHelper,
ownerData.mIsBlankDecode,
&result
&result,
OptionSet(ownerData.mHardwareDecodingDisabled
? Option::HardwareDecoderNotAllowed
: Option::Default)
});
break;
}
@@ -980,6 +986,8 @@ MediaFormatReader::NotifyNewOutput(TrackType aTrack, MediaData* aSample)
decoder.mOutput.AppendElement(aSample);
decoder.mNumSamplesOutput++;
decoder.mNumOfConsecutiveError = 0;
// We have decoded our first frame, we can now start to skip future errors.
decoder.mFirstFrameTime.reset();
ScheduleUpdate(aTrack);
}
@@ -1474,7 +1482,7 @@ MediaFormatReader::Update(TrackType aTrack)
RefPtr<MediaData> output = decoder.mOutput[0];
decoder.mOutput.RemoveElementAt(0);
decoder.mSizeOfQueue -= 1;
decoder.mLastSampleTime =
decoder.mLastDecodedSampleTime =
Some(TimeInterval(TimeUnit::FromMicroseconds(output->mTime),
TimeUnit::FromMicroseconds(output->GetEndTime())));
decoder.mNumSamplesOutputTotal++;
@@ -1522,14 +1530,14 @@ MediaFormatReader::Update(TrackType aTrack)
LOG("Rejecting %s promise: EOS", TrackTypeToStr(aTrack));
decoder.RejectPromise(NS_ERROR_DOM_MEDIA_END_OF_STREAM, __func__);
} else if (decoder.mWaitingForData) {
if (wasDraining && decoder.mLastSampleTime &&
if (wasDraining && decoder.mLastDecodedSampleTime &&
!decoder.mNextStreamSourceID) {
// We have completed draining the decoder following WaitingForData.
// Set up the internal seek machinery to be able to resume from the
// last sample decoded.
LOG("Seeking to last sample time: %lld",
decoder.mLastSampleTime.ref().mStart.ToMicroseconds());
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastSampleTime.ref(), true));
decoder.mLastDecodedSampleTime.ref().mStart.ToMicroseconds());
InternalSeek(aTrack, InternalSeekTarget(decoder.mLastDecodedSampleTime.ref(), true));
}
if (!decoder.mReceivedNewData) {
LOG("Rejecting %s promise: WAITING_FOR_DATA", TrackTypeToStr(aTrack));
@@ -1565,24 +1573,52 @@ MediaFormatReader::Update(TrackType aTrack)
if (decoder.mError && !decoder.HasFatalError()) {
decoder.mDecodePending = false;
bool needsNewDecoder = decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER;
MOZ_RELEASE_ASSERT(!decoder.HasInternalSeekPending(),
"No error can occur while an internal seek is pending");
nsCString error;
bool firstFrameDecodingFailedWithHardware =
decoder.mFirstFrameTime &&
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_DECODE_ERR &&
decoder.mDecoder && decoder.mDecoder->IsHardwareAccelerated(error) &&
!decoder.mHardwareDecodingDisabled;
bool needsNewDecoder =
decoder.mError.ref() == NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER ||
firstFrameDecodingFailedWithHardware;
if (!needsNewDecoder && ++decoder.mNumOfConsecutiveError > decoder.mMaxConsecutiveError) {
NotifyError(aTrack, decoder.mError.ref());
return;
}
if (firstFrameDecodingFailedWithHardware) {
decoder.mHardwareDecodingDisabled = true;
}
decoder.mError.reset();
LOG("%s decoded error count %d", TrackTypeToStr(aTrack),
decoder.mNumOfConsecutiveError);
if (needsNewDecoder) {
LOG("Error: Need new decoder");
decoder.ShutdownDecoder();
}
if (decoder.mFirstFrameTime) {
TimeInterval seekInterval = TimeInterval(decoder.mFirstFrameTime.ref(),
decoder.mFirstFrameTime.ref());
InternalSeek(aTrack, InternalSeekTarget(seekInterval, false));
return;
}
media::TimeUnit nextKeyframe;
if (aTrack == TrackType::kVideoTrack && !decoder.HasInternalSeekPending() &&
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe))) {
if (needsNewDecoder) {
decoder.ShutdownDecoder();
}
SkipVideoDemuxToNextKeyFrame(decoder.mLastSampleTime.refOr(TimeInterval()).Length());
NS_SUCCEEDED(decoder.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe)) &&
!nextKeyframe.IsInfinite()) {
SkipVideoDemuxToNextKeyFrame(decoder.mLastDecodedSampleTime.refOr(TimeInterval()).Length());
return;
} else if (aTrack == TrackType::kAudioTrack) {
decoder.Flush();
} else {
// We can't recover from this error.
NotifyError(aTrack, NS_ERROR_DOM_MEDIA_FATAL_ERR);
}
}
@@ -1723,6 +1759,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
if (HasVideo() && aTracks.contains(TrackInfo::kVideoTrack)) {
mVideo.ResetDemuxer();
mVideo.mFirstFrameTime = Some(media::TimeUnit());
Reset(TrackInfo::kVideoTrack);
if (mVideo.HasPromise()) {
mVideo.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
@@ -1731,6 +1768,7 @@ MediaFormatReader::ResetDecode(TrackSet aTracks)
if (HasAudio() && aTracks.contains(TrackInfo::kAudioTrack)) {
mAudio.ResetDemuxer();
mVideo.mFirstFrameTime = Some(media::TimeUnit());
Reset(TrackInfo::kAudioTrack);
if (mAudio.HasPromise()) {
mAudio.RejectPromise(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
@@ -2089,6 +2127,7 @@ MediaFormatReader::OnVideoSeekCompleted(media::TimeUnit aTime)
LOGV("Video seeked to %lld", aTime.ToMicroseconds());
mVideo.mSeekRequest.Complete();
mVideo.mFirstFrameTime = Some(aTime);
mPreviousDecodedKeyframeTime_us = sNoPreviousDecodedKeyframe;
SetVideoDecodeThreshold();
@@ -2170,6 +2209,7 @@ MediaFormatReader::OnAudioSeekCompleted(media::TimeUnit aTime)
MOZ_ASSERT(OnTaskQueue());
LOGV("Audio seeked to %lld", aTime.ToMicroseconds());
mAudio.mSeekRequest.Complete();
mAudio.mFirstFrameTime = Some(aTime);
mPendingSeekTime.reset();
mSeekPromise.Resolve(aTime, __func__);
}
+11 -3
View File
@@ -241,6 +241,7 @@ private:
, mDrainComplete(false)
, mNumOfConsecutiveError(0)
, mMaxConsecutiveError(aNumOfMaxError)
, mFirstFrameTime(Some(media::TimeUnit()))
, mNumSamplesInput(0)
, mNumSamplesOutput(0)
, mNumSamplesOutputTotal(0)
@@ -249,6 +250,7 @@ private:
, mIsHardwareAccelerated(false)
, mLastStreamSourceID(UINT32_MAX)
, mIsBlankDecode(false)
, mHardwareDecodingDisabled(false)
{}
MediaFormatReader* mOwner;
@@ -322,6 +324,11 @@ private:
uint32_t mNumOfConsecutiveError;
uint32_t mMaxConsecutiveError;
// Set when we haven't yet decoded the first frame.
// Cleared once the first frame has been decoded.
// This is used to determine, upon error, if we should try again to decode
// the frame, or skip to the next keyframe.
Maybe<media::TimeUnit> mFirstFrameTime;
Maybe<MediaResult> mError;
bool HasFatalError() const
@@ -347,8 +354,8 @@ private:
// Used for internal seeking when a change of stream is detected or when
// encountering data discontinuity.
Maybe<InternalSeekTarget> mTimeThreshold;
// Time of last sample returned.
Maybe<media::TimeInterval> mLastSampleTime;
// Time of last decoded sample returned.
Maybe<media::TimeInterval> mLastDecodedSampleTime;
// Decoded samples returned my mDecoder awaiting being returned to
// state machine upon request.
@@ -411,7 +418,7 @@ private:
mDraining = false;
mDrainComplete = false;
mTimeThreshold.reset();
mLastSampleTime.reset();
mLastDecodedSampleTime.reset();
mOutput.Clear();
mNumSamplesInput = 0;
mNumSamplesOutput = 0;
@@ -443,6 +450,7 @@ private:
Maybe<media::TimeUnit> mFirstDemuxedSampleTime;
// Use BlankDecoderModule or not.
bool mIsBlankDecode;
bool mHardwareDecodingDisabled;
};
@@ -11,6 +11,7 @@
#include "ImageContainer.h"
#include "MediaDecoderReader.h"
#include "MediaInfo.h"
#include "mozilla/EnumSet.h"
#include "mozilla/MozPromise.h"
#include "mozilla/layers/LayersTypes.h"
#include "mozilla/layers/KnowsCompositor.h"
@@ -47,6 +48,13 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
: mConfig(aConfig)
{}
enum class Option
{
Default,
HardwareDecoderNotAllowed,
};
using OptionSet = EnumSet<Option>;
template <typename T1, typename... Ts>
CreateDecoderParams(const TrackInfo& aConfig, T1&& a1, Ts&&... args)
: mConfig(aConfig)
@@ -83,6 +91,7 @@ struct MOZ_STACK_CLASS CreateDecoderParams final {
RefPtr<layers::KnowsCompositor> mKnowsCompositor;
RefPtr<GMPCrashHelper> mCrashHelper;
bool mUseBlankDecoder = false;
OptionSet mOptions = OptionSet(Option::Default);
private:
void Set(TaskQueue* aTaskQueue) { mTaskQueue = aTaskQueue; }
@@ -92,6 +101,7 @@ private:
void Set(MediaResult* aError) { mError = aError; }
void Set(GMPCrashHelper* aCrashHelper) { mCrashHelper = aCrashHelper; }
void Set(bool aUseBlankDecoder) { mUseBlankDecoder = aUseBlankDecoder; }
void Set(OptionSet aOptions) { mOptions = aOptions; }
void Set(layers::KnowsCompositor* aKnowsCompositor) { mKnowsCompositor = aKnowsCompositor; }
template <typename T1, typename T2, typename... Ts>
void Set(T1&& a1, T2&& a2, Ts&&... args)
@@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "VPXDecoder.h"
#include "mp4_demuxer/BitReader.h"
#include "gfx2DGlue.h"
#include "nsError.h"
#include "TimeUnits.h"
@@ -383,5 +384,32 @@ VPXDecoder::GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec)
return nsIntSize(si.w, si.h);
}
/* static */
int
VPXDecoder::GetVP9Profile(Span<const uint8_t> aBuffer)
{
if (aBuffer.Length() < 2) {
// Can't be good.
return -1;
}
mp4_demuxer::BitReader br(aBuffer.Elements(), aBuffer.Length() * 8);
uint32_t frameMarker = br.ReadBits(2); // frame_marker
if (frameMarker != 2) {
// That's not a valid vp9 header.
return -1;
}
uint32_t profile = br.ReadBits(1); // profile_low_bit
profile |= br.ReadBits(1) << 1; // profile_high_bit
if (profile == 3) {
profile += br.ReadBits(1); // reserved_zero
if (profile > 3) {
// reserved_zero wasn't zero.
return -1;
}
}
return profile;
}
} // namespace mozilla
#undef LOG
@@ -53,6 +53,10 @@ public:
// Return the frame dimensions for a sample for the specified codec.
static nsIntSize GetFrameSize(Span<const uint8_t> aBuffer, Codec aCodec);
// Return the VP9 profile as per https://www.webmproject.org/vp9/profiles/
// Return negative value if error.
static int GetVP9Profile(Span<const uint8_t> aBuffer);
private:
void ProcessDecode(MediaRawData* aSample);
MediaResult DoDecode(MediaRawData* aSample);
+6 -5
View File
@@ -91,11 +91,12 @@ WMFDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
return nullptr;
}
nsAutoPtr<WMFVideoMFTManager> manager(
new WMFVideoMFTManager(aParams.VideoConfig(),
aParams.mKnowsCompositor,
aParams.mImageContainer,
sDXVAEnabled));
nsAutoPtr<WMFVideoMFTManager> manager(new WMFVideoMFTManager(
aParams.VideoConfig(),
aParams.mKnowsCompositor,
aParams.mImageContainer,
sDXVAEnabled && !aParams.mOptions.contains(
CreateDecoderParams::Option::HardwareDecoderNotAllowed)));
if (!manager->Init()) {
return nullptr;
@@ -557,6 +557,16 @@ WMFVideoMFTManager::Input(MediaRawData* aSample)
return E_FAIL;
}
if (mStreamType == VP9 && aSample->mKeyframe) {
// Check the VP9 profile. the VP9 MFT can only handle correctly profile 0
// and 2 (yuv420 8/10/12 bits)
int profile =
VPXDecoder::GetVP9Profile(MakeSpan(aSample->Data(), aSample->Size()));
if (profile != 0 && profile != 2) {
return E_FAIL;
}
}
HRESULT hr = mDecoder->CreateInputSample(aSample->Data(),
uint32_t(aSample->Size()),
aSample->mTime,
+11
View File
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.11.2] - 2026-02-10
### Fixed
- fix tile dimension in low memory rendering pipeline (#4495 -
[CVE-2025-12474](https://www.cve.org/cverecord?id=CVE-2025-12474))
- fix number of channels for gray-to-gray color transform (#4579 -
[CVE-2026-1837](https://www.cve.org/cverecord?id=CVE-2026-1837))
- `djxl`: reject decoding JXL files if "packed" representation size overflows
`size_t` (#4589 - thanks to Mateusz Jurczyk of Google Project Zero for
identifying this issue)
## [0.11.1] - 2024-26-11
### Fixed
+18 -4
View File
@@ -3,10 +3,24 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "giflib", version = "5.2.1")
module(
name = "libjxl",
repo_name = "libjxl",
)
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "brotli", version = "1.1.0")
bazel_dep(name = "giflib", version = "5.2.1.bcr.1")
bazel_dep(name = "googletest", version = "1.14.0")
bazel_dep(name = "libjpeg_turbo", version = "2.1.91")
bazel_dep(name = "libpng", version = "1.6.40")
bazel_dep(name = "libwebp", version = "1.3.2")
bazel_dep(name = "libpng", version = "1.6.50.bcr.1")
bazel_dep(name = "libwebp", version = "1.6.0")
bazel_dep(name = "openexr", version = "3.2.1")
bazel_dep(name = "skcms", version = "20250916.0")
# Requires patching `MODULE.bazel` and `BUILD` files
bazel_dep(name = "highway", version = "1.2.0")
local_path_override(
module_name = "highway",
path = "third_party/highway",
)
+162 -56
View File
@@ -1,132 +1,238 @@
{
"lockFileVersion": 11,
"lockFileVersion": 18,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
"https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
"https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
"https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
"https://bcr.bazel.build/modules/abseil-cpp/20230125.1/source.json": "06cc0842d241da0c5edc755edb3c7d0d008d304330e57ecf2d6449fb0b633a82",
"https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
"https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
"https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/source.json": "750d5e29326fb59cbe61116a7b803c8a1d0a7090a9c8ed89888d188e3c473fc7",
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
"https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442",
"https://bcr.bazel.build/modules/apple_support/1.23.1/source.json": "d888b44312eb0ad2c21a91d026753f330caa48a25c9b2102fae75eb2b0dcfdd2",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
"https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
"https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
"https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
"https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
"https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65",
"https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87",
"https://bcr.bazel.build/modules/bazel_features/1.30.0/source.json": "b07e17f067fe4f69f90b03b36ef1e08fe0d1f3cac254c1241a1818773e3423bc",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
"https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
"https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb",
"https://bcr.bazel.build/modules/brotli/1.1.0/MODULE.bazel": "3b5b90488995183419c4b5c9b063a164f6c0bc4d0d6b40550a612a5e860cc0fe",
"https://bcr.bazel.build/modules/brotli/1.1.0/source.json": "098a4fd315527166e8dfe1fd1537c96a737a83764be38fc43f4da231d600f3d0",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/giflib/5.2.1/MODULE.bazel": "810dbc4275425c89ffe648dd78c537fe2eb1d2a9704d10e950b295263af03366",
"https://bcr.bazel.build/modules/giflib/5.2.1/source.json": "94215af981976c329eaec0083727b155ea89607e61debea50ed508e7963ef9a6",
"https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
"https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
"https://bcr.bazel.build/modules/googletest/1.14.0/source.json": "2478949479000fdd7de9a3d0107ba2c85bb5f961c3ecb1aa448f52549ce310b5",
"https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108",
"https://bcr.bazel.build/modules/googletest/1.15.2/source.json": "dbdda654dcb3a0d7a8bc5d0ac5fc7e150b58c2a986025ae5bc634bb2cb61f470",
"https://bcr.bazel.build/modules/imath/3.1.9/MODULE.bazel": "26fe47ee8137a4c605667fb0d26a5c12b8fb2e758824a376789b287b2f9d424d",
"https://bcr.bazel.build/modules/imath/3.1.9/source.json": "22b7d9e617d4d26626f5ac8fba3cd2bd7a87f7501c99fa847f8d9e2980416e8f",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
"https://bcr.bazel.build/modules/libdeflate/1.19/MODULE.bazel": "b7396a2edfd5ce6669509fbdd10db5e8731d60954063699c546c3126c8156824",
"https://bcr.bazel.build/modules/libdeflate/1.19/source.json": "d4604a526efba9b5347309de49673bbe152da465f7c80c7f7ffe6800d8b504d1",
"https://bcr.bazel.build/modules/libjpeg_turbo/2.1.91/MODULE.bazel": "bcc23b7c4866af2d7777ee49db435603ca1e35b90ea0689f8051900fa8c73c6b",
"https://bcr.bazel.build/modules/libjpeg_turbo/2.1.91/source.json": "42ea85708058e2408f229075e1cbeaad13fa2719918ff9c505be5e22b57ef17b",
"https://bcr.bazel.build/modules/libpng/1.6.40/MODULE.bazel": "cc1952a9b5efd4df3dfdb9f9ba2b1c8d88b4fd9b0e474185cb81d90a31c7c453",
"https://bcr.bazel.build/modules/libpng/1.6.40/source.json": "2fe294bf161c2d3f1e04e7cecb6eb2e6c0c198698b23cabc1c4e6ff77d82a86a",
"https://bcr.bazel.build/modules/libwebp/1.3.2/MODULE.bazel": "c60edf34a913daebac9bd2cbe17b84048e4a7a5d3571f70be93c1b1227a69659",
"https://bcr.bazel.build/modules/libwebp/1.3.2/source.json": "e7b8d3047ad9758fda22fcf46bd8b57414b0eb5e7903f4ce888683d778633cf7",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/libpng/1.6.50.bcr.1/MODULE.bazel": "5a5bef9f8b723d04b194b80071b927653a4064379bb6673c829fd3c14828fba0",
"https://bcr.bazel.build/modules/libpng/1.6.50.bcr.1/source.json": "90245ae3e111b84da48061935c3f6ebc658e3c87e5bd8c6e2f19cd7eec43203a",
"https://bcr.bazel.build/modules/libwebp/1.6.0/MODULE.bazel": "b541e9026102a85fa3b5ec890e20f186e1664a06ab0f876bbfb3165f81c9b5df",
"https://bcr.bazel.build/modules/libwebp/1.6.0/source.json": "ff540383b07271ba7d1a3ebe332dd0910a92dc13cd16e525305205526559ee6f",
"https://bcr.bazel.build/modules/openexr/3.2.1/MODULE.bazel": "5665fa95490825760943601d618e2d70eb45378ea3f2961c5ec18f23ae8a2106",
"https://bcr.bazel.build/modules/openexr/3.2.1/source.json": "afc17dda6614ff723cc1def634fa4f33534d3d29514b089fa4aa5eb47ba1c65b",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
"https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
"https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
"https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
"https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
"https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
"https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
"https://bcr.bazel.build/modules/platforms/0.0.9/source.json": "cd74d854bf16a9e002fb2ca7b1a421f4403cda29f824a765acd3a8c56f8d43e6",
"https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580",
"https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96",
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
"https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
"https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
"https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
"https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
"https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680",
"https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
"https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa",
"https://bcr.bazel.build/modules/re2/2024-07-02/source.json": "547d0111a9d4f362db32196fef805abbf3676e8d6afbe44d395d87816c1130ca",
"https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
"https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
"https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
"https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
"https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
"https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
"https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513",
"https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0",
"https://bcr.bazel.build/modules/rules_cc/0.1.2/source.json": "53fcb09b5816c83ca60d9d7493faf3bfaf410dfc2f15deb52d6ddd146b8d43f0",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
"https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
"https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
"https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
"https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
"https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
"https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
"https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
"https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/7.6.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362",
"https://bcr.bazel.build/modules/rules_java/8.14.0/MODULE.bazel": "717717ed40cc69994596a45aec6ea78135ea434b8402fb91b009b9151dd65615",
"https://bcr.bazel.build/modules/rules_java/8.14.0/source.json": "8a88c4ca9e8759da53cddc88123880565c520503321e2566b4e33d0287a3d4bc",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
"https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/source.json": "a075731e1b46bc8425098512d038d416e966ab19684a10a34f4741295642fc35",
"https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
"https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
"https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
"https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
"https://bcr.bazel.build/modules/rules_jvm_external/6.3/source.json": "6f5f5a5a4419ae4e37c35a5bb0a6ae657ed40b7abc5a5189111b47fcebe43197",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
"https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
"https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
"https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
"https://bcr.bazel.build/modules/rules_license/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a",
"https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
"https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
"https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/source.json": "d57902c052424dfda0e71646cb12668d39c4620ee0544294d9d941e7d12bc3a9",
"https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483",
"https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
"https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
"https://bcr.bazel.build/modules/rules_python/0.22.1/source.json": "57226905e783bae7c37c2dd662be078728e48fa28ee4324a7eabcafb5a43d014",
"https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
"https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
"https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
"https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
"https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937",
"https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
"https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
"https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/source.json": "7f27af3c28037d9701487c4744b5448d26537cc66cdef0d8df7ae85411f8de95",
"https://bcr.bazel.build/modules/skcms/20250916.0/MODULE.bazel": "4dd6405c5c5220e0d1ea218094a2f1541acceaf85e066747ec94878c9553a07f",
"https://bcr.bazel.build/modules/skcms/20250916.0/source.json": "f979e9985009d3d8913dd7b211e6ae4ec0152fdd70ef1d5dc4538a5abaa93df8",
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
"https://bcr.bazel.build/modules/stardoc/0.5.1/source.json": "a96f95e02123320aa015b956f29c00cb818fa891ef823d55148e1a362caacf29",
"https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
"https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
"https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
"https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
"https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459",
"https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
"https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
"https://bcr.bazel.build/modules/zlib/1.3/MODULE.bazel": "6a9c02f19a24dcedb05572b2381446e27c272cd383aed11d41d99da9e3167a72",
"https://bcr.bazel.build/modules/zlib/1.3/source.json": "b6b43d0737af846022636e6e255fd4a96fee0d34f08f3830e6e0bac51465c37c"
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.6/MODULE.bazel": "e937cf0a3772f93ad91f3c7af4f330b76a878bbfee06527ca1a9673b790eb896",
"https://bcr.bazel.build/modules/zlib/1.3.1.bcr.6/source.json": "5f397158198f338129c865a4c3ae21bc5626a9664b3c3b40fa3b3c2ec1ff83bf",
"https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
},
"selectedYankedVersions": {},
"moduleExtensions": {
"@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
"@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
"general": {
"bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=",
"usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
"bzlTransitiveDigest": "OlvsB0HsvxbR8ZN+J9Vf00X/+WVz/Y/5Xrq2LgcVfdo=",
"usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"local_config_apple_cc": {
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
"ruleClassName": "_apple_cc_autoconf",
"attributes": {}
"com_github_jetbrains_kotlin_git": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
"attributes": {
"urls": [
"https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
],
"sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
}
},
"local_config_apple_cc_toolchains": {
"bzlFile": "@@apple_support~//crosstool:setup.bzl",
"ruleClassName": "_apple_cc_autoconf_toolchains",
"attributes": {}
"com_github_jetbrains_kotlin": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
"attributes": {
"git_repository_name": "com_github_jetbrains_kotlin_git",
"compiler_version": "1.9.23"
}
},
"com_github_google_ksp": {
"repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
"attributes": {
"urls": [
"https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
],
"sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
"strip_version": "1.9.23-1.0.20"
}
},
"com_github_pinterest_ktlint": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
"urls": [
"https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
],
"executable": true
}
},
"rules_android": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
"strip_prefix": "rules_android-0.1.1",
"urls": [
"https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
]
}
}
},
"recordedRepoMappingEntries": [
[
"apple_support~",
"rules_kotlin+",
"bazel_tools",
"bazel_tools"
]
]
}
},
"@@platforms//host:extension.bzl%host_platform": {
"general": {
"bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
"usagesDigest": "meSzxn3DUCcYEhq4HQwExWkWtU4EjriRBQLsZN+Q0SU=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"host_platform": {
"bzlFile": "@@platforms//host:extension.bzl",
"ruleClassName": "host_platform_repo",
"attributes": {}
}
},
"recordedRepoMappingEntries": []
}
}
}
}
+16 -2
View File
@@ -15,6 +15,10 @@ OS=`uname -s`
SELF=$(realpath "$0")
MYDIR=$(dirname "${SELF}")
### Colors
TEXT_BOLD_PURPLE="\033[1;35m"
TEXT_RESET="\033[0m"
### Environment parameters:
TEST_STACK_LIMIT="${TEST_STACK_LIMIT:-256}"
BENCHMARK_NUM_THREADS="${BENCHMARK_NUM_THREADS:-0}"
@@ -40,6 +44,7 @@ fi
POST_MESSAGE_ON_ERROR="${POST_MESSAGE_ON_ERROR:-1}"
# By default, do a lightweight debian HWY package build.
HWY_PKG_OPTIONS="${HWY_PKG_OPTIONS:---set-envvar=HWY_EXTRA_CONFIG=-DBUILD_TESTING=OFF -DHWY_ENABLE_EXAMPLES=OFF -DHWY_ENABLE_CONTRIB=OFF}"
EXCLUDE_DEBIAN_PACKAGES="${EXCLUDE_DEBIAN_PACKAGES:-}"
# Set default compilers to clang if not already set
export CC=${CC:-clang}
@@ -708,7 +713,9 @@ cmd_msan_install() {
["15"]="15.0.7"
["16"]="16.0.6"
["17"]="17.0.6"
["18"]="18.1.6"
["18"]="18.1.8"
["19"]="19.1.7"
["20"]="20.1.2"
)
local llvm_tag="${CLANG_VERSION}.0.0"
if [[ -n "${llvm_tag_by_version["${CLANG_VERSION}"]}" ]]; then
@@ -1221,6 +1228,8 @@ cmd_lint() {
echo 'To fix them run (from the base directory):' >&2
echo ' buildifier `git ls-files | grep -E "/BUILD$|WORKSPACE|.bzl$"`' >&2
fi
else
echo -e "${TEXT_BOLD_PURPLE}SKIPPED:${TEXT_RESET} buildifier (not installed)"
fi
# It is ok, if spell-checker is not installed.
@@ -1229,7 +1238,7 @@ cmd_lint() {
local sources=`git -C "${MYDIR}" ls-files | grep -E "\.(${src_ext})$"`
typos -c "${MYDIR}/tools/scripts/typos.toml" ${sources}
else
echo "Consider installing https://github.com/crate-ci/typos for spell-checking"
echo -e "${TEXT_BOLD_PURPLE}SKIPPED:${TEXT_RESET} typos not installed; try: cargo install typos-cli"
fi
local installed=()
@@ -1370,6 +1379,11 @@ build_debian_pkg() {
ln -s "${srcdir}/$f" "${builddir}/$f"
fi
done
if [[ -n "${EXCLUDE_DEBIAN_PACKAGES}" ]]; then
# TODO(eustas): support comma-separated list
rm -f "${builddir}"/debian/${EXCLUDE_DEBIAN_PACKAGES}.install
sed -i "/Package: ${EXCLUDE_DEBIAN_PACKAGES}/,/\n/d" "${builddir}"/debian/control
fi
(
cd "${builddir}"
debuild "${options}" -b -uc -us
+7 -1
View File
@@ -1,4 +1,10 @@
jpeg-xl (0.11.1) UNRELEASED; urgency=medium
jpeg-xl (0.11.2) UNRELEASED; urgency=medium
* Bump JPEG XL version to 0.11.2.
-- JPEG XL Maintainers <jpegxl@google.com> Mon, 09 Feb 2026 21:37:21 +0100
jpeg-xl (0.11.1) unstable; urgency=medium
* Bump JPEG XL version to 0.11.1.
+1 -1
View File
@@ -10,7 +10,7 @@ Build-Depends:
libbrotli-dev,
libgdk-pixbuf-2.0-dev | libgdk-pixbuf2.0-dev,
libgif-dev,
libgimp2.0-dev,
libgimp2.0-dev | base-files (>= 13.8),
libgoogle-perftools-dev,
libgtest-dev,
libhwy-dev (>= 1.0.0),
+5 -5
View File
@@ -16,12 +16,12 @@ MYDIR=$(dirname "${SELF}")
# update a git submodule.
TESTDATA="873045a9c42ed60721756e26e2a6b32e17415205"
THIRD_PARTY_BROTLI="36533a866ed1ca4b75cf049f4521e4ec5fe24727"
THIRD_PARTY_GOOGLETEST="58d77fa8070e8cec2dc1ed015d66b454c8d78850"
THIRD_PARTY_HIGHWAY="457c891775a7397bdb0376bb1031e6e027af1c48"
THIRD_PARTY_SKCMS="42030a771244ba67f86b1c1c76a6493f873c5f91"
THIRD_PARTY_SJPEG="e5ab13008bb214deb66d5f3e17ca2f8dbff150bf"
THIRD_PARTY_GOOGLETEST="6910c9d9165801d8827d628cb72eb7ea9dd538c5" # v1.16.0
THIRD_PARTY_HIGHWAY="457c891775a7397bdb0376bb1031e6e027af1c48" # v1.2.0
THIRD_PARTY_SKCMS="b2e692629c1fb19342517d7fb61f1cf83d075492"
THIRD_PARTY_SJPEG="94e0df6d0f8b44228de5be0ff35efb9f946a13c9" # Wed Apr 2 15:42:02 2025 -0700
THIRD_PARTY_ZLIB="51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf" # v1.3.1
THIRD_PARTY_LIBPNG="f135775ad4e5d4408d2e12ffcc71bb36e6b48551" # v1.6.40
THIRD_PARTY_LIBPNG="872555f4ba910252783af1507f9e7fe1653be252" # v1.6.47
THIRD_PARTY_LIBJPEG_TURBO="8ecba3647edb6dd940463fedf38ca33a8e2a73d1" # 2.1.5.1
# Download the target revision from GitHub.
+1 -1
View File
@@ -5,7 +5,7 @@
set(JPEGXL_MAJOR_VERSION 0)
set(JPEGXL_MINOR_VERSION 11)
set(JPEGXL_PATCH_VERSION 1)
set(JPEGXL_PATCH_VERSION 2)
set(JPEGXL_LIBRARY_VERSION
"${JPEGXL_MAJOR_VERSION}.${JPEGXL_MINOR_VERSION}.${JPEGXL_PATCH_VERSION}")
@@ -36,6 +36,7 @@ class PackedImage {
public:
static StatusOr<PackedImage> Create(size_t xsize, size_t ysize,
const JxlPixelFormat& format) {
JXL_RETURN_IF_ERROR(VerifyDimensions(xsize, ysize, format));
PackedImage image(xsize, ysize, format, CalcStride(format, xsize));
if (!image.pixels()) {
// TODO(szabadka): use specialized OOM error code
@@ -149,6 +150,28 @@ class PackedImage {
}
}
static Status VerifyDimensions(size_t xsize, size_t ysize,
const JxlPixelFormat& format) {
size_t multiplier = (BitsPerChannel(format.data_type) *
format.num_channels / jxl::kBitsPerByte);
size_t stride = xsize * multiplier;
if ((stride / multiplier) != xsize) {
return JXL_FAILURE("Image too big");
}
if (format.align > 1) {
size_t aligned_stride = jxl::DivCeil(stride, format.align) * format.align;
if (stride > aligned_stride) {
return JXL_FAILURE("Image too big");
}
stride = aligned_stride;
}
size_t pixels_size = ysize * stride;
if ((pixels_size / stride) != ysize) {
return JXL_FAILURE("Image too big");
}
return true;
}
private:
PackedImage(size_t xsize, size_t ysize, const JxlPixelFormat& format,
size_t stride)
+1 -1
View File
@@ -352,7 +352,7 @@ typedef enum {
*
* When using streaming input and output the encoder minimizes memory usage at
* the cost of compression density. Also note that images produced with
* streaming mode might not be progressively decodeable.
* streaming mode might not be progressively decodable.
*/
JXL_ENC_FRAME_SETTING_BUFFERING = 34,
@@ -604,7 +604,7 @@ void ClusterJpegHistograms(j_compress_ptr cinfo, const Histogram* histograms,
slot_histograms.push_back(histogram_index);
slot_costs.push_back(best_cost);
} else {
// TODO(szabadka) Find the best histogram to replce.
// TODO(szabadka) Find the best histogram to replace.
best_slot = (clusters->slot_ids.back() + 1) % 4;
}
slot_histograms[best_slot] = histogram_index;
+1 -1
View File
@@ -705,7 +705,7 @@ void SetQuantMatrices(j_compress_ptr cinfo, float distances[NUM_QUANT_TBLS],
void InitQuantizer(j_compress_ptr cinfo, QuantPass pass) {
jpeg_comp_master* m = cinfo->master;
// Compute quantization multupliers from the quant table values.
// Compute quantization multipliers from the quant table values.
for (int c = 0; c < cinfo->num_components; ++c) {
int quant_idx = cinfo->comp_info[c].quant_tbl_no;
JQUANT_TBL* quant_table = cinfo->quant_tbl_ptrs[quant_idx];
@@ -145,7 +145,7 @@ TEST_P(StreamingTestParam, TestStreaming) {
jpegli_finish_compress(&cinfo);
}
// Atfer the first iMCU row, we don't yet expect any output because the
// After the first iMCU row, we don't yet expect any output because the
// compressor delays processing to have context rows after the iMCU row.
if (y_in < std::min<size_t>(2 * iMCU_height, cinfo.image_height)) {
continue;
@@ -26,7 +26,7 @@
namespace jxl {
struct ReferceFrame {
struct ReferenceFrame {
std::unique_ptr<ImageBundle> frame;
// ImageBundle doesn't yet have a simple way to state it is in XYB.
bool ib_is_in_xyb = false;
@@ -107,7 +107,7 @@ class PatchDictionary {
explicit PatchDictionary(JxlMemoryManager* memory_manager)
: memory_manager_(memory_manager) {}
void SetShared(const std::array<ReferceFrame, 4>* reference_frames) {
void SetShared(const std::array<ReferenceFrame, 4>* reference_frames) {
reference_frames_ = reference_frames;
}
@@ -138,7 +138,7 @@ class PatchDictionary {
friend class PatchDictionaryEncoder;
JxlMemoryManager* memory_manager_;
const std::array<ReferceFrame, 4>* reference_frames_;
const std::array<ReferenceFrame, 4>* reference_frames_;
std::vector<PatchPosition> positions_;
std::vector<PatchReferencePosition> ref_positions_;
std::vector<PatchBlending> blendings_;
+1 -1
View File
@@ -1530,7 +1530,7 @@ std::ostream& operator<<(std::ostream& os, const PixelTestConfig& c) {
}
if (c.preview_mode == jxl::kSmallPreview) os << "Preview";
if (c.preview_mode == jxl::kBigPreview) os << "BigPreview";
if (c.add_intrinsic_size) os << "IntrinicSize";
if (c.add_intrinsic_size) os << "IntrinsicSize";
if (c.use_callback) os << "Callback";
if (c.set_buffer_early) os << "EarlyBuffer";
if (c.use_resizable_runner) os << "ResizableRunner";
+1 -1
View File
@@ -101,7 +101,7 @@ struct Token {
StatusOr<float> ANSPopulationCost(const ANSHistBin* data, size_t alphabet_size);
// Writes the context map to the bitstream and concatenates the individual
// histogram bistreams in codes.encoded_histograms. Used in streaming mode.
// histogram bitstreams in codes.encoded_histograms. Used in streaming mode.
Status EncodeHistograms(const std::vector<uint8_t>& context_map,
const EntropyEncodingData& codes, BitWriter* writer,
LayerType layer, AuxOut* aux_out);
+1 -1
View File
@@ -1859,7 +1859,7 @@ class EncoderStreamingTest : public testing::TestWithParam<StreamingTestParam> {
size_t frame_count = static_cast<int>(p.multiple_frames()) + 1;
for (size_t i = 0; i < frame_count; i++) {
// Create local copy of pixels and adapter because they are only
// guarantted to be available during the JxlEncoderAddChunkedFrame() call.
// guaranteed to be available during the JxlEncoderAddChunkedFrame() call.
JxlChunkedFrameInputSourceAdapter chunked_frame_adapter(frame.Copy(),
ec_frame.Copy());
EXPECT_EQ(JXL_ENC_SUCCESS,
+1 -1
View File
@@ -437,7 +437,7 @@ void JPEGData::CalculateMcuSize(const JPEGScanInfo& scan, int* MCUs_per_row,
// h_group / v_group act as numerators for converting number of blocks to
// number of MCU. In interleaved mode it is 1, so MCU is represented with
// max_*_samp_factor blocks. In non-interleaved mode we choose numerator to
// be the samping factor, consequently MCU is always represented with single
// be the sampling factor, consequently MCU is always represented with single
// block.
const int h_group = is_interleaved ? 1 : base_component.h_samp_factor;
const int v_group = is_interleaved ? 1 : base_component.v_samp_factor;
@@ -68,12 +68,19 @@ JXL_INLINE void FastUnsqueeze(const pixel_type *JXL_RESTRICT p_residual,
auto absan = Abs(an);
auto absBn = Abs(Sub(top, next_avg));
// Compute a3 = absBa / 3
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
auto a3eh = MulEven(absBa, onethird);
auto a3oh = MulOdd(absBa, onethird);
auto a3 = OddEven(DupEven(BitCast(d, a3oh)), BitCast(d, a3eh));
#else
auto a3e = BitCast(d, ShiftRight<32>(MulEven(absBa, onethird)));
auto a3oi = MulEven(Reverse(d, absBa), onethird);
auto a3o = BitCast(
d, Reverse(hwy::HWY_NAMESPACE::Repartition<pixel_type_w, decltype(d)>(),
a3oi));
auto a3 = OddEven(a3o, a3e);
#endif
a3 = Add(a3, Add(absBn, Set(d, 2)));
auto absdiff = ShiftRight<2>(a3);
auto skipdiff = Ne(Ba, Zero(d));
+1 -1
View File
@@ -89,7 +89,7 @@ struct PassesSharedState {
Image3F dc_frames[4];
std::array<ReferceFrame, 4> reference_frames;
std::array<ReferenceFrame, 4> reference_frames;
// Number of pre-clustered set of histograms (with the same ctx map), per
// pass. Encoded as num_histograms_ - 1.
@@ -600,16 +600,8 @@ Status LowMemoryRenderPipeline::RenderRect(size_t thread_id,
channel_shifts_[i][anyc_[i]]));
}
ssize_t frame_x0 =
first_image_dim_stage_ == stages_.size() ? 0 : frame_origin_.x0;
ssize_t frame_y0 =
first_image_dim_stage_ == stages_.size() ? 0 : frame_origin_.y0;
size_t full_image_xsize = first_image_dim_stage_ == stages_.size()
? frame_dimensions_.xsize_upsampled
: full_image_xsize_;
size_t full_image_ysize = first_image_dim_stage_ == stages_.size()
? frame_dimensions_.ysize_upsampled
: full_image_ysize_;
ssize_t frame_x0 = frame_origin_.x0;
ssize_t frame_y0 = frame_origin_.y0;
// Compute actual x-axis bounds for the current image area in the context of
// the full image this frame is part of. As the left boundary may be negative,
@@ -624,13 +616,21 @@ Status LowMemoryRenderPipeline::RenderRect(size_t thread_id,
full_image_x0 = 0;
}
ssize_t full_image_x1 = frame_x0 + image_area_rect.x1();
full_image_x1 = std::min<ssize_t>(full_image_x1, full_image_xsize);
// If the current image area is entirely outside of the visible image, there
// is no point in proceeding. Note: this uses the assumption that if there is
// a stage with observable effects (i.e. a kInput stage), it only appears
// after the stage that switches to image dimensions.
if (full_image_x1 <= full_image_x0) return true;
std::vector<Rect> span(stages_.size());
for (size_t i = 0; i < stages_.size(); ++i) {
if (i < first_image_dim_stage_) {
span[i] = Rect(group_rect[i].x0(), 0, group_rect[i].xsize(),
image_rect_[i].ysize());
} else {
size_t x0 = full_image_x0;
size_t x1 = full_image_x1;
size_t x_max = full_image_xsize_;
size_t cropped_x1 = std::min<ssize_t>(x1, x_max);
span[i] =
Rect(x0, 0, std::max<ssize_t>(0, cropped_x1 - x0), full_image_ysize_);
}
}
// Data structures to hold information about input/output rows and their
// buffers.
@@ -723,18 +723,17 @@ Status LowMemoryRenderPipeline::RenderRect(size_t thread_id,
ssize_t image_y = static_cast<ssize_t>(group_rect[i].y0()) + y;
// Do not produce rows in out-of-bounds areas.
if (image_y < 0 ||
image_y >= static_cast<ssize_t>(image_rect_[i].ysize())) {
continue;
}
if (image_y < 0) continue;
if (image_y >= static_cast<ssize_t>(span[i].y1())) continue;
// Get the input/output rows and potentially apply mirroring to the input.
prepare_io_rows(y, i);
// Produce output rows.
if (span[i].xsize() == 0) continue;
JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow(
input_rows[i], output_rows, xpadding_for_output_[i],
group_rect[i].xsize(), group_rect[i].x0(), image_y, thread_id));
input_rows[i], output_rows, xpadding_for_output_[i], span[i].xsize(),
span[i].x0(), image_y, thread_id));
}
// Process trailing stages, i.e. the final set of non-kInOut stages; they
@@ -743,11 +742,8 @@ Status LowMemoryRenderPipeline::RenderRect(size_t thread_id,
int y = vy - num_extra_rows;
for (size_t c = 0; c < input_data.size(); c++) {
// Skip pixels that are not part of the actual final image area.
input_rows[first_trailing_stage_][c][0] =
rows.GetBuffer(stage_input_for_channel_[first_trailing_stage_][c], y,
c) +
x_pixels_skip;
input_rows[first_trailing_stage_][c][0] = rows.GetBuffer(
stage_input_for_channel_[first_trailing_stage_][c], y, c);
}
// Check that we are not outside of the bounds for the current rendering
@@ -757,26 +753,35 @@ Status LowMemoryRenderPipeline::RenderRect(size_t thread_id,
continue;
}
for (size_t i = first_trailing_stage_; i < first_image_dim_stage_; i++) {
if (span[i].xsize() == 0) continue;
size_t y0 = image_area_rect.y0() + y;
if (y0 >= span[i].y1()) continue;
JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow(
input_rows[first_trailing_stage_], output_rows,
/*xextra=*/0, span[i].xsize(), span[i].x0(), y0, thread_id));
}
if (first_image_dim_stage_ == stages_.size()) continue;
// Skip pixels that are not part of the actual final image area.
for (size_t c = 0; c < input_data.size(); c++) {
input_rows[first_trailing_stage_][c][0] += x_pixels_skip;
}
// Avoid running pipeline stages on pixels that are outside the full image
// area. As trailing stages have no borders, this is a free optimization
// (and may be necessary for correctness, as some stages assume coordinates
// are within bounds).
ssize_t full_image_y = frame_y0 + image_area_rect.y0() + y;
if (full_image_y < 0 ||
full_image_y >= static_cast<ssize_t>(full_image_ysize)) {
continue;
}
if (full_image_y < 0) continue;
for (size_t i = first_trailing_stage_; i < stages_.size(); i++) {
// Before the first_image_dim_stage_, coordinates are relative to the
// current frame.
size_t x0 =
i < first_image_dim_stage_ ? full_image_x0 - frame_x0 : full_image_x0;
size_t y =
i < first_image_dim_stage_ ? full_image_y - frame_y0 : full_image_y;
JXL_RETURN_IF_ERROR(stages_[i]->ProcessRow(
input_rows[first_trailing_stage_], output_rows,
/*xextra=*/0, full_image_x1 - full_image_x0, x0, y, thread_id));
for (size_t i = first_image_dim_stage_; i < stages_.size(); i++) {
if (span[i].xsize() == 0) continue;
if (full_image_y >= static_cast<ssize_t>(span[i].y1())) continue;
JXL_RETURN_IF_ERROR(
stages_[i]->ProcessRow(input_rows[first_trailing_stage_], output_rows,
/*xextra=*/0, span[i].xsize(), span[i].x0(),
full_image_y, thread_id));
}
}
return true;
@@ -45,27 +45,45 @@ class CmsStage : public RenderPipelineStage {
size_t xextra, size_t xsize, size_t xpos, size_t ypos,
size_t thread_id) const final {
JXL_ENSURE(xsize <= xsize_);
// TODO(firsching): handle grey case separately
// interleave
float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0);
float* JXL_RESTRICT row1 = GetInputRow(input_rows, 1, 0);
float* JXL_RESTRICT row2 = GetInputRow(input_rows, 2, 0);
bool gray_src = (c_src_.Channels() == 1);
bool gray_dst = (output_encoding_info_.color_encoding.Channels() == 1);
float* mutable_buf_src = color_space_transform->BufSrc(thread_id);
float* JXL_RESTRICT buf_dst = color_space_transform->BufDst(thread_id);
// interleave
if (gray_src) {
float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0);
memcpy(mutable_buf_src, row0, xsize * sizeof(float));
} else {
float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0);
float* JXL_RESTRICT row1 = GetInputRow(input_rows, 1, 0);
float* JXL_RESTRICT row2 = GetInputRow(input_rows, 2, 0);
for (size_t x = 0; x < xsize; x++) {
mutable_buf_src[3 * x + 0] = row0[x];
mutable_buf_src[3 * x + 1] = row1[x];
mutable_buf_src[3 * x + 2] = row2[x];
for (size_t x = 0; x < xsize; x++) {
mutable_buf_src[3 * x + 0] = row0[x];
mutable_buf_src[3 * x + 1] = row1[x];
mutable_buf_src[3 * x + 2] = row2[x];
}
}
const float* buf_src = mutable_buf_src;
float* JXL_RESTRICT buf_dst = color_space_transform->BufDst(thread_id);
JXL_RETURN_IF_ERROR(
color_space_transform->Run(thread_id, buf_src, buf_dst, xsize));
// de-interleave
for (size_t x = 0; x < xsize; x++) {
row0[x] = buf_dst[3 * x + 0];
row1[x] = buf_dst[3 * x + 1];
row2[x] = buf_dst[3 * x + 2];
if (gray_dst) {
float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0);
float* JXL_RESTRICT row1 = GetInputRow(input_rows, 1, 0);
float* JXL_RESTRICT row2 = GetInputRow(input_rows, 2, 0);
memcpy(row0, buf_dst, xsize * sizeof(float));
memcpy(row1, buf_dst, xsize * sizeof(float));
memcpy(row2, buf_dst, xsize * sizeof(float));
} else {
float* JXL_RESTRICT row0 = GetInputRow(input_rows, 0, 0);
float* JXL_RESTRICT row1 = GetInputRow(input_rows, 1, 0);
float* JXL_RESTRICT row2 = GetInputRow(input_rows, 2, 0);
for (size_t x = 0; x < xsize; x++) {
row0[x] = buf_dst[3 * x + 0];
row1[x] = buf_dst[3 * x + 1];
row2[x] = buf_dst[3 * x + 2];
}
}
return true;
}
+3 -3
View File
@@ -744,10 +744,10 @@ bool SamePixels(const extras::PackedPixelFile& a,
Status ReadICC(BitReader* JXL_RESTRICT reader,
std::vector<uint8_t>* JXL_RESTRICT icc) {
JxlMemoryManager* memort_manager = jxl::test::MemoryManager();
JxlMemoryManager* memory_manager = jxl::test::MemoryManager();
icc->clear();
ICCReader icc_reader{memort_manager};
PaddedBytes icc_buffer{memort_manager};
ICCReader icc_reader{memory_manager};
PaddedBytes icc_buffer{memory_manager};
JXL_RETURN_IF_ERROR(icc_reader.Init(reader));
JXL_RETURN_IF_ERROR(icc_reader.Process(reader, &icc_buffer));
Bytes(icc_buffer).AppendTo(*icc);
+1 -1
View File
@@ -544,7 +544,7 @@ libjxl_major_version = 0
libjxl_minor_version = 11
libjxl_patch_version = 1
libjxl_patch_version = 2
libjxl_public_headers = [
"include/jxl/cms.h",
+1 -1
View File
@@ -542,7 +542,7 @@ libjxl_major_version = 0
libjxl_minor_version = 11
libjxl_patch_version = 1
libjxl_patch_version = 2
libjxl_public_headers = [
"include/jxl/cms.h",
+2 -2
View File
@@ -112,7 +112,7 @@ if (JPEGXL_ENABLE_VIEWERS OR NOT JPEGXL_ENABLE_SKCMS OR JPEGXL_ENABLE_PLUGINS)
endif ()
else()
include(lcms2.cmake)
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lcms/COPYING"
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/lcms/LICENSE"
${PROJECT_BINARY_DIR}/LICENSE.lcms COPYONLY)
endif()
endif()
@@ -138,7 +138,7 @@ elseif (JPEGXL_BUNDLE_LIBPNG)
add_subdirectory(zlib)
set(PNG_STATIC ON CACHE BOOL "")
set(PNG_EXECUTABLES OFF CACHE BOOL "")
set(PNG_BUILD_ZLIB ON CACHE BOOL "")
set(ZLIB_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/zlib/" CACHE BOOL "")
set(PNG_TESTS OFF CACHE BOOL "")
set(SKIP_INSTALL_ALL ON CACHE BOOL "")
set(ZLIB_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/zlib/")
@@ -1015,9 +1015,9 @@ class Benchmark {
memcpy(row_out, &row_in[x0], size * sizeof(row_out[0]));
}
}
std::string fn_output =
StringPrintf("%s/%s.crop_%dx%d+%d+%d.png", sample_tmp_dir.c_str(),
FileBaseName(fnames[idx]).c_str(), size, size, x0, y0);
std::string fn_output = StringPrintf(
"%s/%s.crop_%" PRIuS "x%" PRIuS "+%d+%d.png", sample_tmp_dir.c_str(),
FileBaseName(fnames[idx]).c_str(), size, size, x0, y0);
ThreadPool* null_pool = nullptr;
JPEGXL_TOOLS_CHECK(WriteImage(sample, null_pool, fn_output));
fnames_out.push_back(fn_output);
+2 -1
View File
@@ -243,7 +243,8 @@ int CJpegliMain(int argc, const char* argv[]) {
}
if (!args.quiet) {
fprintf(stderr, "Compressed to %" PRIuS " bytes ", jpeg_bytes.size());
const size_t num_pixels = ppf.info.xsize * ppf.info.ysize;
const double num_pixels =
static_cast<double>(ppf.info.xsize) * ppf.info.ysize;
const double bpp =
static_cast<double>(jpeg_bytes.size() * jxl::kBitsPerByte) / num_pixels;
fprintf(stderr, "(%.3f bpp).\n", bpp);
@@ -177,7 +177,8 @@ bool EncodeWithJpegli(const ImageSpec& spec, const std::vector<uint8_t>& pixels,
jpegli_set_progressive_level(&cinfo, spec.progressive_level);
cinfo.restart_interval = spec.restart_interval;
jpegli_start_compress(&cinfo, TRUE);
size_t stride = cinfo.image_width * cinfo.input_components;
size_t stride =
cinfo.image_width * static_cast<size_t>(cinfo.input_components);
std::vector<uint8_t> row_bytes(stride);
for (size_t y = 0; y < cinfo.image_height; ++y) {
memcpy(row_bytes.data(), &pixels[y * stride], stride);
+16 -16
View File
@@ -32,7 +32,7 @@ MIN_STACK_SIZE = 32
IS_OSX = (platform.system() == 'Darwin')
Symbol = collections.namedtuple('Symbol', ['address', 'size', 'typ', 'name'])
Symbol = collections.namedtuple('Symbol', ['address', 'size', 'kind', 'name'])
# Represents the stack size information of a function (defined by its address).
SymbolStack = collections.namedtuple('SymbolStack',
@@ -213,10 +213,10 @@ def TargetSize(symbols, symbol_filter=None):
if not sym.size or (symbol_filter is not None and
sym.name not in symbol_filter):
continue
t = sym.typ.lower()
t = sym.kind.lower()
# We can remove symbols if they appear in multiple objects since they will
# be merged by the linker.
if symbol_filter is not None and (t == sym.typ or t in 'wv'):
if symbol_filter is not None and (t == sym.kind or t in 'wv'):
symbol_filter.remove(sym.name)
ret.setdefault(t, 0)
ret[t] += sym.size
@@ -232,13 +232,13 @@ def PrintStats(stats):
for objstat in stats:
bin_size = 0
ram_size = 0
for typ, size in objstat.size_map.items():
if typ in BIN_SIZE:
for kind, size in objstat.size_map.items():
if kind in BIN_SIZE:
bin_size += size
if typ in RAM_SIZE:
if kind in RAM_SIZE:
ram_size += size
if typ not in BIN_SIZE + RAM_SIZE:
raise Exception('Unknown type "%s"' % typ)
if kind not in BIN_SIZE + RAM_SIZE:
raise Exception('Unknown type "%s"' % kind)
if objstat.in_partition:
sum_bin_size += bin_size
sum_ram_size += ram_size
@@ -274,8 +274,8 @@ def PrintTopSymbols(tgt_top_symbols):
if not tgt_top_symbols:
return
print(' Size T Symbol name')
for size, typ, name in tgt_top_symbols:
print('%9d %s %s' % (size, typ, name))
for size, kind, name in tgt_top_symbols:
print('%9d %s %s' % (size, kind, name))
print()
@@ -317,19 +317,19 @@ def SizeStats(args):
tgt_syms = syms[target]
used_syms = set()
for sym in tgt_syms:
if sym.typ.lower() in BIN_SIZE + RAM_SIZE:
if sym.kind.lower() in BIN_SIZE + RAM_SIZE:
used_syms.add(sym.name)
elif sym.typ.lower() in IGNORE_SYMBOLS:
elif sym.kind.lower() in IGNORE_SYMBOLS:
continue
else:
print('Unknown: %s %s' % (sym.typ, sym.name))
print('Unknown: %s %s' % (sym.kind, sym.name))
target_path = os.path.join(args.build_dir, tgt.filename)
sym_stacks = []
if not target_path.endswith('.a'):
sym_stacks = LoadStackSizes(target_path, args.binutils)
symbols_by_addr = {sym.address: sym for sym in tgt_syms
if sym.typ.lower() in 'tw'}
if sym.kind.lower() in 'tw'}
tgt_stack_sizes = collections.OrderedDict()
for sym_stack in sorted(sym_stacks, key=lambda s: -s.stack_size):
tgt_stack_sizes[
@@ -337,7 +337,7 @@ def SizeStats(args):
tgt_top_symbols = []
if args.top_symbols:
tgt_top_symbols = [(sym.size, sym.typ, sym.name) for sym in tgt_syms
tgt_top_symbols = [(sym.size, sym.kind, sym.name) for sym in tgt_syms
if sym.name in used_syms and sym.size]
tgt_top_symbols.sort(key=lambda t: (-t[0], t[2]))
tgt_top_symbols = tgt_top_symbols[:args.top_symbols]
@@ -354,7 +354,7 @@ def SizeStats(args):
for sym in tgt_syms:
if not sym.size or mangled not in sym.name:
continue
t = sym.typ.lower()
t = sym.kind.lower()
ret.setdefault(t, 0)
ret[t] += sym.size
# SIMD namespaces are not part of the partition, they are already included
@@ -24,6 +24,7 @@ cmsCreateTransformTHR = "cmsCreateTransformTHR"
cmsCreateXYZProfileTHR = "cmsCreateXYZProfileTHR"
cmsOpenProfileFromMemTHR = "cmsOpenProfileFromMemTHR"
cmsSetLogErrorHandlerTHR = "cmsSetLogErrorHandlerTHR"
gl_pathc = "gl_pathc" # glob_t
hIST = "hIST" # histogram PNG chunk
JMSG_STR_PARM_MAX = "JMSG_STR_PARM_MAX" # jpeglib
msg_parm = "msg_parm" # jpeglib
+1 -1
View File
@@ -106,7 +106,7 @@ python3 ./tools/wasm_demo/build_site.py ./tools/wasm_demo/ ./build-wasm32/tools/
Then you need to put your image files in the correct same place and are should be good to go.
To summarize, using the wasm decoder together with a service workder amounts to adding
To summarize, using the wasm decoder together with a service worker amounts to adding
```html
<script src="service_worker.js"></script>
```
@@ -33,7 +33,7 @@ let onLoadJxlModule = (module) => {
};
// Check if multi-threading is supported (i.e. SharedArrayBuffer is allowed).
let probeMutlithreading = () => {
let probeMultithreading = () => {
try {
new SharedArrayBuffer();
return true;
@@ -65,7 +65,7 @@ let probeHdr = () => {
// "main" method executed after page is loaded; all scripts are "synchronous" elements,
// so it is guaranteed that script elements are loaded and executed.
let onDomContentLoaded = () => {
if (!probeMutlithreading()) return;
if (!probeMultithreading()) return;
hdrCanvas = probeHdr();
JxlDecoderModule().then(onLoadJxlModule);
};