feat: extended jxl support

This commit is contained in:
Louie Torres
2023-01-12 00:25:34 +08:00
committed by Alex Kontos
parent 75887a0792
commit f6af2f42ad
26 changed files with 2982 additions and 2686 deletions

4
Cargo.lock generated
View File

@@ -4082,9 +4082,9 @@ dependencies = [
[[package]] [[package]]
name = "mime_guess" name = "mime_guess"
version = "2.0.4" version = "2.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
dependencies = [ dependencies = [
"mime", "mime",
"unicase", "unicase",

View File

@@ -1288,6 +1288,7 @@ function maybeRecordToHandleTelemetry(uri, isLaunch) {
".xhtml", ".xhtml",
".svg", ".svg",
".webp", ".webp",
".jxl",
]); ]);
if (registeredExtensions.has(extension)) { if (registeredExtensions.has(extension)) {
counter[extension].add(1); counter[extension].add(1);

View File

@@ -67,6 +67,7 @@
<uap:FileType>.xhtml</uap:FileType> <uap:FileType>.xhtml</uap:FileType>
<uap:FileType>.svg</uap:FileType> <uap:FileType>.svg</uap:FileType>
<uap:FileType>.webp</uap:FileType> <uap:FileType>.webp</uap:FileType>
<uap:FileType>.jxl</uap:FileType>
</uap:SupportedFileTypes> </uap:SupportedFileTypes>
<uap:Logo>Assets\Document44x44.png</uap:Logo> <uap:Logo>Assets\Document44x44.png</uap:Logo>
<uap2:SupportedVerbs> <uap2:SupportedVerbs>

View File

@@ -513,6 +513,7 @@ ${RemoveDefaultBrowserAgentShortcut}
${AddAssociationIfNoneExist} ".svg" "WaterfoxHTML$5" ${AddAssociationIfNoneExist} ".svg" "WaterfoxHTML$5"
${AddAssociationIfNoneExist} ".webp" "WaterfoxHTML$5" ${AddAssociationIfNoneExist} ".webp" "WaterfoxHTML$5"
${AddAssociationIfNoneExist} ".avif" "WaterfoxHTML$5" ${AddAssociationIfNoneExist} ".avif" "WaterfoxHTML$5"
${AddAssociationIfNoneExist} ".jxl" "WaterfoxHTML$5"
${AddAssociationIfNoneExist} ".pdf" "WaterfoxPDF$5" ${AddAssociationIfNoneExist} ".pdf" "WaterfoxPDF$5"

View File

@@ -505,7 +505,9 @@ Section "Uninstall"
${un.RegCleanFileHandler} ".ogv" "WaterfoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".ogv" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".webm" "WaterfoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".webm" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".svg" "WaterfoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".svg" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".webp" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".avif" "WaterfoxHTML-$AppUserModelID" ${un.RegCleanFileHandler} ".avif" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".jxl" "WaterfoxHTML-$AppUserModelID"
${un.RegCleanFileHandler} ".pdf" "WaterfoxPDF-$AppUserModelID" ${un.RegCleanFileHandler} ".pdf" "WaterfoxPDF-$AppUserModelID"

View File

@@ -249,7 +249,8 @@ nsresult DecoderFactory::CreateAnimationDecoder(
} }
MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG || MOZ_ASSERT(aType == DecoderType::GIF || aType == DecoderType::PNG ||
aType == DecoderType::WEBP || aType == DecoderType::AVIF, aType == DecoderType::WEBP || aType == DecoderType::AVIF ||
aType == DecoderType::JXL,
"Calling CreateAnimationDecoder for non-animating DecoderType"); "Calling CreateAnimationDecoder for non-animating DecoderType");
// Create an anonymous decoder. Interaction with the SurfaceCache and the // Create an anonymous decoder. Interaction with the SurfaceCache and the
@@ -304,7 +305,8 @@ already_AddRefed<Decoder> DecoderFactory::CloneAnimationDecoder(
// rediscover it is animated). // rediscover it is animated).
DecoderType type = aDecoder->GetType(); DecoderType type = aDecoder->GetType();
MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG || MOZ_ASSERT(type == DecoderType::GIF || type == DecoderType::PNG ||
type == DecoderType::WEBP || type == DecoderType::AVIF, type == DecoderType::WEBP || type == DecoderType::AVIF ||
type == DecoderType::JXL,
"Calling CloneAnimationDecoder for non-animating DecoderType"); "Calling CloneAnimationDecoder for non-animating DecoderType");
RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true); RefPtr<Decoder> decoder = GetDecoder(type, nullptr, /* aIsRedecode = */ true);

View File

@@ -45,9 +45,20 @@ nsJXLDecoder::nsJXLDecoder(RasterImage* aImage)
Transition::TerminateSuccess()), Transition::TerminateSuccess()),
mDecoder(JxlDecoderMake(nullptr)), mDecoder(JxlDecoderMake(nullptr)),
mParallelRunner( mParallelRunner(
JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())) { JxlThreadParallelRunnerMake(nullptr, PreferredThreadCount())),
JxlDecoderSubscribeEvents(mDecoder.get(), mUsePipeTransform(true),
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;
}
JxlDecoderSubscribeEvents(mDecoder.get(), events);
JxlDecoderSetParallelRunner(mDecoder.get(), JxlThreadParallelRunner, JxlDecoderSetParallelRunner(mDecoder.get(), JxlThreadParallelRunner,
mParallelRunner.get()); mParallelRunner.get());
@@ -58,6 +69,10 @@ nsJXLDecoder::nsJXLDecoder(RasterImage* aImage)
nsJXLDecoder::~nsJXLDecoder() { nsJXLDecoder::~nsJXLDecoder() {
MOZ_LOG(sJXLLog, LogLevel::Debug, MOZ_LOG(sJXLLog, LogLevel::Debug,
("[this=%p] nsJXLDecoder::~nsJXLDecoder", this)); ("[this=%p] nsJXLDecoder::~nsJXLDecoder", this));
if (mCMSLine) {
free(mCMSLine);
}
} }
size_t nsJXLDecoder::PreferredThreadCount() { size_t nsJXLDecoder::PreferredThreadCount() {
@@ -86,14 +101,20 @@ LexerResult nsJXLDecoder::DoDecode(SourceBufferIterator& aIterator,
LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData( LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
const char* aData, size_t aLength) { const char* aData, size_t aLength) {
const uint8_t* input = (const uint8_t*)aData; // Ignore data we have already read.
size_t length = aLength; // This will only occur as a result of a yield for animation.
if (mBuffer.length() != 0) { if (!mContinue) {
JXL_TRY_BOOL(mBuffer.append(aData, aLength)); const uint8_t* input = (const uint8_t*)aData;
input = mBuffer.begin(); size_t length = aLength;
length = mBuffer.length(); 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) { while (true) {
JxlDecoderStatus status = JxlDecoderProcessInput(mDecoder.get()); JxlDecoderStatus status = JxlDecoderProcessInput(mDecoder.get());
@@ -106,6 +127,34 @@ LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
size_t remaining = JxlDecoderReleaseInput(mDecoder.get()); size_t remaining = JxlDecoderReleaseInput(mDecoder.get());
mBuffer.clear(); mBuffer.clear();
JXL_TRY_BOOL(mBuffer.append(aData + aLength - remaining, remaining)); 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); return Transition::ContinueUnbuffered(State::JXL_DATA);
} }
@@ -116,42 +165,199 @@ LexerTransition<nsJXLDecoder::State> nsJXLDecoder::ReadJXLData(
PostFrameCount(/* aFrameCount */ 1); PostFrameCount(/* aFrameCount */ 1);
} }
if (mInfo.alpha_bits > 0) { if (mInfo.alpha_bits > 0) {
mSurfaceFormat = SurfaceFormat::OS_RGBA;
PostHasTransparency(); PostHasTransparency();
} }
if (!mInfo.have_animation && IsMetadataDecode()) {
return Transition::TerminateSuccess();
}
// If CMS is off or the image is RGB, always output in RGBA.
// If the image is grayscale, then the pipe transform can't be used.
if (mCMSMode != CMSMode::Off) {
mChannels = mInfo.num_color_channels == 1
? 1 + (mInfo.alpha_bits > 0 ? 1 : 0)
: 4;
} else {
mChannels = 4;
}
mFormat = {mChannels, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0};
break;
}
case JXL_DEC_COLOR_ENCODING: {
size_t size = 0;
JXL_TRY(JxlDecoderGetICCProfileSize(
mDecoder.get(), JXL_COLOR_PROFILE_TARGET_DATA, &size))
std::vector<uint8_t> icc_profile(size);
JXL_TRY(JxlDecoderGetColorAsICCProfile(mDecoder.get(),
JXL_COLOR_PROFILE_TARGET_DATA,
icc_profile.data(), size))
mInProfile = qcms_profile_from_memory((char*)icc_profile.data(), size);
uint32_t profileSpace = qcms_profile_get_color_space(mInProfile);
// Skip color management if color profile is not compatible with number
// of channels.
if (profileSpace != icSigRgbData &&
(mInfo.num_color_channels == 3 || profileSpace != icSigGrayData)) {
break;
}
mUsePipeTransform =
profileSpace == icSigRgbData && mInfo.num_color_channels == 3;
qcms_data_type inType;
if (mInfo.num_color_channels == 3) {
inType = QCMS_DATA_RGBA_8;
} else if (mInfo.alpha_bits > 0) {
inType = QCMS_DATA_GRAYA_8;
} else {
inType = QCMS_DATA_GRAY_8;
}
if (!mUsePipeTransform) {
mCMSLine =
static_cast<uint8_t*>(malloc(sizeof(uint32_t) * mInfo.xsize));
}
int intent = gfxPlatform::GetRenderingIntent();
if (intent == -1) {
intent = qcms_profile_get_rendering_intent(mInProfile);
}
mTransform =
qcms_transform_create(mInProfile, inType, GetCMSOutputProfile(),
QCMS_DATA_RGBA_8, (qcms_intent)intent);
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()) { if (IsMetadataDecode()) {
return Transition::TerminateSuccess(); return Transition::TerminateSuccess();
} }
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 (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;
}
qcms_transform* pipeTransform =
mUsePipeTransform ? mTransform : nullptr;
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
mSurfaceFormat, animParams, pipeTransform, pipeFlags);
if (!pipe) {
MOZ_LOG(sJXLLog, LogLevel::Debug,
("[this=%p] nsJXLDecoder::ReadJXLData - no pipe\n", this));
return Transition::TerminateFailure();
}
mPipe = std::move(*pipe);
break; break;
} }
case JXL_DEC_NEED_IMAGE_OUT_BUFFER: { case JXL_DEC_NEED_IMAGE_OUT_BUFFER: {
size_t size = 0; size_t size = 0;
JxlPixelFormat format{4, JXL_TYPE_UINT8, JXL_LITTLE_ENDIAN, 0}; JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &mFormat, &size));
JXL_TRY(JxlDecoderImageOutBufferSize(mDecoder.get(), &format, &size));
mOutBuffer.clear(); mOutBuffer.clear();
JXL_TRY_BOOL(mOutBuffer.growBy(size)); JXL_TRY_BOOL(mOutBuffer.growBy(size));
JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &format, JXL_TRY(JxlDecoderSetImageOutBuffer(mDecoder.get(), &mFormat,
mOutBuffer.begin(), size)); mOutBuffer.begin(), size));
break; break;
} }
case JXL_DEC_FULL_IMAGE: { case JXL_DEC_FULL_IMAGE: {
OrientedIntSize size(mInfo.xsize, mInfo.ysize); mPipe.ResetToFirstRow();
Maybe<SurfacePipe> pipe = SurfacePipeFactory::CreateSurfacePipe(
this, size, OutputSize(), FullFrame(), SurfaceFormat::R8G8B8A8,
SurfaceFormat::OS_RGBA, Nothing(), nullptr, SurfacePipeFlags());
for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end(); for (uint8_t* rowPtr = mOutBuffer.begin(); rowPtr < mOutBuffer.end();
rowPtr += mInfo.xsize * 4) { rowPtr += mInfo.xsize * mChannels) {
pipe->WriteBuffer(reinterpret_cast<uint32_t*>(rowPtr)); 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 = pipe->TakeInvalidRect()) { if (Maybe<SurfaceInvalidRect> invalidRect = mPipe.TakeInvalidRect()) {
PostInvalidation(invalidRect->mInputSpaceRect, PostInvalidation(invalidRect->mInputSpaceRect,
Some(invalidRect->mOutputSpaceRect)); 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: {
int32_t loopArg;
if (HasAnimation()) {
// JXL num_loops: 0 means infinite. (num_loops - 1) becomes -1.
// JXL num_loops: 1 means play once. (num_loops - 1) becomes 0 (0 repeats).
// JXL num_loops: N means play N times. (num_loops - 1) becomes N-1 (N-1 repeats).
loopArg = static_cast<int32_t>(mInfo.animation.num_loops) - 1;
} else {
loopArg = 0; // For non-animated images, repeat count is 0.
}
PostLoopCount(loopArg); // Pass the loop count to PostLoopCount
PostDecodeDone(); // Call PostDecodeDone without arguments
return Transition::TerminateSuccess(); return Transition::TerminateSuccess();
} }
} }

View File

@@ -45,7 +45,19 @@ class nsJXLDecoder final : public Decoder {
JxlThreadParallelRunnerPtr mParallelRunner; JxlThreadParallelRunnerPtr mParallelRunner;
Vector<uint8_t> mBuffer; Vector<uint8_t> mBuffer;
Vector<uint8_t> mOutBuffer; Vector<uint8_t> mOutBuffer;
JxlBasicInfo mInfo{}; JxlBasicInfo mInfo;
JxlPixelFormat mFormat;
JxlFrameHeader mFrameHeader;
bool mUsePipeTransform;
uint8_t mChannels;
uint8_t* mCMSLine;
uint32_t mNumFrames;
FrameTimeout mTimeout;
gfx::SurfaceFormat mSurfaceFormat;
SurfacePipe mPipe;
bool mContinue;
}; };
} // namespace mozilla::image } // namespace mozilla::image

View File

@@ -2347,6 +2347,12 @@ version = "1.4.0"
notes = "I have read over the macros, and audited the unsafe code." notes = "I have read over the macros, and audited the unsafe code."
aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml" aggregated-from = "https://raw.githubusercontent.com/mozilla/cargo-vet/main/supply-chain/audits.toml"
[[audits.mozilla.audits.mime_guess]]
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
criteria = "safe-to-deploy"
delta = "2.0.4 -> 2.0.5"
aggregated-from = "https://raw.githubusercontent.com/mozilla/glean/main/supply-chain/audits.toml"
[[audits.mozilla.audits.rkv]] [[audits.mozilla.audits.rkv]]
who = "Kagami Sascha Rosylight <krosylight@mozilla.com>" who = "Kagami Sascha Rosylight <krosylight@mozilla.com>"
criteria = "safe-to-deploy" criteria = "safe-to-deploy"

View File

@@ -1 +1 @@
{"files":{"Cargo.lock":"1be3b2e0b56466b1a4ab94c35176df5a41846677caa7bd2d5603cfdb19d9eef3","Cargo.toml":"c367dbd734e16d3dc6333fc072021372baee73170ec1c9b19606bb52f1772d9a","LICENSE":"6919f1acec82afc721be2d9907b993267f433a44d25d8aedf1003b5f59ebfd46","README.md":"417338ebb9da8e8bdfad3c3da81248ab5f023652f3468ec5dcb2fdf43ea40b32","benches/benchmark.rs":"2287c7233cf78a9af98b2b53cd20e221e4a785209bd70a87030f1ade34a02507","build.rs":"8e47254c0a927eeb243058cfc0da413f34a958226707c941e8634e4514562f04","examples/rev_map.rs":"0bab6cc20b9eace741c6cc4a8c67ebfa124df1bf213038c5e34976081ffd2ebc","src/impl_bin_search.rs":"32a89409690d57f074f11eb93a9d6e422f73788af63fc29f980e13d1c2d2fa6f","src/impl_phf.rs":"321028cc657364c6f7c5b5f538b0033bcfd6f3b5ef711304d806c0644466a964","src/lib.rs":"bb190bcbbf4139c410af20564f0376a99a83474ca12b7e8c6860228e0caff7da","src/mime_types.rs":"57ee8db84eb0fc4f06a3eac0da8c730a334cb99a7e81e60413f5febd886d91f4"},"package":"4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"} {"files":{"Cargo.lock":"2b59f34ab30d336b54edb66ea861174599310a5a87d597f45ca518cf55a186dc","Cargo.toml":"aca17af6f0fd2497700e94f764a25862ea41a35629fe4ba6603596213b8e1d88","LICENSE":"816000f9c28f7005d931c77636eb79fa7020071eb0f6e6a995515dfccd3559cb","README.md":"32663b3f4530e71cfec689576cca62911c83e504232963c65da82ebed26e2aa7","benches/benchmark.rs":"021dde9d834a3e4fab08d41f6e23d4f083f18c5f382b59866c2e07dc0ed9747a","build.rs":"bc413487e376b343b65089a9a897f4bb3c9d5fbaa5a6833e87db1d3c18c462d8","examples/rev_map.rs":"13a79d0b9eba6bfb49f99102917d1dada89c37ffcfab492759af997539b616ba","src/impl_bin_search.rs":"dd5817c9bc817c36274361c4cd0612ed303347c38bdbf8dff84cf57cd2918808","src/impl_phf.rs":"a9d956119304926c1f37754102ff74fbfe36004e24e326329e67e7c51fff381b","src/lib.rs":"7ea3571f3b7a231e4bf0003d66056becddeedb3084ee7af7fa9826f0602613f4","src/mime_types.rs":"1e89c58024547606d78e71488f0e027b740613fc22ac5877e24e3851e0f0628b"},"package":"f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"}

View File

@@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@@ -15,42 +24,27 @@ dependencies = [
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.0.1" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90682c8d613ad3373e66de8c6411e0ae2ab2571e879d2efbf73558cc66f21279"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]] [[package]]
name = "bumpalo" name = "bumpalo"
version = "3.7.0" version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "cast" name = "cast"
version = "0.2.7" version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
dependencies = [
"rustc_version",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@@ -60,9 +54,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.3" version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"textwrap", "textwrap",
@@ -71,9 +65,9 @@ dependencies = [
[[package]] [[package]]
name = "criterion" name = "criterion"
version = "0.3.5" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
dependencies = [ dependencies = [
"atty", "atty",
"cast", "cast",
@@ -97,65 +91,45 @@ dependencies = [
[[package]] [[package]]
name = "criterion-plot" name = "criterion-plot"
version = "0.4.4" version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
dependencies = [ dependencies = [
"cast", "cast",
"itertools", "itertools",
] ]
[[package]]
name = "crossbeam-channel"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.8.1" version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [ dependencies = [
"cfg-if",
"crossbeam-epoch", "crossbeam-epoch",
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.5" version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [ dependencies = [
"cfg-if",
"crossbeam-utils", "crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
] ]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.5" version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]] [[package]]
name = "csv" name = "csv"
version = "1.1.6" version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe"
dependencies = [ dependencies = [
"bstr",
"csv-core", "csv-core",
"itoa", "itoa",
"ryu", "ryu",
@@ -164,24 +138,24 @@ dependencies = [
[[package]] [[package]]
name = "csv-core" name = "csv-core"
version = "0.1.10" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
[[package]] [[package]]
name = "either" name = "either"
version = "1.6.1" version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]] [[package]]
name = "half" name = "half"
version = "1.7.1" version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62aca2aba2d62b4a7f5b33f3712cb1b0692779a56fb510499d5c0aa594daeaf3" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
@@ -194,73 +168,61 @@ dependencies = [
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.10.1" version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [ dependencies = [
"either", "either",
] ]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.7" version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b"
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.52" version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.98" version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.14" version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
dependencies = [
"cfg-if",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.4.0" version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "memoffset"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "mime" name = "mime"
version = "0.3.16" version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
[[package]] [[package]]
name = "mime_guess" name = "mime_guess"
version = "2.0.4" version = "2.0.5"
dependencies = [ dependencies = [
"criterion", "criterion",
"mime", "mime",
@@ -269,22 +231,18 @@ dependencies = [
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.14" version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
name = "num_cpus" name = "once_cell"
version = "1.13.0" version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "oorandom" name = "oorandom"
@@ -294,9 +252,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]] [[package]]
name = "plotters" name = "plotters"
version = "0.3.1" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3"
dependencies = [ dependencies = [
"num-traits", "num-traits",
"plotters-backend", "plotters-backend",
@@ -307,97 +265,91 @@ dependencies = [
[[package]] [[package]]
name = "plotters-backend" name = "plotters-backend"
version = "0.3.2" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7"
[[package]] [[package]]
name = "plotters-svg" name = "plotters-svg"
version = "0.3.1" version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705"
dependencies = [ dependencies = [
"plotters-backend", "plotters-backend",
] ]
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.28" version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [ dependencies = [
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.9" version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.5.1" version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [ dependencies = [
"autocfg",
"crossbeam-deque",
"either", "either",
"rayon-core", "rayon-core",
] ]
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.9.1" version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [ dependencies = [
"crossbeam-channel",
"crossbeam-deque", "crossbeam-deque",
"crossbeam-utils", "crossbeam-utils",
"lazy_static",
"num_cpus",
] ]
[[package]] [[package]]
name = "regex" name = "regex"
version = "1.5.4" version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [ dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax", "regex-syntax",
] ]
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.1.10" version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [ dependencies = [
"semver", "aho-corasick",
"memchr",
"regex-syntax",
] ]
[[package]] [[package]]
name = "ryu" name = "regex-syntax"
version = "1.0.5" version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "ryu"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]] [[package]]
name = "same-file" name = "same-file"
@@ -408,29 +360,20 @@ dependencies = [
"winapi-util", "winapi-util",
] ]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.127" version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
[[package]] [[package]]
name = "serde_cbor" name = "serde_cbor"
version = "0.11.1" version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e18acfa2f90e8b735b2836ab8d538de304cbb6729a7360729ea5a895d15a622" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [ dependencies = [
"half", "half",
"serde", "serde",
@@ -438,9 +381,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.127" version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -449,9 +392,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.66" version = "1.0.118"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@@ -460,13 +403,13 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.74" version = "2.0.68"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" checksum = "901fa70d88b9d6c98022e23b4136f9f3e54e4662c3bc1bd1d84a42a9a0f0c1e9"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-ident",
] ]
[[package]] [[package]]
@@ -490,47 +433,46 @@ dependencies = [
[[package]] [[package]]
name = "unicase" name = "unicase"
version = "2.6.0" version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89"
dependencies = [ dependencies = [
"version_check", "version_check",
] ]
[[package]] [[package]]
name = "unicode-width" name = "unicode-ident"
version = "0.1.8" version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-xid" name = "unicode-width"
version = "0.2.2" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.3" version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]] [[package]]
name = "walkdir" name = "walkdir"
version = "2.3.2" version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [ dependencies = [
"same-file", "same-file",
"winapi",
"winapi-util", "winapi-util",
] ]
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.75" version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"wasm-bindgen-macro", "wasm-bindgen-macro",
@@ -538,13 +480,13 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-backend" name = "wasm-bindgen-backend"
version = "0.2.75" version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"lazy_static",
"log", "log",
"once_cell",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
@@ -553,9 +495,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.75" version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -563,9 +505,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.75" version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -576,15 +518,15 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.75" version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.52" version = "0.3.69"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@@ -608,11 +550,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.5" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [ dependencies = [
"winapi", "windows-sys",
] ]
[[package]] [[package]]
@@ -620,3 +562,76 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
[[package]]
name = "windows_i686_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
[[package]]
name = "windows_i686_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"

View File

@@ -11,12 +11,16 @@
[package] [package]
name = "mime_guess" name = "mime_guess"
version = "2.0.4" version = "2.0.5"
authors = ["Austin Bonander <austin.bonander@gmail.com>"] authors = ["Austin Bonander <austin.bonander@gmail.com>"]
description = "A simple crate for detection of a file's MIME type by its extension." description = "A simple crate for detection of a file's MIME type by its extension."
documentation = "https://docs.rs/mime_guess/" documentation = "https://docs.rs/mime_guess/"
readme = "README.md" readme = "README.md"
keywords = ["mime", "filesystem", "extension"] keywords = [
"mime",
"filesystem",
"extension",
]
license = "MIT" license = "MIT"
repository = "https://github.com/abonander/mime_guess" repository = "https://github.com/abonander/mime_guess"
@@ -27,13 +31,16 @@ required-features = ["rev-mappings"]
[[bench]] [[bench]]
name = "benchmark" name = "benchmark"
harness = false harness = false
[dependencies.mime] [dependencies.mime]
version = "0.3" version = "0.3"
[dependencies.unicase] [dependencies.unicase]
version = "2.4.0" version = "2.4.0"
[dev-dependencies.criterion] [dev-dependencies.criterion]
version = "0.3" version = "0.3"
[build-dependencies.unicase] [build-dependencies.unicase]
version = "2.4.0" version = "2.4.0"

View File

@@ -1,22 +1,22 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2015 Austin Bonander Copyright (c) 2015 Austin Bonander
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.

View File

@@ -1,86 +1,86 @@
# mime_guess ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/abonander/mime_guess/Rust) [![Crates.io](https://img.shields.io/crates/v/mime_guess.svg)](https://crates.io/crates/mime_guess) # mime_guess ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/abonander/mime_guess/rust.yml?branch=master) [![Crates.io](https://img.shields.io/crates/v/mime_guess.svg)](https://crates.io/crates/mime_guess)
MIME/MediaType guessing by file extension. MIME/MediaType guessing by file extension.
Uses a static map of known file extension -> MIME type mappings. Uses a static map of known file extension -> MIME type mappings.
**Returning Contributors: New Requirements for Submissions Below** **Returning Contributors: New Requirements for Submissions Below**
##### Required Rust Version: 1.33 ##### Required Rust Version: 1.33
#### [Documentation](https://docs.rs/mime_guess/) #### [Documentation](https://docs.rs/mime_guess/)
### Versioning ### Versioning
Due to a mistaken premature release, `mime_guess` currently publicly depends on a pre-1.0 `mime`, Due to a mistaken premature release, `mime_guess` currently publicly depends on a pre-1.0 `mime`,
which means `mime` upgrades are breaking changes and necessitate a major version bump. which means `mime` upgrades are breaking changes and necessitate a major version bump.
Refer to the following table to find a version of `mime_guess` which matches your version of `mime`: Refer to the following table to find a version of `mime_guess` which matches your version of `mime`:
| `mime` version | `mime_guess` version | | `mime` version | `mime_guess` version |
|----------------|----------------------| |----------------|----------------------|
| `0.1.x, 0.2.x` | `1.x.y` | | `0.1.x, 0.2.x` | `1.x.y` |
| `0.3.x` | `2.x.y` | | `0.3.x` | `2.x.y` |
#### Note: MIME Types Returned Are Not Stable/Guaranteed #### Note: MIME Types Returned Are Not Stable/Guaranteed
The media types returned for a given extension are not considered to be part of the crate's The media types returned for a given extension are not considered to be part of the crate's
stable API and are often updated in patch (`x.y.z + 1`) releases to be as correct as possible. MIME stable API and are often updated in patch (`x.y.z + 1`) releases to be as correct as possible. MIME
changes are backported to previous major releases on a best-effort basis. changes are backported to previous major releases on a best-effort basis.
Note that only the extensions of paths/filenames are inspected in order to guess the MIME type. The Note that only the extensions of paths/filenames are inspected in order to guess the MIME type. The
file that may or may not reside at that path may or may not be a valid file of the returned MIME type. file that may or may not reside at that path may or may not be a valid file of the returned MIME type.
Be wary of unsafe or un-validated assumptions about file structure or length. Be wary of unsafe or un-validated assumptions about file structure or length.
An extension may also have multiple applicable MIME types. When more than one is returned, the first An extension may also have multiple applicable MIME types. When more than one is returned, the first
is considered to be the most "correct"--see below for elaboration. is considered to be the most "correct"--see below for elaboration.
Contributing Contributing
----------- -----------
#### Adding or correcting MIME types for extensions #### Adding or correcting MIME types for extensions
Is the MIME type for a file extension wrong or missing? Great! Is the MIME type for a file extension wrong or missing? Great!
Well, not great for us, but great for you if you'd like to open a pull request! Well, not great for us, but great for you if you'd like to open a pull request!
The file extension -> MIME type mappings are listed in `src/mime_types.rs`. The file extension -> MIME type mappings are listed in `src/mime_types.rs`.
**The list is sorted lexicographically by file extension, and all extensions are lowercase (where applicable).** **The list is sorted lexicographically by file extension, and all extensions are lowercase (where applicable).**
The former is necessary to support fallback to binary search when the The former is necessary to support fallback to binary search when the
`phf-map` feature is turned off, and for the maintainers' sanity. `phf-map` feature is turned off, and for the maintainers' sanity.
The latter is only for consistency's sake; the search is case-insensitive. The latter is only for consistency's sake; the search is case-insensitive.
Simply add or update the appropriate string pair(s) to make the correction(s) needed. Simply add or update the appropriate string pair(s) to make the correction(s) needed.
Run `cargo test` to make sure the library continues to work correctly. Run `cargo test` to make sure the library continues to work correctly.
#### Important! Citing the corrected MIME type #### Important! Citing the corrected MIME type
When opening a pull request, please include a link to an official document or RFC noting When opening a pull request, please include a link to an official document or RFC noting
the correct MIME type for the file type in question **in the commit message** so the correct MIME type for the file type in question **in the commit message** so
that the commit history can be used as an audit trail. that the commit history can be used as an audit trail.
Though we're only guessing here, we like to be as correct as we can. Though we're only guessing here, we like to be as correct as we can.
It makes it much easier to vet your contribution if we don't have to search for corroborating material. It makes it much easier to vet your contribution if we don't have to search for corroborating material.
#### Multiple MIME types per extension #### Multiple MIME types per extension
As of `2.0.0`, multiple MIME types per extension are supported. The first MIME type in the list for As of `2.0.0`, multiple MIME types per extension are supported. The first MIME type in the list for
a given extension should be the most "correct" so users who only care about getting a single MIME a given extension should be the most "correct" so users who only care about getting a single MIME
type can use the `first*()` methods. type can use the `first*()` methods.
The definition of "correct" is open to debate, however. In the author's opinion this should be The definition of "correct" is open to debate, however. In the author's opinion this should be
whatever is defined by the latest IETF RFC for the given file format, or otherwise explicitly whatever is defined by the latest IETF RFC for the given file format, or otherwise explicitly
supercedes all others. supercedes all others.
If an official IANA registration replaces an older "experimental" style media type, please If an official IANA registration replaces an older "experimental" style media type, please
place the new type before the old type in the list, but keep the old type for reference: place the new type before the old type in the list, but keep the old type for reference:
``` ```
- ("md", &["text/x-markdown"]), - ("md", &["text/x-markdown"]),
+ ("md", &["text/markdown", "text/x-markdown"]), + ("md", &["text/markdown", "text/x-markdown"]),
``` ```
#### Changes to the API or operation of the crate #### Changes to the API or operation of the crate
We're open to changes to the crate's API or its inner workings, breaking or not, if it improves the overall operation, efficiency, or ergonomics of the crate. However, it would be a good idea to open an issue on the repository so we can discuss your proposed changes and decide how best to approach them. We're open to changes to the crate's API or its inner workings, breaking or not, if it improves the overall operation, efficiency, or ergonomics of the crate. However, it would be a good idea to open an issue on the repository so we can discuss your proposed changes and decide how best to approach them.
License License
------- -------
MIT (See the `LICENSE` file in this repository for more information.) MIT (See the `LICENSE` file in this repository for more information.)

View File

@@ -1,31 +1,31 @@
#[macro_use] #[macro_use]
extern crate criterion; extern crate criterion;
extern crate mime_guess; extern crate mime_guess;
use self::criterion::Criterion; use self::criterion::Criterion;
use mime_guess::from_ext; use mime_guess::from_ext;
include!("../src/mime_types.rs"); include!("../src/mime_types.rs");
/// WARNING: this may take a while! /// WARNING: this may take a while!
fn bench_mime_str(c: &mut Criterion) { fn bench_mime_str(c: &mut Criterion) {
c.bench_function("from_ext", |b| { c.bench_function("from_ext", |b| {
for (mime_ext, _) in MIME_TYPES { for (mime_ext, _) in MIME_TYPES {
b.iter(|| from_ext(mime_ext).first_raw()); b.iter(|| from_ext(mime_ext).first_raw());
} }
}); });
} }
fn bench_mime_str_uppercase(c: &mut Criterion) { fn bench_mime_str_uppercase(c: &mut Criterion) {
c.bench_function("from_ext uppercased", |b| { c.bench_function("from_ext uppercased", |b| {
let uppercased = MIME_TYPES.into_iter().map(|(s, _)| s.to_uppercase()); let uppercased = MIME_TYPES.into_iter().map(|(s, _)| s.to_uppercase());
for mime_ext in uppercased { for mime_ext in uppercased {
b.iter(|| from_ext(&mime_ext).first_raw()); b.iter(|| from_ext(&mime_ext).first_raw());
} }
}); });
} }
criterion_group!(benches, bench_mime_str, bench_mime_str_uppercase); criterion_group!(benches, bench_mime_str, bench_mime_str_uppercase);
criterion_main!(benches); criterion_main!(benches);

View File

@@ -1,191 +1,196 @@
#[cfg(feature = "phf")] #[cfg(feature = "phf")]
extern crate phf_codegen; extern crate phf_codegen;
extern crate unicase; extern crate unicase;
use unicase::UniCase; use unicase::UniCase;
use std::env; use std::env;
use std::fs::File; use std::fs::File;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::BufWriter; use std::io::BufWriter;
use std::path::Path; use std::path::Path;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use mime_types::MIME_TYPES; use mime_types::MIME_TYPES;
#[path = "src/mime_types.rs"] #[path = "src/mime_types.rs"]
mod mime_types; mod mime_types;
#[cfg(feature = "phf")] #[cfg(feature = "phf")]
const PHF_PATH: &str = "::impl_::phf"; const PHF_PATH: &str = "::impl_::phf";
fn main() { fn main() {
let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("mime_types_generated.rs"); let dest_path = Path::new(&out_dir).join("mime_types_generated.rs");
let mut outfile = BufWriter::new(File::create(dest_path).unwrap()); let mut outfile = BufWriter::new(File::create(&dest_path).unwrap());
#[cfg(feature = "phf")] println!(
build_forward_map(&mut outfile); "cargo:rustc-env=MIME_TYPES_GENERATED_PATH={}",
dest_path.display()
#[cfg(feature = "rev-mappings")] );
build_rev_map(&mut outfile);
} #[cfg(feature = "phf")]
build_forward_map(&mut outfile);
// Build forward mappings (ext -> mime type)
#[cfg(feature = "phf")] #[cfg(feature = "rev-mappings")]
fn build_forward_map<W: Write>(out: &mut W) { build_rev_map(&mut outfile);
use phf_codegen::Map as PhfMap; }
let mut forward_map = PhfMap::new(); // Build forward mappings (ext -> mime type)
forward_map.phf_path(PHF_PATH); #[cfg(feature = "phf")]
fn build_forward_map<W: Write>(out: &mut W) {
let mut map_entries: Vec<(&str, Vec<&str>)> = Vec::new(); use phf_codegen::Map as PhfMap;
for &(key, types) in MIME_TYPES { let mut forward_map = PhfMap::new();
if let Some(&mut (key_, ref mut values)) = map_entries.last_mut() { forward_map.phf_path(PHF_PATH);
// deduplicate extensions
if key == key_ { let mut map_entries: Vec<(&str, Vec<&str>)> = Vec::new();
values.extend_from_slice(types);
continue; for &(key, types) in MIME_TYPES {
} if let Some(&mut (key_, ref mut values)) = map_entries.last_mut() {
} // deduplicate extensions
if key == key_ {
map_entries.push((key, types.into())); values.extend_from_slice(types);
} continue;
}
for (key, values) in map_entries { }
forward_map.entry(
UniCase::new(key), map_entries.push((key, types.into()));
&format!("&{:?}", values), }
);
} for (key, values) in map_entries {
forward_map.entry(
writeln!( UniCase::new(key),
out, &format!("&{:?}", values),
"static MIME_TYPES: phf::Map<UniCase<&'static str>, &'static [&'static str]> = \n{};", );
forward_map.build() }
)
.unwrap(); writeln!(
} out,
"static MIME_TYPES: phf::Map<UniCase<&'static str>, &'static [&'static str]> = \n{};",
// Build reverse mappings (mime type -> ext) forward_map.build()
#[cfg(all(feature = "phf", feature = "rev-mappings"))] )
fn build_rev_map<W: Write>(out: &mut W) { .unwrap();
use phf_codegen::Map as PhfMap; }
let dyn_map = get_rev_mappings(); // Build reverse mappings (mime type -> ext)
#[cfg(all(feature = "phf", feature = "rev-mappings"))]
let mut rev_map = PhfMap::new(); fn build_rev_map<W: Write>(out: &mut W) {
rev_map.phf_path(PHF_PATH); use phf_codegen::Map as PhfMap;
let mut exts = Vec::new(); let dyn_map = get_rev_mappings();
for (top, subs) in dyn_map { let mut rev_map = PhfMap::new();
let top_start = exts.len(); rev_map.phf_path(PHF_PATH);
let mut sub_map = PhfMap::new(); let mut exts = Vec::new();
sub_map.phf_path(PHF_PATH);
for (top, subs) in dyn_map {
for (sub, sub_exts) in subs { let top_start = exts.len();
let sub_start = exts.len();
exts.extend(sub_exts); let mut sub_map = PhfMap::new();
let sub_end = exts.len(); sub_map.phf_path(PHF_PATH);
sub_map.entry(sub, &format!("({}, {})", sub_start, sub_end)); for (sub, sub_exts) in subs {
} let sub_start = exts.len();
exts.extend(sub_exts);
let top_end = exts.len(); let sub_end = exts.len();
rev_map.entry( sub_map.entry(sub, &format!("({}, {})", sub_start, sub_end));
top, }
&format!(
"TopLevelExts {{ start: {}, end: {}, subs: {} }}", let top_end = exts.len();
top_start, top_end, sub_map.build()
), rev_map.entry(
); top,
} &format!(
"TopLevelExts {{ start: {}, end: {}, subs: {} }}",
writeln!( top_start, top_end, sub_map.build()
out, ),
"static REV_MAPPINGS: phf::Map<UniCase<&'static str>, TopLevelExts> = \n{};", );
rev_map.build() }
).unwrap();
writeln!(
writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap(); out,
} "static REV_MAPPINGS: phf::Map<UniCase<&'static str>, TopLevelExts> = \n{};",
rev_map.build()
#[cfg(all(not(feature = "phf"), feature = "rev-mappings"))] ).unwrap();
fn build_rev_map<W: Write>(out: &mut W) {
use std::fmt::Write as _; writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap();
}
macro_rules! unicase_const {
($s:expr) => ({ #[cfg(all(not(feature = "phf"), feature = "rev-mappings"))]
format_args!("{}({:?})", (if $s.is_ascii() { fn build_rev_map<W: Write>(out: &mut W) {
"UniCase::ascii" use std::fmt::Write as _;
} else {
"UniCase::unicode" macro_rules! unicase_const {
}), $s) ($s:expr) => ({
}) format_args!("{}({:?})", (if $s.is_ascii() {
} "UniCase::ascii"
} else {
let dyn_map = get_rev_mappings(); "UniCase::unicode"
}), $s)
write!(out, "static REV_MAPPINGS: &'static [(UniCase<&'static str>, TopLevelExts)] = &[").unwrap(); })
}
let mut exts = Vec::new();
let dyn_map = get_rev_mappings();
for (top, subs) in dyn_map {
let top_start = exts.len(); write!(out, "static REV_MAPPINGS: &'static [(UniCase<&'static str>, TopLevelExts)] = &[").unwrap();
let mut sub_map = String::new(); let mut exts = Vec::new();
for (sub, sub_exts) in subs { for (top, subs) in dyn_map {
let sub_start = exts.len(); let top_start = exts.len();
exts.extend(sub_exts);
let sub_end = exts.len(); let mut sub_map = String::new();
write!( for (sub, sub_exts) in subs {
sub_map, let sub_start = exts.len();
"({}, ({}, {})),", exts.extend(sub_exts);
unicase_const!(sub), sub_start, sub_end let sub_end = exts.len();
).unwrap();
} write!(
sub_map,
let top_end = exts.len(); "({}, ({}, {})),",
unicase_const!(sub), sub_start, sub_end
write!( ).unwrap();
out, }
"({}, TopLevelExts {{ start: {}, end: {}, subs: &[{}] }}),",
unicase_const!(top), top_start, top_end, sub_map let top_end = exts.len();
).unwrap();
} write!(
out,
writeln!(out, "];").unwrap(); "({}, TopLevelExts {{ start: {}, end: {}, subs: &[{}] }}),",
unicase_const!(top), top_start, top_end, sub_map
writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap(); ).unwrap();
} }
#[cfg(feature = "rev-mappings")] writeln!(out, "];").unwrap();
fn get_rev_mappings(
) -> BTreeMap<UniCase<&'static str>, BTreeMap<UniCase<&'static str>, Vec<&'static str>>> { writeln!(out, "const EXTS: &'static [&'static str] = &{:?};", exts).unwrap();
// First, collect all the mime type -> ext mappings) }
let mut dyn_map = BTreeMap::new();
for &(key, types) in MIME_TYPES { #[cfg(feature = "rev-mappings")]
for val in types { fn get_rev_mappings(
let (top, sub) = split_mime(val); ) -> BTreeMap<UniCase<&'static str>, BTreeMap<UniCase<&'static str>, Vec<&'static str>>> {
dyn_map // First, collect all the mime type -> ext mappings)
.entry(UniCase::new(top)) let mut dyn_map = BTreeMap::new();
.or_insert_with(BTreeMap::new) for &(key, types) in MIME_TYPES {
.entry(UniCase::new(sub)) for val in types {
.or_insert_with(Vec::new) let (top, sub) = split_mime(val);
.push(key); dyn_map
} .entry(UniCase::new(top))
} .or_insert_with(BTreeMap::new)
dyn_map .entry(UniCase::new(sub))
} .or_insert_with(Vec::new)
.push(key);
fn split_mime(mime: &str) -> (&str, &str) { }
let split_idx = mime.find('/').unwrap(); }
(&mime[..split_idx], &mime[split_idx + 1..]) dyn_map
} }
fn split_mime(mime: &str) -> (&str, &str) {
let split_idx = mime.find('/').unwrap();
(&mime[..split_idx], &mime[split_idx + 1..])
}

View File

@@ -1,14 +1,14 @@
extern crate mime_guess; extern crate mime_guess;
fn main() { fn main() {
print_exts("video/*"); print_exts("video/*");
print_exts("video/x-matroska"); print_exts("video/x-matroska");
} }
fn print_exts(mime_type: &str) { fn print_exts(mime_type: &str) {
println!( println!(
"Exts for {:?}: {:?}", "Exts for {:?}: {:?}",
mime_type, mime_type,
mime_guess::get_mime_extensions_str(mime_type) mime_guess::get_mime_extensions_str(mime_type)
); );
} }

View File

@@ -1,41 +1,41 @@
use unicase::UniCase; use unicase::UniCase;
include!("mime_types.rs"); include!("mime_types.rs");
include!(concat!(env!("OUT_DIR"), "/mime_types_generated.rs")); include!(env!("MIME_TYPES_GENERATED_PATH"));
#[cfg(feature = "rev-mappings")] #[cfg(feature = "rev-mappings")]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
struct TopLevelExts { struct TopLevelExts {
start: usize, start: usize,
end: usize, end: usize,
subs: &'static [(UniCase<&'static str>, (usize, usize))], subs: &'static [(UniCase<&'static str>, (usize, usize))],
} }
pub fn get_mime_types(ext: &str) -> Option<&'static [&'static str]> { pub fn get_mime_types(ext: &str) -> Option<&'static [&'static str]> {
let ext = UniCase::new(ext); let ext = UniCase::new(ext);
map_lookup(MIME_TYPES, &ext) map_lookup(MIME_TYPES, &ext)
} }
#[cfg(feature = "rev-mappings")] #[cfg(feature = "rev-mappings")]
pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> { pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> {
if toplevel == "*" { if toplevel == "*" {
return Some(EXTS); return Some(EXTS);
} }
let top = map_lookup(REV_MAPPINGS, toplevel)?; let top = map_lookup(REV_MAPPINGS, toplevel)?;
if sublevel == "*" { if sublevel == "*" {
return Some(&EXTS[top.start..top.end]); return Some(&EXTS[top.start..top.end]);
} }
let sub = map_lookup(&top.subs, sublevel)?; let sub = map_lookup(&top.subs, sublevel)?;
Some(&EXTS[sub.0..sub.1]) Some(&EXTS[sub.0..sub.1])
} }
fn map_lookup<K, V>(map: &'static [(K, V)], key: &str) -> Option<V> fn map_lookup<K, V>(map: &'static [(K, V)], key: &str) -> Option<V>
where K: Copy + Into<UniCase<&'static str>>, V: Copy { where K: Copy + Into<UniCase<&'static str>>, V: Copy {
map.binary_search_by_key(&UniCase::new(key), |(k, _)| (*k).into()) map.binary_search_by_key(&UniCase::new(key), |(k, _)| (*k).into())
.ok() .ok()
.map(|i| map[i].1) .map(|i| map[i].1)
} }

View File

@@ -1,40 +1,40 @@
extern crate phf; extern crate phf;
use unicase::UniCase; use unicase::UniCase;
include!(concat!(env!("OUT_DIR"), "/mime_types_generated.rs")); include!(env!("MIME_TYPES_GENERATED_PATH"));
#[cfg(feature = "rev-mappings")] #[cfg(feature = "rev-mappings")]
struct TopLevelExts { struct TopLevelExts {
start: usize, start: usize,
end: usize, end: usize,
subs: phf::Map<UniCase<&'static str>, (usize, usize)>, subs: phf::Map<UniCase<&'static str>, (usize, usize)>,
} }
pub fn get_mime_types(ext: &str) -> Option<&'static [&'static str]> { pub fn get_mime_types(ext: &str) -> Option<&'static [&'static str]> {
map_lookup(&MIME_TYPES, ext).cloned() map_lookup(&MIME_TYPES, ext).cloned()
} }
pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> { pub fn get_extensions(toplevel: &str, sublevel: &str) -> Option<&'static [&'static str]> {
if toplevel == "*" { if toplevel == "*" {
return Some(EXTS); return Some(EXTS);
} }
let top = map_lookup(&REV_MAPPINGS, toplevel)?; let top = map_lookup(&REV_MAPPINGS, toplevel)?;
if sublevel == "*" { if sublevel == "*" {
return Some(&EXTS[top.start..top.end]); return Some(&EXTS[top.start..top.end]);
} }
let sub = map_lookup(&top.subs, sublevel)?; let sub = map_lookup(&top.subs, sublevel)?;
Some(&EXTS[sub.0..sub.1]) Some(&EXTS[sub.0..sub.1])
} }
fn map_lookup<'key, 'map: 'key, V>( fn map_lookup<'key, 'map: 'key, V>(
map: &'map phf::Map<UniCase<&'static str>, V>, map: &'map phf::Map<UniCase<&'static str>, V>,
key: &'key str, key: &'key str,
) -> Option<&'map V> { ) -> Option<&'map V> {
// FIXME: this doesn't compile unless we transmute `key` to `UniCase<&'static str>` // FIXME: this doesn't compile unless we transmute `key` to `UniCase<&'static str>`
// https://github.com/sfackler/rust-phf/issues/169 // https://github.com/sfackler/rust-phf/issues/169
map.get(&UniCase::new(key)) map.get(&UniCase::new(key))
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,7 @@ const FILE_EXTENSIONS = [
"jpg", "jpg",
"jpeg", "jpeg",
"json", "json",
"jxl",
"m4a", "m4a",
"mdb", "mdb",
"mid", "mid",

View File

@@ -104,6 +104,7 @@ const FILTER_IMAGES_EXTENSIONS = [
"raw", "raw",
"webp", "webp",
"heic", "heic",
"jxl",
]; ];
const FILTER_XML_EXTENSIONS = ["xml"]; const FILTER_XML_EXTENSIONS = ["xml"];

View File

@@ -5,7 +5,7 @@
allFilter=* allFilter=*
htmlFilter=*.html; *.htm; *.shtml; *.xhtml htmlFilter=*.html; *.htm; *.shtml; *.xhtml
textFilter=*.txt; *.text textFilter=*.txt; *.text
imageFilter=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp; *.heic imageFilter=*.jpe; *.jpg; *.jpeg; *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw; *.webp; *.heic; *.avif; *.jxl
xmlFilter=*.xml xmlFilter=*.xml
xulFilter=*.xul xulFilter=*.xul
audioFilter=*.aac; *.aif; *.flac; *.iff; *.m4a; *.m4b; *.mid; *.midi; *.mp3; *.mpa; *.mpc; *.oga; *.ogg; *.opus; *.ra; *.ram; *.snd; *.wav; *.wma audioFilter=*.aac; *.aif; *.flac; *.iff; *.m4a; *.m4b; *.mid; *.midi; *.mp3; *.mpa; *.mpc; *.oga; *.ogg; *.opus; *.ra; *.ram; *.snd; *.wav; *.wma

View File

@@ -932,9 +932,9 @@ set_config("MOZ_SYSTEM_AV1", True, when="--with-system-av1")
option("--disable-jxl", help="Disable jxl image support") option("--disable-jxl", help="Disable jxl image support")
@depends("--disable-jxl", milestone.is_nightly) @depends("--disable-jxl")
def jxl(value, is_nightly): def jxl(value):
if is_nightly and value: if value:
return True return True

View File

@@ -420,7 +420,8 @@ nsresult nsAppShell::Init() {
gchar* name = gdk_pixbuf_format_get_name(format); gchar* name = gdk_pixbuf_format_get_name(format);
if (strcmp(name, "jpeg") && strcmp(name, "png") && strcmp(name, "gif") && if (strcmp(name, "jpeg") && strcmp(name, "png") && strcmp(name, "gif") &&
strcmp(name, "bmp") && strcmp(name, "ico") && strcmp(name, "xpm") && strcmp(name, "bmp") && strcmp(name, "ico") && strcmp(name, "xpm") &&
strcmp(name, "svg") && strcmp(name, "webp") && strcmp(name, "avif")) { strcmp(name, "svg") && strcmp(name, "webp") && strcmp(name, "avif") &&
strcmp(name, "jxl")) {
gdk_pixbuf_format_set_disabled(format, TRUE); gdk_pixbuf_format_set_disabled(format, TRUE);
} }
g_free(name); g_free(name);