forked from mirrors/gecko-dev
Bug 1731773 - Part 1: Run mach vendor for libjxl and highway r=tnikkel
Just library version updates, nothing else. Differential Revision: https://phabricator.services.mozilla.com/D126359
This commit is contained in:
parent
057a1bac29
commit
622ed0f491
296 changed files with 15179 additions and 7669 deletions
|
|
@ -20,11 +20,11 @@ origin:
|
|||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: commit d9882104caf9fb060d328d62cac9ce0a05a191db (2021-05-21T10:02:16Z).
|
||||
release: commit e2397743fe092df68b760d358253773699a16c93 (2021-06-09T08:56:32Z).
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
revision: d9882104caf9fb060d328d62cac9ce0a05a191db
|
||||
revision: e2397743fe092df68b760d358253773699a16c93
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@
|
|||
#define JXL_EXPORT_H
|
||||
|
||||
#define JXL_EXPORT
|
||||
#define JXL_DEPRECATED [[deprecated]]
|
||||
|
||||
#endif /* JXL_EXPORT_H */
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ SOURCES += [
|
|||
"/third_party/jpeg-xl/lib/jxl/base/descriptive_statistics.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/base/padded_bytes.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/base/status.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/base/time.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/blending.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/chroma_from_luma.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/coeff_order.cc",
|
||||
|
|
@ -30,6 +29,7 @@ SOURCES += [
|
|||
"/third_party/jpeg-xl/lib/jxl/convolve.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dct_scales.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_ans.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_cache.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_context_map.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_external_image.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_frame.cc",
|
||||
|
|
@ -43,6 +43,7 @@ SOURCES += [
|
|||
"/third_party/jpeg-xl/lib/jxl/dec_upsample.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/dec_xyb.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/decode.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/decode_to_jpeg.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/enc_bit_writer.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/entropy_coder.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/epf.cc",
|
||||
|
|
@ -66,6 +67,8 @@ SOURCES += [
|
|||
"/third_party/jpeg-xl/lib/jxl/modular/encoding/dec_ma.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/modular/encoding/encoding.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/modular/modular_image.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/modular/transform/rct.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/modular/transform/squeeze.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/modular/transform/transform.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/opsin_params.cc",
|
||||
"/third_party/jpeg-xl/lib/jxl/passes_state.cc",
|
||||
|
|
|
|||
|
|
@ -1,54 +1,54 @@
|
|||
# Version of this schema
|
||||
schema: 1
|
||||
|
||||
bugzilla:
|
||||
# Bugzilla product and component for this directory and subdirectories
|
||||
product: Core
|
||||
component: "ImageLib"
|
||||
|
||||
# Document the source of externally hosted code
|
||||
origin:
|
||||
|
||||
# Short name of the package/library
|
||||
name: jpeg-xl
|
||||
|
||||
description: JPEG XL image format reference implementation
|
||||
|
||||
# Full URL for the package's homepage/etc
|
||||
# Usually different from repository url
|
||||
url: https://gitlab.com/wg1/jpeg-xl
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: commit bdde644b94c125a15e532b2572b96306371a7d4e (2021-05-25T19:02:18.000+02:00).
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
# NOTE(krosylight): Update highway together when updating this!
|
||||
revision: bdde644b94c125a15e532b2572b96306371a7d4e
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
# Multiple licenses can be specified (as a YAML list)
|
||||
# A "LICENSE" file must exist containing the full license text
|
||||
license: Apache-2.0
|
||||
|
||||
license-file: LICENSE
|
||||
|
||||
updatebot:
|
||||
maintainer-phab: saschanaz
|
||||
maintainer-bz: krosylight@mozilla.com
|
||||
tasks:
|
||||
- type: vendoring
|
||||
enabled: True
|
||||
frequency: 3 weeks
|
||||
|
||||
vendoring:
|
||||
url: https://gitlab.com/wg1/jpeg-xl.git
|
||||
source-hosting: gitlab
|
||||
vendor-directory: third_party/jpeg-xl
|
||||
|
||||
exclude:
|
||||
- doc/
|
||||
- third_party/testdata/
|
||||
- tools/
|
||||
# Version of this schema
|
||||
schema: 1
|
||||
|
||||
bugzilla:
|
||||
# Bugzilla product and component for this directory and subdirectories
|
||||
product: Core
|
||||
component: "ImageLib"
|
||||
|
||||
# Document the source of externally hosted code
|
||||
origin:
|
||||
|
||||
# Short name of the package/library
|
||||
name: libjxl
|
||||
|
||||
description: JPEG XL image format reference implementation
|
||||
|
||||
# Full URL for the package's homepage/etc
|
||||
# Usually different from repository url
|
||||
url: https://github.com/libjxl/libjxl
|
||||
|
||||
# Human-readable identifier for this version/release
|
||||
# Generally "version NNN", "tag SSS", "bookmark SSS"
|
||||
release: commit 702cd54420513b754edb60e33b9a4438f7e9ca00 (2021-09-28T08:19:14Z).
|
||||
|
||||
# Revision to pull in
|
||||
# Must be a long or short commit SHA (long preferred)
|
||||
# NOTE(krosylight): Update highway together when updating this!
|
||||
revision: 702cd54420513b754edb60e33b9a4438f7e9ca00
|
||||
|
||||
# The package's license, where possible using the mnemonic from
|
||||
# https://spdx.org/licenses/
|
||||
# Multiple licenses can be specified (as a YAML list)
|
||||
# A "LICENSE" file must exist containing the full license text
|
||||
license: Apache-2.0
|
||||
|
||||
license-file: LICENSE
|
||||
|
||||
updatebot:
|
||||
maintainer-phab: saschanaz
|
||||
maintainer-bz: krosylight@mozilla.com
|
||||
tasks:
|
||||
- type: vendoring
|
||||
enabled: True
|
||||
frequency: 3 weeks
|
||||
|
||||
vendoring:
|
||||
url: https://github.com/libjxl/libjxl.git
|
||||
source-hosting: github
|
||||
vendor-directory: third_party/jpeg-xl
|
||||
|
||||
exclude:
|
||||
- doc/
|
||||
- third_party/testdata/
|
||||
- tools/
|
||||
|
|
|
|||
5
third_party/highway/BUILD
vendored
5
third_party/highway/BUILD
vendored
|
|
@ -103,6 +103,11 @@ cc_library(
|
|||
],
|
||||
compatible_with = [],
|
||||
copts = COPTS,
|
||||
# TODO(janwas): remove once WASM toolchain supports *extend instead of *widen
|
||||
defines = select({
|
||||
"//tools/cc_target_os:wasm": ["HWY_WASM_OLD_NAMES"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
textual_hdrs = [
|
||||
"hwy/foreach_target.h", # public
|
||||
"hwy/ops/arm_neon-inl.h",
|
||||
|
|
|
|||
9
third_party/highway/CMakeLists.txt
vendored
9
third_party/highway/CMakeLists.txt
vendored
|
|
@ -19,7 +19,7 @@ if(POLICY CMP0083)
|
|||
cmake_policy(SET CMP0083 NEW)
|
||||
endif()
|
||||
|
||||
project(hwy VERSION 0.12.1) # Keep in sync with highway.h version
|
||||
project(hwy VERSION 0.12.2) # Keep in sync with highway.h version
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
|
@ -307,8 +307,11 @@ foreach (TESTFILE IN LISTS HWY_TEST_FILES)
|
|||
get_filename_component(TESTNAME ${TESTFILE} NAME_WE)
|
||||
add_executable(${TESTNAME} ${TESTFILE})
|
||||
target_compile_options(${TESTNAME} PRIVATE ${HWY_FLAGS})
|
||||
# Test all targets, not just the best/baseline.
|
||||
target_compile_options(${TESTNAME} PRIVATE -DHWY_COMPILE_ALL_ATTAINABLE=1)
|
||||
# Test all targets, not just the best/baseline. This changes the default
|
||||
# policy to all-attainable; note that setting -DHWY_COMPILE_* directly can
|
||||
# cause compile errors because only one may be set, and other CMakeLists.txt
|
||||
# that include us may set them.
|
||||
target_compile_options(${TESTNAME} PRIVATE -DHWY_IS_TEST=1)
|
||||
|
||||
if(HWY_SYSTEM_GTEST)
|
||||
target_link_libraries(${TESTNAME} hwy hwy_contrib GTest::GTest GTest::Main)
|
||||
|
|
|
|||
7
third_party/highway/debian/changelog
vendored
7
third_party/highway/debian/changelog
vendored
|
|
@ -1,3 +1,10 @@
|
|||
highway (0.12.2-1) UNRELEASED; urgency=medium
|
||||
|
||||
* fix scalar-only test and Windows macro conflict with Load/StoreFence
|
||||
* replace deprecated wasm intrinsics
|
||||
|
||||
-- Jan Wassenberg <janwas@google.com> Mon, 31 May 2021 16:00:00 +0200
|
||||
|
||||
highway (0.12.1-1) UNRELEASED; urgency=medium
|
||||
|
||||
* doc updates, ARM GCC support, fix s390/ppc, complete partial vectors
|
||||
|
|
|
|||
12
third_party/highway/hwy/cache_control.h
vendored
12
third_party/highway/hwy/cache_control.h
vendored
|
|
@ -32,6 +32,14 @@
|
|||
#include <emmintrin.h> // SSE2
|
||||
#endif
|
||||
|
||||
// Windows.h #defines these, which causes infinite recursion. Temporarily
|
||||
// undefine them in this header; these functions are anyway deprecated.
|
||||
// TODO(janwas): remove when these functions are removed.
|
||||
#pragma push_macro("LoadFence")
|
||||
#pragma push_macro("StoreFence")
|
||||
#undef LoadFence
|
||||
#undef StoreFence
|
||||
|
||||
namespace hwy {
|
||||
|
||||
// Even if N*sizeof(T) is smaller, Stream may write a multiple of this size.
|
||||
|
|
@ -92,4 +100,8 @@ HWY_INLINE HWY_ATTR_CACHE void Pause() {
|
|||
|
||||
} // namespace hwy
|
||||
|
||||
// TODO(janwas): remove when these functions are removed. (See above.)
|
||||
#pragma pop_macro("StoreFence")
|
||||
#pragma pop_macro("LoadFence")
|
||||
|
||||
#endif // HIGHWAY_HWY_CACHE_CONTROL_H_
|
||||
|
|
|
|||
2
third_party/highway/hwy/highway.h
vendored
2
third_party/highway/hwy/highway.h
vendored
|
|
@ -28,7 +28,7 @@ namespace hwy {
|
|||
// API version (https://semver.org/); keep in sync with CMakeLists.txt.
|
||||
#define HWY_MAJOR 0
|
||||
#define HWY_MINOR 12
|
||||
#define HWY_PATCH 1
|
||||
#define HWY_PATCH 2
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Shorthand for descriptors (defined in shared-inl.h) used to select overloads.
|
||||
|
|
|
|||
258
third_party/highway/hwy/ops/wasm_128-inl.h
vendored
258
third_party/highway/hwy/ops/wasm_128-inl.h
vendored
|
|
@ -22,6 +22,28 @@
|
|||
#include "hwy/base.h"
|
||||
#include "hwy/ops/shared-inl.h"
|
||||
|
||||
#ifdef HWY_WASM_OLD_NAMES
|
||||
#define wasm_i8x16_shuffle wasm_v8x16_shuffle
|
||||
#define wasm_i16x8_shuffle wasm_v16x8_shuffle
|
||||
#define wasm_i32x4_shuffle wasm_v32x4_shuffle
|
||||
#define wasm_i64x2_shuffle wasm_v64x2_shuffle
|
||||
#define wasm_u16x8_extend_low_u8x16 wasm_i16x8_widen_low_u8x16
|
||||
#define wasm_u32x4_extend_low_u16x8 wasm_i32x4_widen_low_u16x8
|
||||
#define wasm_i32x4_extend_low_i16x8 wasm_i32x4_widen_low_i16x8
|
||||
#define wasm_i16x8_extend_low_i8x16 wasm_i16x8_widen_low_i8x16
|
||||
#define wasm_u32x4_extend_high_u16x8 wasm_i32x4_widen_high_u16x8
|
||||
#define wasm_i32x4_extend_high_i16x8 wasm_i32x4_widen_high_i16x8
|
||||
#define wasm_i32x4_trunc_sat_f32x4 wasm_i32x4_trunc_saturate_f32x4
|
||||
#define wasm_u8x16_add_sat wasm_u8x16_add_saturate
|
||||
#define wasm_u8x16_sub_sat wasm_u8x16_sub_saturate
|
||||
#define wasm_u16x8_add_sat wasm_u16x8_add_saturate
|
||||
#define wasm_u16x8_sub_sat wasm_u16x8_sub_saturate
|
||||
#define wasm_i8x16_add_sat wasm_i8x16_add_saturate
|
||||
#define wasm_i8x16_sub_sat wasm_i8x16_sub_saturate
|
||||
#define wasm_i16x8_add_sat wasm_i16x8_add_saturate
|
||||
#define wasm_i16x8_sub_sat wasm_i16x8_sub_saturate
|
||||
#endif
|
||||
|
||||
HWY_BEFORE_NAMESPACE();
|
||||
namespace hwy {
|
||||
namespace HWY_NAMESPACE {
|
||||
|
|
@ -281,24 +303,24 @@ HWY_API Vec128<float, N> operator-(const Vec128<float, N> a,
|
|||
template <size_t N>
|
||||
HWY_API Vec128<uint8_t, N> SaturatedAdd(const Vec128<uint8_t, N> a,
|
||||
const Vec128<uint8_t, N> b) {
|
||||
return Vec128<uint8_t, N>{wasm_u8x16_add_saturate(a.raw, b.raw)};
|
||||
return Vec128<uint8_t, N>{wasm_u8x16_add_sat(a.raw, b.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint16_t, N> SaturatedAdd(const Vec128<uint16_t, N> a,
|
||||
const Vec128<uint16_t, N> b) {
|
||||
return Vec128<uint16_t, N>{wasm_u16x8_add_saturate(a.raw, b.raw)};
|
||||
return Vec128<uint16_t, N>{wasm_u16x8_add_sat(a.raw, b.raw)};
|
||||
}
|
||||
|
||||
// Signed
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int8_t, N> SaturatedAdd(const Vec128<int8_t, N> a,
|
||||
const Vec128<int8_t, N> b) {
|
||||
return Vec128<int8_t, N>{wasm_i8x16_add_saturate(a.raw, b.raw)};
|
||||
return Vec128<int8_t, N>{wasm_i8x16_add_sat(a.raw, b.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N> SaturatedAdd(const Vec128<int16_t, N> a,
|
||||
const Vec128<int16_t, N> b) {
|
||||
return Vec128<int16_t, N>{wasm_i16x8_add_saturate(a.raw, b.raw)};
|
||||
return Vec128<int16_t, N>{wasm_i16x8_add_sat(a.raw, b.raw)};
|
||||
}
|
||||
|
||||
// ------------------------------ Saturating subtraction
|
||||
|
|
@ -309,24 +331,24 @@ HWY_API Vec128<int16_t, N> SaturatedAdd(const Vec128<int16_t, N> a,
|
|||
template <size_t N>
|
||||
HWY_API Vec128<uint8_t, N> SaturatedSub(const Vec128<uint8_t, N> a,
|
||||
const Vec128<uint8_t, N> b) {
|
||||
return Vec128<uint8_t, N>{wasm_u8x16_sub_saturate(a.raw, b.raw)};
|
||||
return Vec128<uint8_t, N>{wasm_u8x16_sub_sat(a.raw, b.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint16_t, N> SaturatedSub(const Vec128<uint16_t, N> a,
|
||||
const Vec128<uint16_t, N> b) {
|
||||
return Vec128<uint16_t, N>{wasm_u16x8_sub_saturate(a.raw, b.raw)};
|
||||
return Vec128<uint16_t, N>{wasm_u16x8_sub_sat(a.raw, b.raw)};
|
||||
}
|
||||
|
||||
// Signed
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int8_t, N> SaturatedSub(const Vec128<int8_t, N> a,
|
||||
const Vec128<int8_t, N> b) {
|
||||
return Vec128<int8_t, N>{wasm_i8x16_sub_saturate(a.raw, b.raw)};
|
||||
return Vec128<int8_t, N>{wasm_i8x16_sub_sat(a.raw, b.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N> SaturatedSub(const Vec128<int16_t, N> a,
|
||||
const Vec128<int16_t, N> b) {
|
||||
return Vec128<int16_t, N>{wasm_i16x8_sub_saturate(a.raw, b.raw)};
|
||||
return Vec128<int16_t, N>{wasm_i16x8_sub_sat(a.raw, b.raw)};
|
||||
}
|
||||
|
||||
// ------------------------------ Average
|
||||
|
|
@ -679,29 +701,29 @@ template <size_t N>
|
|||
HWY_API Vec128<uint16_t, N> MulHigh(const Vec128<uint16_t, N> a,
|
||||
const Vec128<uint16_t, N> b) {
|
||||
// TODO(eustas): replace, when implemented in WASM.
|
||||
const auto al = wasm_i32x4_widen_low_u16x8(a.raw);
|
||||
const auto ah = wasm_i32x4_widen_high_u16x8(a.raw);
|
||||
const auto bl = wasm_i32x4_widen_low_u16x8(b.raw);
|
||||
const auto bh = wasm_i32x4_widen_high_u16x8(b.raw);
|
||||
const auto al = wasm_u32x4_extend_low_u16x8(a.raw);
|
||||
const auto ah = wasm_u32x4_extend_high_u16x8(a.raw);
|
||||
const auto bl = wasm_u32x4_extend_low_u16x8(b.raw);
|
||||
const auto bh = wasm_u32x4_extend_high_u16x8(b.raw);
|
||||
const auto l = wasm_i32x4_mul(al, bl);
|
||||
const auto h = wasm_i32x4_mul(ah, bh);
|
||||
// TODO(eustas): shift-right + narrow?
|
||||
return Vec128<uint16_t, N>{
|
||||
wasm_v16x8_shuffle(l, h, 1, 3, 5, 7, 9, 11, 13, 15)};
|
||||
wasm_i16x8_shuffle(l, h, 1, 3, 5, 7, 9, 11, 13, 15)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N> MulHigh(const Vec128<int16_t, N> a,
|
||||
const Vec128<int16_t, N> b) {
|
||||
// TODO(eustas): replace, when implemented in WASM.
|
||||
const auto al = wasm_i32x4_widen_low_i16x8(a.raw);
|
||||
const auto ah = wasm_i32x4_widen_high_i16x8(a.raw);
|
||||
const auto bl = wasm_i32x4_widen_low_i16x8(b.raw);
|
||||
const auto bh = wasm_i32x4_widen_high_i16x8(b.raw);
|
||||
const auto al = wasm_i32x4_extend_low_i16x8(a.raw);
|
||||
const auto ah = wasm_i32x4_extend_high_i16x8(a.raw);
|
||||
const auto bl = wasm_i32x4_extend_low_i16x8(b.raw);
|
||||
const auto bh = wasm_i32x4_extend_high_i16x8(b.raw);
|
||||
const auto l = wasm_i32x4_mul(al, bl);
|
||||
const auto h = wasm_i32x4_mul(ah, bh);
|
||||
// TODO(eustas): shift-right + narrow?
|
||||
return Vec128<int16_t, N>{
|
||||
wasm_v16x8_shuffle(l, h, 1, 3, 5, 7, 9, 11, 13, 15)};
|
||||
wasm_i16x8_shuffle(l, h, 1, 3, 5, 7, 9, 11, 13, 15)};
|
||||
}
|
||||
|
||||
// Multiplies even lanes (0, 2 ..) and returns the double-width result.
|
||||
|
|
@ -997,12 +1019,12 @@ HWY_API Mask128<int64_t, N> operator>(const Vec128<int64_t, N> a,
|
|||
|
||||
// Otherwise, the lower half decides.
|
||||
const auto m_eq = a32 == b32;
|
||||
const auto lo_in_hi = wasm_v32x4_shuffle(m_gt, m_gt, 2, 2, 0, 0);
|
||||
const auto lo_in_hi = wasm_i32x4_shuffle(m_gt, m_gt, 2, 2, 0, 0);
|
||||
const auto lo_gt = And(m_eq, lo_in_hi);
|
||||
|
||||
const auto gt = Or(lo_gt, m_gt);
|
||||
// Copy result in upper 32 bits to lower 32 bits.
|
||||
return Mask128<int64_t, N>{wasm_v32x4_shuffle(gt, gt, 3, 3, 1, 1)};
|
||||
return Mask128<int64_t, N>{wasm_i32x4_shuffle(gt, gt, 3, 3, 1, 1)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
|
|
@ -1496,12 +1518,12 @@ HWY_API Vec128<T, N / 2> LowerHalf(Vec128<T, N> v) {
|
|||
template <typename T>
|
||||
HWY_API Vec128<T, 8 / sizeof(T)> UpperHalf(Vec128<T> v) {
|
||||
// TODO(eustas): use swizzle?
|
||||
return Vec128<T, 8 / sizeof(T)>{wasm_v32x4_shuffle(v.raw, v.raw, 2, 3, 2, 3)};
|
||||
return Vec128<T, 8 / sizeof(T)>{wasm_i32x4_shuffle(v.raw, v.raw, 2, 3, 2, 3)};
|
||||
}
|
||||
template <>
|
||||
HWY_INLINE Vec128<float, 2> UpperHalf(Vec128<float> v) {
|
||||
// TODO(eustas): use swizzle?
|
||||
return Vec128<float, 2>{wasm_v32x4_shuffle(v.raw, v.raw, 2, 3, 2, 3)};
|
||||
return Vec128<float, 2>{wasm_i32x4_shuffle(v.raw, v.raw, 2, 3, 2, 3)};
|
||||
}
|
||||
|
||||
// ------------------------------ Shift vector by constant #bytes
|
||||
|
|
@ -1516,64 +1538,64 @@ HWY_API Vec128<T> ShiftLeftBytes(const Vec128<T> v) {
|
|||
return v;
|
||||
|
||||
case 1:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 0, 1, 2, 3, 4, 5, 6,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14)};
|
||||
|
||||
case 2:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 0, 1, 2, 3, 4, 5,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 0, 1, 2, 3, 4, 5,
|
||||
6, 7, 8, 9, 10, 11, 12, 13)};
|
||||
|
||||
case 3:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 0, 1, 2, 3,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 0, 1, 2, 3,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 12)};
|
||||
|
||||
case 4:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 0, 1, 2,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 0, 1, 2,
|
||||
3, 4, 5, 6, 7, 8, 9, 10, 11)};
|
||||
|
||||
case 5:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 0, 1,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 0, 1,
|
||||
2, 3, 4, 5, 6, 7, 8, 9, 10)};
|
||||
|
||||
case 6:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9)};
|
||||
|
||||
case 7:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 0, 1, 2, 3, 4, 5, 6, 7, 8)};
|
||||
|
||||
case 8:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 0, 1, 2, 3, 4, 5, 6, 7)};
|
||||
|
||||
case 9:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 0, 1, 2, 3, 4, 5, 6)};
|
||||
|
||||
case 10:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 0, 1, 2, 3, 4, 5)};
|
||||
|
||||
case 11:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 0, 1, 2, 3, 4)};
|
||||
|
||||
case 12:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 0, 1, 2, 3)};
|
||||
|
||||
case 13:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 0, 1, 2)};
|
||||
|
||||
case 14:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 0,
|
||||
1)};
|
||||
|
||||
case 15:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
0)};
|
||||
}
|
||||
|
|
@ -1597,69 +1619,69 @@ HWY_API Vec128<T> ShiftRightBytes(const Vec128<T> v) {
|
|||
return v;
|
||||
|
||||
case 1:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16)};
|
||||
|
||||
case 2:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 16)};
|
||||
|
||||
case 3:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 16, 16)};
|
||||
|
||||
case 4:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 4, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 16, 16, 16)};
|
||||
|
||||
case 5:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 5, 6, 7, 8, 9, 10, 11,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 16, 16, 16, 16)};
|
||||
|
||||
case 6:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 6, 7, 8, 9, 10, 11, 12,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 6, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 16, 16, 16, 16, 16)};
|
||||
|
||||
case 7:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 7, 8, 9, 10, 11, 12, 13,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 7, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 16, 16, 16, 16, 16, 16)};
|
||||
|
||||
case 8:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 8, 9, 10, 11, 12, 13, 14,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 16, 16, 16, 16, 16, 16, 16)};
|
||||
|
||||
case 9:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 9, 10, 11, 12, 13, 14,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 10:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 10, 11, 12, 13, 14, 15,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 10, 11, 12, 13, 14, 15,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 11:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 11, 12, 13, 14, 15, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 11, 12, 13, 14, 15, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 12:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 12, 13, 14, 15, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 12, 13, 14, 15, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 13:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 13, 14, 15, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 13, 14, 15, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 14:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 14, 15, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 14, 15, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
|
||||
case 15:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(v.raw, zero, 15, 16, 16, 16, 16, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(v.raw, zero, 15, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16)};
|
||||
}
|
||||
|
|
@ -1685,72 +1707,72 @@ HWY_API Vec128<T> CombineShiftRightBytes(const Vec128<T> hi,
|
|||
return lo;
|
||||
|
||||
case 1:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 1, 2, 3, 4, 5, 6, 7,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15, 16)};
|
||||
|
||||
case 2:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 2, 3, 4, 5, 6, 7, 8,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16, 17)};
|
||||
|
||||
case 3:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 3, 4, 5, 6, 7, 8, 9,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18)};
|
||||
|
||||
case 4:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 4, 5, 6, 7, 8, 9, 10,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 4, 5, 6, 7, 8, 9, 10,
|
||||
11, 12, 13, 14, 15, 16, 17, 18, 19)};
|
||||
|
||||
case 5:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 5, 6, 7, 8, 9, 10, 11,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 5, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20)};
|
||||
|
||||
case 6:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 6, 7, 8, 9, 10, 11,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 6, 7, 8, 9, 10, 11,
|
||||
12, 13, 14, 15, 16, 17, 18, 19, 20,
|
||||
21)};
|
||||
|
||||
case 7:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 7, 8, 9, 10, 11, 12,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 7, 8, 9, 10, 11, 12,
|
||||
13, 14, 15, 16, 17, 18, 19, 20, 21,
|
||||
22)};
|
||||
|
||||
case 8:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 8, 9, 10, 11, 12, 13,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 8, 9, 10, 11, 12, 13,
|
||||
14, 15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23)};
|
||||
|
||||
case 9:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 9, 10, 11, 12, 13, 14,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24)};
|
||||
|
||||
case 10:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 10, 11, 12, 13, 14,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25)};
|
||||
|
||||
case 11:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 11, 12, 13, 14, 15,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26)};
|
||||
|
||||
case 12:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 12, 13, 14, 15, 16,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||
26, 27)};
|
||||
|
||||
case 13:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 13, 14, 15, 16, 17,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 13, 14, 15, 16, 17,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 26,
|
||||
27, 28)};
|
||||
|
||||
case 14:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 14, 15, 16, 17, 18,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29)};
|
||||
|
||||
case 15:
|
||||
return Vec128<T>{wasm_v8x16_shuffle(lo.raw, hi.raw, 15, 16, 17, 18, 19,
|
||||
return Vec128<T>{wasm_i8x16_shuffle(lo.raw, hi.raw, 15, 16, 17, 18, 19,
|
||||
20, 21, 22, 23, 24, 25, 26, 27, 28,
|
||||
29, 30)};
|
||||
}
|
||||
|
|
@ -1763,28 +1785,28 @@ HWY_API Vec128<T> CombineShiftRightBytes(const Vec128<T> hi,
|
|||
template <int kLane, size_t N>
|
||||
HWY_API Vec128<uint16_t, N> Broadcast(const Vec128<uint16_t, N> v) {
|
||||
static_assert(0 <= kLane && kLane < N, "Invalid lane");
|
||||
return Vec128<uint16_t, N>{wasm_v16x8_shuffle(
|
||||
return Vec128<uint16_t, N>{wasm_i16x8_shuffle(
|
||||
v.raw, v.raw, kLane, kLane, kLane, kLane, kLane, kLane, kLane, kLane)};
|
||||
}
|
||||
template <int kLane, size_t N>
|
||||
HWY_API Vec128<uint32_t, N> Broadcast(const Vec128<uint32_t, N> v) {
|
||||
static_assert(0 <= kLane && kLane < N, "Invalid lane");
|
||||
return Vec128<uint32_t, N>{
|
||||
wasm_v32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
wasm_i32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
}
|
||||
|
||||
// Signed
|
||||
template <int kLane, size_t N>
|
||||
HWY_API Vec128<int16_t, N> Broadcast(const Vec128<int16_t, N> v) {
|
||||
static_assert(0 <= kLane && kLane < N, "Invalid lane");
|
||||
return Vec128<int16_t, N>{wasm_v16x8_shuffle(
|
||||
return Vec128<int16_t, N>{wasm_i16x8_shuffle(
|
||||
v.raw, v.raw, kLane, kLane, kLane, kLane, kLane, kLane, kLane, kLane)};
|
||||
}
|
||||
template <int kLane, size_t N>
|
||||
HWY_API Vec128<int32_t, N> Broadcast(const Vec128<int32_t, N> v) {
|
||||
static_assert(0 <= kLane && kLane < N, "Invalid lane");
|
||||
return Vec128<int32_t, N>{
|
||||
wasm_v32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
wasm_i32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
}
|
||||
|
||||
// Float
|
||||
|
|
@ -1792,7 +1814,7 @@ template <int kLane, size_t N>
|
|||
HWY_API Vec128<float, N> Broadcast(const Vec128<float, N> v) {
|
||||
static_assert(0 <= kLane && kLane < N, "Invalid lane");
|
||||
return Vec128<float, N>{
|
||||
wasm_v32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
wasm_i32x4_shuffle(v.raw, v.raw, kLane, kLane, kLane, kLane)};
|
||||
}
|
||||
|
||||
// ------------------------------ Shuffle bytes with variable indices
|
||||
|
|
@ -1807,7 +1829,7 @@ HWY_API Vec128<T, N> TableLookupBytes(const Vec128<T, N> bytes,
|
|||
// V8 implementation of this had a bug, fixed on 2021-04-03:
|
||||
// https://chromium-review.googlesource.com/c/v8/v8/+/2822951
|
||||
#if 0
|
||||
return Vec128<T, N>{wasm_v8x16_swizzle(bytes.raw, from.raw)};
|
||||
return Vec128<T, N>{wasm_i8x16_swizzle(bytes.raw, from.raw)};
|
||||
#else
|
||||
alignas(16) uint8_t control[16];
|
||||
alignas(16) uint8_t input[16];
|
||||
|
|
@ -1830,56 +1852,56 @@ HWY_API Vec128<T, N> TableLookupBytes(const Vec128<T, N> bytes,
|
|||
|
||||
// Swap 32-bit halves in 64-bit halves.
|
||||
HWY_API Vec128<uint32_t> Shuffle2301(const Vec128<uint32_t> v) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
}
|
||||
HWY_API Vec128<int32_t> Shuffle2301(const Vec128<int32_t> v) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
}
|
||||
HWY_API Vec128<float> Shuffle2301(const Vec128<float> v) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 0, 3, 2)};
|
||||
}
|
||||
|
||||
// Swap 64-bit halves
|
||||
HWY_API Vec128<uint32_t> Shuffle1032(const Vec128<uint32_t> v) {
|
||||
return Vec128<uint32_t>{wasm_v64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
return Vec128<uint32_t>{wasm_i64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
}
|
||||
HWY_API Vec128<int32_t> Shuffle1032(const Vec128<int32_t> v) {
|
||||
return Vec128<int32_t>{wasm_v64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
return Vec128<int32_t>{wasm_i64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
}
|
||||
HWY_API Vec128<float> Shuffle1032(const Vec128<float> v) {
|
||||
return Vec128<float>{wasm_v64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
return Vec128<float>{wasm_i64x2_shuffle(v.raw, v.raw, 1, 0)};
|
||||
}
|
||||
|
||||
// Rotate right 32 bits
|
||||
HWY_API Vec128<uint32_t> Shuffle0321(const Vec128<uint32_t> v) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
}
|
||||
HWY_API Vec128<int32_t> Shuffle0321(const Vec128<int32_t> v) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
}
|
||||
HWY_API Vec128<float> Shuffle0321(const Vec128<float> v) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(v.raw, v.raw, 1, 2, 3, 0)};
|
||||
}
|
||||
// Rotate left 32 bits
|
||||
HWY_API Vec128<uint32_t> Shuffle2103(const Vec128<uint32_t> v) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
}
|
||||
HWY_API Vec128<int32_t> Shuffle2103(const Vec128<int32_t> v) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
}
|
||||
HWY_API Vec128<float> Shuffle2103(const Vec128<float> v) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 0, 1, 2)};
|
||||
}
|
||||
|
||||
// Reverse
|
||||
HWY_API Vec128<uint32_t> Shuffle0123(const Vec128<uint32_t> v) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
}
|
||||
HWY_API Vec128<int32_t> Shuffle0123(const Vec128<int32_t> v) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
}
|
||||
HWY_API Vec128<float> Shuffle0123(const Vec128<float> v) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(v.raw, v.raw, 3, 2, 1, 0)};
|
||||
}
|
||||
|
||||
// ------------------------------ TableLookupLanes
|
||||
|
|
@ -1936,33 +1958,33 @@ HWY_API Vec128<float, N> TableLookupLanes(const Vec128<float, N> v,
|
|||
template <size_t N>
|
||||
HWY_API Vec128<uint16_t, (N + 1) / 2> ZipLower(const Vec128<uint8_t, N> a,
|
||||
const Vec128<uint8_t, N> b) {
|
||||
return Vec128<uint16_t, (N + 1) / 2>{wasm_v8x16_shuffle(
|
||||
return Vec128<uint16_t, (N + 1) / 2>{wasm_i8x16_shuffle(
|
||||
a.raw, b.raw, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint32_t, (N + 1) / 2> ZipLower(const Vec128<uint16_t, N> a,
|
||||
const Vec128<uint16_t, N> b) {
|
||||
return Vec128<uint32_t, (N + 1) / 2>{
|
||||
wasm_v16x8_shuffle(a.raw, b.raw, 0, 8, 1, 9, 2, 10, 3, 11)};
|
||||
wasm_i16x8_shuffle(a.raw, b.raw, 0, 8, 1, 9, 2, 10, 3, 11)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, (N + 1) / 2> ZipLower(const Vec128<int8_t, N> a,
|
||||
const Vec128<int8_t, N> b) {
|
||||
return Vec128<int16_t, (N + 1) / 2>{wasm_v8x16_shuffle(
|
||||
return Vec128<int16_t, (N + 1) / 2>{wasm_i8x16_shuffle(
|
||||
a.raw, b.raw, 0, 16, 1, 17, 2, 18, 3, 19, 4, 20, 5, 21, 6, 22, 7, 23)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, (N + 1) / 2> ZipLower(const Vec128<int16_t, N> a,
|
||||
const Vec128<int16_t, N> b) {
|
||||
return Vec128<int32_t, (N + 1) / 2>{
|
||||
wasm_v16x8_shuffle(a.raw, b.raw, 0, 8, 1, 9, 2, 10, 3, 11)};
|
||||
wasm_i16x8_shuffle(a.raw, b.raw, 0, 8, 1, 9, 2, 10, 3, 11)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint16_t, N / 2> ZipUpper(const Vec128<uint8_t, N> a,
|
||||
const Vec128<uint8_t, N> b) {
|
||||
return Vec128<uint16_t, N / 2>{wasm_v8x16_shuffle(a.raw, b.raw, 8, 24, 9, 25,
|
||||
return Vec128<uint16_t, N / 2>{wasm_i8x16_shuffle(a.raw, b.raw, 8, 24, 9, 25,
|
||||
10, 26, 11, 27, 12, 28, 13,
|
||||
29, 14, 30, 15, 31)};
|
||||
}
|
||||
|
|
@ -1970,13 +1992,13 @@ template <size_t N>
|
|||
HWY_API Vec128<uint32_t, N / 2> ZipUpper(const Vec128<uint16_t, N> a,
|
||||
const Vec128<uint16_t, N> b) {
|
||||
return Vec128<uint32_t, N / 2>{
|
||||
wasm_v16x8_shuffle(a.raw, b.raw, 4, 12, 5, 13, 6, 14, 7, 15)};
|
||||
wasm_i16x8_shuffle(a.raw, b.raw, 4, 12, 5, 13, 6, 14, 7, 15)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N / 2> ZipUpper(const Vec128<int8_t, N> a,
|
||||
const Vec128<int8_t, N> b) {
|
||||
return Vec128<int16_t, N / 2>{wasm_v8x16_shuffle(a.raw, b.raw, 8, 24, 9, 25,
|
||||
return Vec128<int16_t, N / 2>{wasm_i8x16_shuffle(a.raw, b.raw, 8, 24, 9, 25,
|
||||
10, 26, 11, 27, 12, 28, 13,
|
||||
29, 14, 30, 15, 31)};
|
||||
}
|
||||
|
|
@ -1984,7 +2006,7 @@ template <size_t N>
|
|||
HWY_API Vec128<int32_t, N / 2> ZipUpper(const Vec128<int16_t, N> a,
|
||||
const Vec128<int16_t, N> b) {
|
||||
return Vec128<int32_t, N / 2>{
|
||||
wasm_v16x8_shuffle(a.raw, b.raw, 4, 12, 5, 13, 6, 14, 7, 15)};
|
||||
wasm_i16x8_shuffle(a.raw, b.raw, 4, 12, 5, 13, 6, 14, 7, 15)};
|
||||
}
|
||||
|
||||
// ------------------------------ Interleave lanes
|
||||
|
|
@ -2000,17 +2022,17 @@ HWY_API Vec128<T> InterleaveLower(const Vec128<T> a, const Vec128<T> b) {
|
|||
template <>
|
||||
HWY_INLINE Vec128<uint32_t> InterleaveLower<uint32_t>(
|
||||
const Vec128<uint32_t> a, const Vec128<uint32_t> b) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
}
|
||||
template <>
|
||||
HWY_INLINE Vec128<int32_t> InterleaveLower<int32_t>(const Vec128<int32_t> a,
|
||||
const Vec128<int32_t> b) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
}
|
||||
template <>
|
||||
HWY_INLINE Vec128<float> InterleaveLower<float>(const Vec128<float> a,
|
||||
const Vec128<float> b) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(a.raw, b.raw, 0, 4, 1, 5)};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -2020,17 +2042,17 @@ HWY_API Vec128<T> InterleaveUpper(const Vec128<T> a, const Vec128<T> b) {
|
|||
template <>
|
||||
HWY_INLINE Vec128<uint32_t> InterleaveUpper<uint32_t>(
|
||||
const Vec128<uint32_t> a, const Vec128<uint32_t> b) {
|
||||
return Vec128<uint32_t>{wasm_v32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
return Vec128<uint32_t>{wasm_i32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
}
|
||||
template <>
|
||||
HWY_INLINE Vec128<int32_t> InterleaveUpper<int32_t>(const Vec128<int32_t> a,
|
||||
const Vec128<int32_t> b) {
|
||||
return Vec128<int32_t>{wasm_v32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
return Vec128<int32_t>{wasm_i32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
}
|
||||
template <>
|
||||
HWY_INLINE Vec128<float> InterleaveUpper<float>(const Vec128<float> a,
|
||||
const Vec128<float> b) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(a.raw, b.raw, 2, 6, 3, 7)};
|
||||
}
|
||||
|
||||
// ------------------------------ Blocks
|
||||
|
|
@ -2038,13 +2060,13 @@ HWY_INLINE Vec128<float> InterleaveUpper<float>(const Vec128<float> a,
|
|||
// hiH,hiL loH,loL |-> hiL,loL (= lower halves)
|
||||
template <typename T>
|
||||
HWY_API Vec128<T> ConcatLowerLower(const Vec128<T> hi, const Vec128<T> lo) {
|
||||
return Vec128<T>{wasm_v64x2_shuffle(lo.raw, hi.raw, 0, 2)};
|
||||
return Vec128<T>{wasm_i64x2_shuffle(lo.raw, hi.raw, 0, 2)};
|
||||
}
|
||||
|
||||
// hiH,hiL loH,loL |-> hiH,loH (= upper halves)
|
||||
template <typename T>
|
||||
HWY_API Vec128<T> ConcatUpperUpper(const Vec128<T> hi, const Vec128<T> lo) {
|
||||
return Vec128<T>{wasm_v64x2_shuffle(lo.raw, hi.raw, 1, 3)};
|
||||
return Vec128<T>{wasm_i64x2_shuffle(lo.raw, hi.raw, 1, 3)};
|
||||
}
|
||||
|
||||
// hiH,hiL loH,loL |-> hiL,loH (= inner halves)
|
||||
|
|
@ -2056,7 +2078,7 @@ HWY_API Vec128<T> ConcatLowerUpper(const Vec128<T> hi, const Vec128<T> lo) {
|
|||
// hiH,hiL loH,loL |-> hiH,loL (= outer halves)
|
||||
template <typename T>
|
||||
HWY_API Vec128<T> ConcatUpperLower(const Vec128<T> hi, const Vec128<T> lo) {
|
||||
return Vec128<T>{wasm_v64x2_shuffle(lo.raw, hi.raw, 0, 3)};
|
||||
return Vec128<T>{wasm_i64x2_shuffle(lo.raw, hi.raw, 0, 3)};
|
||||
}
|
||||
|
||||
// ------------------------------ Odd/even lanes
|
||||
|
|
@ -2075,12 +2097,12 @@ HWY_API Vec128<T> odd_even_impl(hwy::SizeTag<1> /* tag */, const Vec128<T> a,
|
|||
template <typename T>
|
||||
HWY_API Vec128<T> odd_even_impl(hwy::SizeTag<2> /* tag */, const Vec128<T> a,
|
||||
const Vec128<T> b) {
|
||||
return Vec128<T>{wasm_v16x8_shuffle(a.raw, b.raw, 8, 1, 10, 3, 12, 5, 14, 7)};
|
||||
return Vec128<T>{wasm_i16x8_shuffle(a.raw, b.raw, 8, 1, 10, 3, 12, 5, 14, 7)};
|
||||
}
|
||||
template <typename T>
|
||||
HWY_API Vec128<T> odd_even_impl(hwy::SizeTag<4> /* tag */, const Vec128<T> a,
|
||||
const Vec128<T> b) {
|
||||
return Vec128<T>{wasm_v32x4_shuffle(a.raw, b.raw, 4, 1, 6, 3)};
|
||||
return Vec128<T>{wasm_i32x4_shuffle(a.raw, b.raw, 4, 1, 6, 3)};
|
||||
}
|
||||
// TODO(eustas): implement
|
||||
// template <typename T>
|
||||
|
|
@ -2097,7 +2119,7 @@ HWY_API Vec128<T> OddEven(const Vec128<T> a, const Vec128<T> b) {
|
|||
template <>
|
||||
HWY_INLINE Vec128<float> OddEven<float>(const Vec128<float> a,
|
||||
const Vec128<float> b) {
|
||||
return Vec128<float>{wasm_v32x4_shuffle(a.raw, b.raw, 4, 1, 6, 3)};
|
||||
return Vec128<float>{wasm_i32x4_shuffle(a.raw, b.raw, 4, 1, 6, 3)};
|
||||
}
|
||||
|
||||
// ================================================== CONVERT
|
||||
|
|
@ -2108,52 +2130,52 @@ HWY_INLINE Vec128<float> OddEven<float>(const Vec128<float> a,
|
|||
template <size_t N>
|
||||
HWY_API Vec128<uint16_t, N> PromoteTo(Simd<uint16_t, N> /* tag */,
|
||||
const Vec128<uint8_t, N> v) {
|
||||
return Vec128<uint16_t, N>{wasm_i16x8_widen_low_u8x16(v.raw)};
|
||||
return Vec128<uint16_t, N>{wasm_u16x8_extend_low_u8x16(v.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint32_t, N> PromoteTo(Simd<uint32_t, N> /* tag */,
|
||||
const Vec128<uint8_t, N> v) {
|
||||
return Vec128<uint32_t, N>{
|
||||
wasm_i32x4_widen_low_u16x8(wasm_i16x8_widen_low_u8x16(v.raw))};
|
||||
wasm_u32x4_extend_low_u16x8(wasm_u16x8_extend_low_u8x16(v.raw))};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N> PromoteTo(Simd<int16_t, N> /* tag */,
|
||||
const Vec128<uint8_t, N> v) {
|
||||
return Vec128<int16_t, N>{wasm_i16x8_widen_low_u8x16(v.raw)};
|
||||
return Vec128<int16_t, N>{wasm_u16x8_extend_low_u8x16(v.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, N> PromoteTo(Simd<int32_t, N> /* tag */,
|
||||
const Vec128<uint8_t, N> v) {
|
||||
return Vec128<int32_t, N>{
|
||||
wasm_i32x4_widen_low_u16x8(wasm_i16x8_widen_low_u8x16(v.raw))};
|
||||
wasm_u32x4_extend_low_u16x8(wasm_u16x8_extend_low_u8x16(v.raw))};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<uint32_t, N> PromoteTo(Simd<uint32_t, N> /* tag */,
|
||||
const Vec128<uint16_t, N> v) {
|
||||
return Vec128<uint32_t, N>{wasm_i32x4_widen_low_u16x8(v.raw)};
|
||||
return Vec128<uint32_t, N>{wasm_u32x4_extend_low_u16x8(v.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, N> PromoteTo(Simd<int32_t, N> /* tag */,
|
||||
const Vec128<uint16_t, N> v) {
|
||||
return Vec128<int32_t, N>{wasm_i32x4_widen_low_u16x8(v.raw)};
|
||||
return Vec128<int32_t, N>{wasm_u32x4_extend_low_u16x8(v.raw)};
|
||||
}
|
||||
|
||||
// Signed: replicate sign bit.
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int16_t, N> PromoteTo(Simd<int16_t, N> /* tag */,
|
||||
const Vec128<int8_t, N> v) {
|
||||
return Vec128<int16_t, N>{wasm_i16x8_widen_low_i8x16(v.raw)};
|
||||
return Vec128<int16_t, N>{wasm_i16x8_extend_low_i8x16(v.raw)};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, N> PromoteTo(Simd<int32_t, N> /* tag */,
|
||||
const Vec128<int8_t, N> v) {
|
||||
return Vec128<int32_t, N>{
|
||||
wasm_i32x4_widen_low_i16x8(wasm_i16x8_widen_low_i8x16(v.raw))};
|
||||
wasm_i32x4_extend_low_i16x8(wasm_i16x8_extend_low_i8x16(v.raw))};
|
||||
}
|
||||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, N> PromoteTo(Simd<int32_t, N> /* tag */,
|
||||
const Vec128<int16_t, N> v) {
|
||||
return Vec128<int32_t, N>{wasm_i32x4_widen_low_i16x8(v.raw)};
|
||||
return Vec128<int32_t, N>{wasm_i32x4_extend_low_i16x8(v.raw)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
|
|
@ -2291,7 +2313,7 @@ HWY_API Vec128<float, N> ConvertTo(Simd<float, N> /* tag */,
|
|||
template <size_t N>
|
||||
HWY_API Vec128<int32_t, N> ConvertTo(Simd<int32_t, N> /* tag */,
|
||||
const Vec128<float, N> v) {
|
||||
return Vec128<int32_t, N>{wasm_i32x4_trunc_saturate_f32x4(v.raw)};
|
||||
return Vec128<int32_t, N>{wasm_i32x4_trunc_sat_f32x4(v.raw)};
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
|
|
|
|||
3
third_party/highway/hwy/targets.h
vendored
3
third_party/highway/hwy/targets.h
vendored
|
|
@ -269,13 +269,12 @@
|
|||
#define HWY_TARGETS HWY_STATIC_TARGET
|
||||
|
||||
// 3) For tests: include all attainable targets (in particular: scalar)
|
||||
#elif defined(HWY_COMPILE_ALL_ATTAINABLE)
|
||||
#elif defined(HWY_COMPILE_ALL_ATTAINABLE) || defined(HWY_IS_TEST)
|
||||
#define HWY_TARGETS HWY_ATTAINABLE_TARGETS
|
||||
|
||||
// 4) Default: attainable WITHOUT non-best baseline. This reduces code size by
|
||||
// excluding superseded targets, in particular scalar.
|
||||
#else
|
||||
|
||||
#define HWY_TARGETS (HWY_ATTAINABLE_TARGETS & (2 * HWY_STATIC_TARGET - 1))
|
||||
|
||||
#endif // target policy
|
||||
|
|
|
|||
16
third_party/highway/hwy/tests/logical_test.cc
vendored
16
third_party/highway/hwy/tests/logical_test.cc
vendored
|
|
@ -166,15 +166,21 @@ struct TestFirstN {
|
|||
const size_t N = Lanes(d);
|
||||
auto mask_lanes = AllocateAligned<T>(N);
|
||||
|
||||
// NOTE: reverse polarity (mask is true iff mask_lanes[i] == 0) because we
|
||||
// cannot reliably compare against all bits set (NaN for float types).
|
||||
const T off = 1;
|
||||
// GCC workaround: we previously used zero to indicate true because we can
|
||||
// safely compare with that value. However, that hits an ICE for u64x1 on
|
||||
// GCC 8.3 but not 8.4, even if the implementation of operator== is
|
||||
// simplified to return zero. Using MaskFromVec avoids this, and requires
|
||||
// FF..FF and 0 constants.
|
||||
T on;
|
||||
memset(&on, 0xFF, sizeof(on));
|
||||
const T off = 0;
|
||||
|
||||
for (size_t len = 0; len <= N; ++len) {
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
mask_lanes[i] = i < len ? T(0) : off;
|
||||
mask_lanes[i] = i < len ? on : off;
|
||||
}
|
||||
const auto mask = Eq(Load(d, mask_lanes.get()), Zero(d));
|
||||
const auto mask_vals = Load(d, mask_lanes.get());
|
||||
const auto mask = MaskFromVec(mask_vals);
|
||||
HWY_ASSERT_MASK_EQ(d, mask, FirstN(d, len));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
6
third_party/highway/hwy/tests/memory_test.cc
vendored
6
third_party/highway/hwy/tests/memory_test.cc
vendored
|
|
@ -12,6 +12,12 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Ensure incompabilities with Windows macros (e.g. #define StoreFence) are
|
||||
// detected. Must come before Highway headers.
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
|
|||
17
third_party/jpeg-xl/.readthedocs.yaml
vendored
Normal file
17
third_party/jpeg-xl/.readthedocs.yaml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
#
|
||||
# readthedocs.io configuration file. See:
|
||||
# https://docs.readthedocs.io/en/stable/config-file/v2.html
|
||||
|
||||
version: 2
|
||||
|
||||
sphinx:
|
||||
configuration: doc/sphinx/conf.py
|
||||
|
||||
python:
|
||||
version: "3.7"
|
||||
install:
|
||||
- requirements: doc/sphinx/requirements.txt
|
||||
9
third_party/jpeg-xl/AUTHORS
vendored
9
third_party/jpeg-xl/AUTHORS
vendored
|
|
@ -16,5 +16,14 @@ Cloudinary Ltd. <*@cloudinary.com>
|
|||
Google LLC <*@google.com>
|
||||
|
||||
# Individuals:
|
||||
Alexander Sago <cagelight@gmail.com>
|
||||
Dirk Lemstra <dirk@lemstra.org>
|
||||
Jon Sneyers <jon@cloudinary.com>
|
||||
Lovell Fuller
|
||||
Marcin Konicki <ahwayakchih@gmail.com>
|
||||
Petr Diblík
|
||||
Pieter Wuille
|
||||
xiota
|
||||
Ziemowit Zabawa <ziemek.zabawa@outlook.com>
|
||||
Andrius Lukas Narbutas <andrius4669@gmail.com>
|
||||
Misaki Kasumi <misakikasumi@outlook.com>
|
||||
|
|
|
|||
157
third_party/jpeg-xl/CHANGELOG.md
vendored
Normal file
157
third_party/jpeg-xl/CHANGELOG.md
vendored
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
# Changelog
|
||||
|
||||
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.6] - Unreleased
|
||||
### Added
|
||||
- API: New functions to decode extra channels:
|
||||
`JxlDecoderExtraChannelBufferSize` and `JxlDecoderSetExtraChannelBuffer`.
|
||||
- API: New function `JxlEncoderInitBasicInfo` to initialize `JxlBasicInfo`
|
||||
(only needed when encoding). NOTE: it is now required to call this function
|
||||
when using the encoder. Padding was added to the struct for forward
|
||||
compatibility.
|
||||
- API: Support for encoding oriented images.
|
||||
- API: FLOAT16 support in the encoder API.
|
||||
- Rewrite of the GDK pixbuf loader plugin. Added proper color management and
|
||||
animation support.
|
||||
- Rewrite of GIMP plugin. Added compression parameters dialog and switched to
|
||||
using the public C API.
|
||||
- Debian packages for GDK pixbuf loader (`libjxl-gdk-pixbuf`) and GIMP
|
||||
(`libjxl-gimp-plugin`) plugins.
|
||||
- `cjxl`/`djxl` support for `stdin` and `stdout`.
|
||||
|
||||
### Changed
|
||||
- API: Renamed the field `alpha_associated` in `JxlExtraChannelInfo` to
|
||||
`alpha_premultiplied`, to match the corresponding name in `JxlBasicInfo`.
|
||||
- Improved the 2x2 downscaling method in the encoder for the optional color
|
||||
channel resampling for low bit rates.
|
||||
- Fixed: the combination of floating point original data, XYB color encoding,
|
||||
and Modular mode was broken (in both encoder and decoder). It now works.
|
||||
NOTE: this can cause the current encoder to write jxl bitstreams that do
|
||||
not decode with the old decoder. In particular this will happen when using
|
||||
cjxl with PFM, EXR, or floating point PSD input, and a combination of XYB
|
||||
and modular mode is used (which caused an encoder error before), e.g.
|
||||
using options like `-m -q 80` (lossy modular), `-d 4.5` or `--progressive_dc=1`
|
||||
(modular DC frame), or default lossy encoding on an image where patches
|
||||
end up being used. There is no problem when using cjxl with PNG, JPEG, GIF,
|
||||
APNG, PPM, PGM, PGX, or integer (8-bit or 16-bit) PSD input.
|
||||
- `libjxl` static library now bundles skcms, fixing static linking in
|
||||
downstream projects when skcms is used.
|
||||
- Spline rendering performance improvements.
|
||||
- Butteraugli changes for less visual masking.
|
||||
|
||||
## [0.5] - 2021-08-02
|
||||
### Added
|
||||
- API: New function to decode the image using a callback outputting a part of a
|
||||
row per call.
|
||||
- API: 16-bit float output support.
|
||||
- API: `JxlDecoderRewind` and `JxlDecoderSkipFrames` functions to skip more
|
||||
efficiently to earlier animation frames.
|
||||
- API: `JxlDecoderSetPreferredColorProfile` function to choose color profile in
|
||||
certain circumstances.
|
||||
- encoder: Adding `center_x` and `center_y` flags for more control of the tile
|
||||
order.
|
||||
- New encoder speeds `lightning` (1) and `thunder` (2).
|
||||
|
||||
### Changed
|
||||
- Re-licensed the project under a BSD 3-Clause license. See the
|
||||
[LICENSE](LICENSE) and [PATENTS](PATENTS) files for details.
|
||||
- Full JPEG XL part 1 specification support: Implemented all the spec required
|
||||
to decode files to pixels, including cases that are not used by the encoder
|
||||
yet. Part 2 of the spec (container format) is final but not fully implemented
|
||||
here.
|
||||
- Butteraugli metric improvements. Exact numbers are different from previous
|
||||
versions.
|
||||
- Memory reductions during decoding.
|
||||
- Reduce the size of the jxl_dec library by removing dependencies.
|
||||
- A few encoding speedups.
|
||||
- Clarify the security policy.
|
||||
- Significant encoding improvements (~5 %) and less ringing.
|
||||
- Butteraugli metric to have some less masking.
|
||||
- `cjxl` flag `--speed` is deprecated and replaced by the `--effort` synonym.
|
||||
|
||||
### Removed
|
||||
- API for returning a downsampled DC was deprecated
|
||||
(`JxlDecoderDCOutBufferSize` and `JxlDecoderSetDCOutBuffer`) and will be
|
||||
removed in the next release.
|
||||
|
||||
## [0.3.7] - 2021-03-29
|
||||
### Changed
|
||||
- Fix a rounding issue in 8-bit decoding.
|
||||
|
||||
## [0.3.6] - 2021-03-25
|
||||
### Changed
|
||||
- Fix a bug that could result in the generation of invalid codestreams as
|
||||
well as failure to decode valid streams.
|
||||
|
||||
## [0.3.5] - 2021-03-23
|
||||
### Added
|
||||
- New encode-time options for faster decoding at the cost of quality.
|
||||
- Man pages for cjxl and djxl.
|
||||
|
||||
### Changed
|
||||
- Memory usage improvements.
|
||||
- Faster decoding to 8-bit output with the C API.
|
||||
- GIMP plugin: avoid the sRGB conversion dialog for sRGB images, do not show
|
||||
a console window on Windows.
|
||||
- Various bug fixes.
|
||||
|
||||
## [0.3.4] - 2021-03-16
|
||||
### Changed
|
||||
- Improved box parsing.
|
||||
- Improved metadata handling.
|
||||
- Performance and memory usage improvements.
|
||||
|
||||
## [0.3.3] - 2021-03-05
|
||||
### Changed
|
||||
- Performance improvements for small images.
|
||||
- Add a (flag-protected) non-high-precision mode with better speed.
|
||||
- Significantly speed up the PQ EOTF.
|
||||
- Allow optional HDR tone mapping in djxl (--tone_map, --display_nits).
|
||||
- Change the behavior of djxl -j to make it consistent with cjxl (#153).
|
||||
- Improve image quality.
|
||||
- Improve EXIF handling.
|
||||
|
||||
## [0.3.2] - 2021-02-12
|
||||
### Changed
|
||||
- Fix embedded ICC encoding regression
|
||||
[#149](https://gitlab.com/wg1/jpeg-xl/-/issues/149).
|
||||
|
||||
## [0.3.1] - 2021-02-10
|
||||
### Changed
|
||||
- New experimental Butteraugli API (`jxl/butteraugli.h`).
|
||||
- Encoder improvements to low quality settings.
|
||||
- Bug fixes, including fuzzer-found potential security bug fixes.
|
||||
- Fixed `-q 100` and `-d 0` not triggering lossless modes.
|
||||
|
||||
## [0.3] - 2021-01-29
|
||||
### Changed
|
||||
- Minor change to the Decoder C API to accommodate future work for other ways
|
||||
to provide input.
|
||||
- Future decoder C API changes will be backwards compatible.
|
||||
- Lots of bug fixes since the previous version.
|
||||
|
||||
## [0.2] - 2020-12-24
|
||||
### Added
|
||||
- JPEG XL bitstream format is frozen. Files encoded with 0.2 will be supported
|
||||
by future versions.
|
||||
|
||||
### Changed
|
||||
- Files encoded with previous versions are not supported.
|
||||
|
||||
## [0.1.1] - 2020-12-01
|
||||
|
||||
## [0.1] - 2020-11-14
|
||||
### Added
|
||||
- Initial release of an encoder (`cjxl`) and decoder (`djxl`) that work
|
||||
together as well as a benchmark tool for comparison with other codecs
|
||||
(`benchmark_xl`).
|
||||
- Note: JPEG XL format is in the final stages of standardization, minor changes
|
||||
to the codestream format are still possible but we are not expecting any
|
||||
changes beyond what is required by bug fixing.
|
||||
- API: new decoder API in C, check the `examples/` directory for its example
|
||||
usage. The C API is a work in progress and likely to change both in API and
|
||||
ABI in future releases.
|
||||
120
third_party/jpeg-xl/CMakeLists.txt
vendored
120
third_party/jpeg-xl/CMakeLists.txt
vendored
|
|
@ -20,7 +20,7 @@ if(POLICY CMP0083)
|
|||
cmake_policy(SET CMP0083 NEW)
|
||||
endif()
|
||||
|
||||
project(JPEGXL LANGUAGES C CXX)
|
||||
project(LIBJXL LANGUAGES C CXX)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
check_cxx_source_compiles(
|
||||
|
|
@ -71,22 +71,31 @@ endif()
|
|||
|
||||
set(WARNINGS_AS_ERRORS_DEFAULT false)
|
||||
|
||||
# Standard cmake naming for building shared libraries.
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries instead of static ones" ON)
|
||||
|
||||
set(JPEGXL_ENABLE_FUZZERS ${ENABLE_FUZZERS_DEFAULT} CACHE BOOL
|
||||
"Build JPEGXL fuzzer targets.")
|
||||
set(JPEGXL_ENABLE_DEVTOOLS false CACHE BOOL
|
||||
"Build JPEGXL developer tools.")
|
||||
set(JPEGXL_ENABLE_TOOLS true CACHE BOOL
|
||||
"Build JPEGXL user tools: cjxl and djxl.")
|
||||
set(JPEGXL_ENABLE_MANPAGES true CACHE BOOL
|
||||
"Build and install man pages for the command-line tools.")
|
||||
set(JPEGXL_ENABLE_BENCHMARK true CACHE BOOL
|
||||
"Build JPEGXL benchmark tools.")
|
||||
set(JPEGXL_ENABLE_EXAMPLES true CACHE BOOL
|
||||
"Build JPEGXL library usage examples.")
|
||||
set(JPEGXL_ENABLE_JNI true CACHE BOOL
|
||||
"Build JPEGXL JNI Java wrapper, if Java dependencies are installed.")
|
||||
set(JPEGXL_ENABLE_SJPEG true CACHE BOOL
|
||||
"Build JPEGXL with support for encoding with sjpeg.")
|
||||
set(JPEGXL_ENABLE_OPENEXR true CACHE BOOL
|
||||
"Build JPEGXL with support for OpenEXR if available.")
|
||||
set(JPEGXL_ENABLE_SKCMS true CACHE BOOL
|
||||
"Build with skcms instead of lcms2.")
|
||||
set(JPEGXL_BUNDLE_SKCMS true CACHE BOOL
|
||||
"When building with skcms, bundle it into libjxl.a.")
|
||||
set(JPEGXL_ENABLE_VIEWERS false CACHE BOOL
|
||||
"Build JPEGXL viewer tools for evaluation.")
|
||||
set(JPEGXL_ENABLE_TCMALLOC ${ENABLE_TCMALLOC_DEFAULT} CACHE BOOL
|
||||
|
|
@ -97,6 +106,10 @@ set(JPEGXL_ENABLE_COVERAGE false CACHE BOOL
|
|||
"Enable code coverage tracking for libjxl. This also enables debug and disables optimizations.")
|
||||
set(JPEGXL_ENABLE_PROFILER false CACHE BOOL
|
||||
"Builds in support for profiling (printed by tools if extra flags given")
|
||||
set(JPEGXL_ENABLE_TRANSCODE_JPEG true CACHE BOOL
|
||||
"Builds in support for decoding transcoded JXL files back to JPEG,\
|
||||
disabling it makes the decoder reject JXL_DEC_JPEG_RECONSTRUCTION events,\
|
||||
(default enabled)")
|
||||
set(JPEGXL_STATIC false CACHE BOOL
|
||||
"Build tools as static binaries.")
|
||||
set(JPEGXL_WARNINGS_AS_ERRORS ${WARNINGS_AS_ERRORS_DEFAULT} CACHE BOOL
|
||||
|
|
@ -146,8 +159,20 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||
if(JPEGXL_STATIC)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||
set(BUILD_SHARED_LIBS 0)
|
||||
set(CMAKE_EXE_LINKER_FLAGS
|
||||
"${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
|
||||
# Clang developers say that in case to use "static" we have to build stdlib
|
||||
# ourselves; for real use case we don't care about stdlib, as it is "granted",
|
||||
# so just linking all other libraries is fine.
|
||||
if (NOT APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS
|
||||
"${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
|
||||
endif()
|
||||
endif() # JPEGXL_STATIC
|
||||
|
||||
# Threads
|
||||
set(THREADS_PREFER_PTHREAD_FLAG YES)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if(JPEGXL_STATIC)
|
||||
if (MINGW)
|
||||
# In MINGW libstdc++ uses pthreads directly. When building statically a
|
||||
# program (regardless of whether the source code uses pthread or not) the
|
||||
|
|
@ -163,9 +188,22 @@ if(JPEGXL_STATIC)
|
|||
# will be discarded anyway.
|
||||
# This adds these flags as dependencies for *all* targets. Adding this to
|
||||
# CMAKE_EXE_LINKER_FLAGS instead would cause them to be included before any
|
||||
# object files and therefore discarded.
|
||||
# object files and therefore discarded. This should be set in the
|
||||
# INTERFACE_LINK_LIBRARIES of Threads::Threads but some third_part targets
|
||||
# don't depend on it.
|
||||
link_libraries(-Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic)
|
||||
endif() # MINGW
|
||||
elseif(CMAKE_USE_PTHREADS_INIT)
|
||||
# "whole-archive" is not supported on OSX.
|
||||
if (NOT APPLE)
|
||||
# Set pthreads as a whole-archive, otherwise weak symbols in the static
|
||||
# libraries will discard pthreads symbols leading to segmentation fault at
|
||||
# runtime.
|
||||
message(STATUS "Using -lpthread as --whole-archive")
|
||||
set_target_properties(Threads::Threads PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES
|
||||
"-Wl,--whole-archive;-lpthread;-Wl,--no-whole-archive")
|
||||
endif()
|
||||
endif()
|
||||
endif() # JPEGXL_STATIC
|
||||
|
||||
if (MSVC)
|
||||
|
|
@ -245,9 +283,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
|||
|
||||
add_subdirectory(third_party)
|
||||
|
||||
set(THREADS_PREFER_PTHREAD_FLAG YES)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# Copy the JXL license file to the output build directory.
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/LICENSE"
|
||||
${PROJECT_BINARY_DIR}/LICENSE.jpeg-xl COPYONLY)
|
||||
|
|
@ -273,15 +308,37 @@ endif() # BUILD_TESTING
|
|||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
set(DOXYGEN_GENERATE_HTML "YES")
|
||||
set(DOXYGEN_GENERATE_XML "NO")
|
||||
set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||
set(DOXYGEN_GENERATE_XML "YES")
|
||||
set(DOXYGEN_STRIP_FROM_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/include")
|
||||
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE "README.md")
|
||||
set(DOXYGEN_WARN_AS_ERROR "YES")
|
||||
set(DOXYGEN_QUIET "YES")
|
||||
doxygen_add_docs(doc
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/include/jxl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/lib/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/doc/api.txt"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
COMMENT "Generating C API documentation")
|
||||
|
||||
# Add sphinx doc build step for readthedocs.io (requires doxygen too).
|
||||
find_program(SPHINX_BUILD_PROGRAM sphinx-build)
|
||||
if(SPHINX_BUILD_PROGRAM)
|
||||
add_custom_command(
|
||||
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/rtd/nonexistent"
|
||||
COMMENT "Generating readthedocs.io output on ${CMAKE_CURRENT_BINARY_DIR}/rtd"
|
||||
COMMAND ${SPHINX_BUILD_PROGRAM} -q -W -b html -j auto
|
||||
${CMAKE_SOURCE_DIR}/doc/sphinx
|
||||
${CMAKE_CURRENT_BINARY_DIR}/rtd
|
||||
DEPENDS doc
|
||||
)
|
||||
# This command runs the documentation generation every time since the output
|
||||
# target file doesn't exist.
|
||||
add_custom_target(rtd-html
|
||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/rtd/nonexistent
|
||||
)
|
||||
else() # SPHINX_BUILD_PROGRAM\
|
||||
message(WARNING "sphinx-build not found, skipping rtd documentation")
|
||||
endif() # SPHINX_BUILD_PROGRAM
|
||||
|
||||
else()
|
||||
# Create a "doc" target for compatibility since "doc" is not otherwise added to
|
||||
# the build when doxygen is not installed.
|
||||
|
|
@ -290,13 +347,31 @@ add_custom_target(doc false
|
|||
endif() # DOXYGEN_FOUND
|
||||
|
||||
if(JPEGXL_ENABLE_MANPAGES)
|
||||
find_package(Python COMPONENTS Interpreter)
|
||||
if(Python_Interpreter_FOUND)
|
||||
find_program(ASCIIDOC a2x)
|
||||
endif()
|
||||
if(NOT Python_Interpreter_FOUND OR "${ASCIIDOC}" STREQUAL "ASCIIDOC-NOTFOUND")
|
||||
message(WARNING "asciidoc was not found, the man pages will not be installed.")
|
||||
find_program(ASCIIDOC a2x)
|
||||
if(NOT "${ASCIIDOC}" STREQUAL "ASCIIDOC-NOTFOUND")
|
||||
file(STRINGS "${ASCIIDOC}" ASCIIDOC_SHEBANG LIMIT_COUNT 1)
|
||||
if(ASCIIDOC_SHEBANG MATCHES "python2")
|
||||
find_package(Python2 COMPONENTS Interpreter)
|
||||
set(ASCIIDOC_PY_FOUND "${Python2_Interpreter_FOUND}")
|
||||
set(ASCIIDOC_PY Python2::Interpreter)
|
||||
elseif(ASCIIDOC_SHEBANG MATCHES "python3")
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
set(ASCIIDOC_PY_FOUND "${Python3_Interpreter_FOUND}")
|
||||
set(ASCIIDOC_PY Python3::Interpreter)
|
||||
else()
|
||||
find_package(Python COMPONENTS Interpreter QUIET)
|
||||
if(NOT Python_Interpreter_FOUND)
|
||||
find_program(ASCIIDOC_PY python)
|
||||
if(NOT ASCIIDOC_PY STREQUAL "ASCIIDOC_PY-NOTFOUND")
|
||||
set(ASCIIDOC_PY_FOUND ON)
|
||||
endif()
|
||||
else()
|
||||
set(ASCIIDOC_PY_FOUND "${Python_Interpreter_FOUND}")
|
||||
set(ASCIIDOC_PY Python::Interpreter)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ASCIIDOC_PY_FOUND)
|
||||
set(MANPAGE_FILES "")
|
||||
set(MANPAGES "")
|
||||
foreach(PAGE IN ITEMS cjxl djxl)
|
||||
|
|
@ -305,7 +380,7 @@ else()
|
|||
# does not recognize it.
|
||||
add_custom_command(
|
||||
OUTPUT "${PAGE}.1"
|
||||
COMMAND Python::Interpreter
|
||||
COMMAND "${ASCIIDOC_PY}"
|
||||
ARGS "${ASCIIDOC}"
|
||||
--format manpage --destination-dir="${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/doc/man/${PAGE}.txt"
|
||||
|
|
@ -315,12 +390,15 @@ else()
|
|||
endforeach()
|
||||
add_custom_target(manpages ALL DEPENDS ${MANPAGES})
|
||||
install(FILES ${MANPAGE_FILES} DESTINATION share/man/man1)
|
||||
endif()
|
||||
endif()
|
||||
endif() # ASCIIDOC_PY_FOUND
|
||||
else()
|
||||
message(WARNING "asciidoc was not found, the man pages will not be installed.")
|
||||
endif() # ASCIIDOC != "ASCIIDOC-NOTFOUND"
|
||||
endif() # JPEGXL_ENABLE_MANPAGES
|
||||
|
||||
# Example usage code.
|
||||
if (${JPEGXL_ENABLE_EXAMPLES})
|
||||
add_subdirectory(examples)
|
||||
include(examples/examples.cmake)
|
||||
endif ()
|
||||
|
||||
# Plugins for third-party software
|
||||
|
|
|
|||
17
third_party/jpeg-xl/CONTRIBUTING.md
vendored
17
third_party/jpeg-xl/CONTRIBUTING.md
vendored
|
|
@ -42,6 +42,19 @@ to accept your pull requests.
|
|||
***NOTE***: Only original source code from you and other people that have signed
|
||||
the CLA can be accepted into the main repository.
|
||||
|
||||
### License
|
||||
|
||||
Contributions are licensed under the project's [LICENSE](LICENSE). Each new
|
||||
file must include the following header when possible, with comment style adapted
|
||||
to the language as needed:
|
||||
|
||||
```
|
||||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
```
|
||||
|
||||
### Code Reviews
|
||||
|
||||
All submissions, including submissions by project members, require review. We
|
||||
|
|
@ -92,6 +105,10 @@ information on using pull requests.
|
|||
Request to see the changes between versions. We use "Rebase and merge" policy
|
||||
to keep a linear git history which is easier to reason about.
|
||||
|
||||
* Your change must pass the build and test workflows. There's a `ci.sh` script
|
||||
to help building and testing these configurations. See [building and
|
||||
testing](doc/building_and_testing.md) for more details.
|
||||
|
||||
### Contributing checklist.
|
||||
|
||||
* Sign the CLA (only needed once per user, see above).
|
||||
|
|
|
|||
2
third_party/jpeg-xl/README.Haiku.md
vendored
2
third_party/jpeg-xl/README.Haiku.md
vendored
|
|
@ -10,7 +10,7 @@ instructions see "[README](README.md)" and
|
|||
## Dependencies
|
||||
|
||||
```shell
|
||||
pkgman install llvm9_clang ninja cmake doxygen libjpeg_turbo_devel
|
||||
pkgman install llvm9_clang ninja cmake doxygen libjpeg_turbo_devel giflib_devel
|
||||
```
|
||||
|
||||
## Building
|
||||
|
|
|
|||
134
third_party/jpeg-xl/README.md
vendored
134
third_party/jpeg-xl/README.md
vendored
|
|
@ -1,14 +1,24 @@
|
|||
# JPEG XL reference implementation
|
||||
|
||||
[](
|
||||
https://github.com/libjxl/libjxl/actions/workflows/build_test.yml)
|
||||
[](
|
||||
https://github.com/libjxl/libjxl/actions/workflows/release.yaml)
|
||||
[](
|
||||
https://libjxl.readthedocs.io/en/latest/?badge=latest)
|
||||
[](
|
||||
https://codecov.io/gh/libjxl/libjxl)
|
||||
|
||||
<img src="doc/jxl.svg" width="100" align="right" alt="JXL logo">
|
||||
|
||||
This repository contains a reference implementation of JPEG XL (encoder and
|
||||
decoder), called `libjxl`.
|
||||
decoder), called `libjxl`. This software library is
|
||||
[used by many applications that support JPEG XL](doc/software_support.md).
|
||||
|
||||
JPEG XL is in the final stages of standardization and its codestream format is
|
||||
frozen.
|
||||
JPEG XL is in the final stages of standardization and its codestream and file format
|
||||
are frozen.
|
||||
|
||||
The libraries API, command line options and tools in this repository are subject
|
||||
The library API, command line options, and tools in this repository are subject
|
||||
to change, however files encoded with `cjxl` conform to the JPEG XL format
|
||||
specification and can be decoded with current and future `djxl` decoders or
|
||||
`libjxl` decoding library.
|
||||
|
|
@ -20,13 +30,16 @@ For more details and other workflows see the "Advanced guide" below.
|
|||
### Checking out the code
|
||||
|
||||
```bash
|
||||
git clone https://gitlab.com/wg1/jpeg-xl.git --recursive
|
||||
git clone https://github.com/libjxl/libjxl.git --recursive
|
||||
```
|
||||
|
||||
This repository uses git submodules to handle some third party dependencies
|
||||
under `third_party/`, that's why is important to pass `--recursive`. If you
|
||||
under `third_party`, that's why is important to pass `--recursive`. If you
|
||||
didn't check out with `--recursive`, or any submodule has changed, run:
|
||||
`git submodule update --init --recursive`.
|
||||
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
Important: If you downloaded a zip file or tarball from the web interface you
|
||||
won't get the needed submodules and the code will not compile. You can download
|
||||
|
|
@ -50,17 +63,17 @@ sudo apt install libgif-dev libjpeg-dev libopenexr-dev libpng-dev libwebp-dev
|
|||
```
|
||||
|
||||
We recommend using a recent Clang compiler (version 7 or newer), for that
|
||||
install clang and set `CC` and `CXX` variables. For example, with clang-7:
|
||||
install clang and set `CC` and `CXX` variables.
|
||||
|
||||
```bash
|
||||
sudo apt install clang-7
|
||||
export CC=clang-7 CXX=clang++-7
|
||||
sudo apt install clang
|
||||
export CC=clang CXX=clang++
|
||||
```
|
||||
|
||||
### Building
|
||||
|
||||
```bash
|
||||
cd jpeg-xl
|
||||
cd libjxl
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF ..
|
||||
|
|
@ -102,8 +115,8 @@ For speed benchmarks on single images in single or multi-threaded decoding
|
|||
on the decoding options and note that the output image is optional for
|
||||
benchmarking purposes.
|
||||
|
||||
For a more comprehensive comparison of compression density between multiple
|
||||
options see "Benchmarking with benchmark_xl" section below.
|
||||
For more comprehensive benchmarking options, see the
|
||||
[benchmarking guide](doc/benchmarking.md).
|
||||
|
||||
## Advanced guide
|
||||
|
||||
|
|
@ -112,85 +125,19 @@ options see "Benchmarking with benchmark_xl" section below.
|
|||
We build a common environment based on Debian/Ubuntu using Docker. Other
|
||||
systems may have different combinations of versions and dependencies that
|
||||
have not been tested and may not work. For those cases we recommend using the
|
||||
Docker environment as explained in the
|
||||
Docker container as explained in the
|
||||
[step by step guide](doc/developing_in_docker.md).
|
||||
|
||||
### Building JPEG XL for developers
|
||||
|
||||
For experienced developers, we also provide build instructions for an [up to
|
||||
date Debian-based Linux](doc/developing_in_debian.md) and [64-bit
|
||||
Windows](doc/developing_in_windows.md). If you encounter any difficulties,
|
||||
please use Docker instead.
|
||||
For experienced developers, we provide build instructions for several other environments:
|
||||
|
||||
## Benchmarking with benchmark_xl
|
||||
* [Building on Debian](doc/developing_in_debian.md)
|
||||
* Building on Windows with [vcpkg](doc/developing_in_windows_vcpkg.md) (Visual Studio 2019)
|
||||
* Building on Windows with [MSYS2](doc/developing_in_windows_msys.md)
|
||||
* [Cross Compiling for Windows with Crossroad](doc/developing_with_crossroad.md)
|
||||
|
||||
We recommend `build/tools/benchmark_xl` as a convenient method for reading
|
||||
images or image sequences, encoding them using various codecs (jpeg jxl png
|
||||
webp), decoding the result, and computing objective quality metrics. An example
|
||||
invocation is:
|
||||
|
||||
```bash
|
||||
build/tools/benchmark_xl --input "/path/*.png" --codec jxl:wombat:d1,jxl:cheetah:d2
|
||||
```
|
||||
|
||||
Multiple comma-separated codecs are allowed. The characters after : are
|
||||
parameters for the codec, separated by colons, in this case specifying maximum
|
||||
target psychovisual distances of 1 and 2 (higher implies lower quality) and
|
||||
the encoder effort (see below). Other common parameters are `r0.5` (target
|
||||
bitrate 0.5 bits per pixel) and `q92` (quality 92, on a scale of 0-100, where
|
||||
higher is better). The `jxl` codec supports the following additional parameters:
|
||||
|
||||
Speed: `falcon`, `cheetah`, `hare`, `wombat`, `squirrel`, `kitten`, `tortoise`
|
||||
control the encoder effort in ascending order. This also affects memory usage:
|
||||
using lower effort will typically reduce memory consumption during encoding.
|
||||
|
||||
* `falcon` disables all of the following tools.
|
||||
* `cheetah` enables coefficient reordering, context clustering, and heuristics
|
||||
for selecting DCT sizes and quantization steps.
|
||||
* `hare` enables Gaborish filtering, chroma from luma, and an initial estimate
|
||||
of quantization steps.
|
||||
* `wombat` enables error diffusion quantization and full DCT size selection
|
||||
heuristics.
|
||||
* `squirrel` (default) enables dots, patches, and spline detection, and full
|
||||
context clustering.
|
||||
* `kitten` optimizes the adaptive quantization for a psychovisual metric.
|
||||
* `tortoise` enables a more thorough adaptive quantization search.
|
||||
|
||||
Mode: JPEG XL has two modes. The default is Var-DCT mode, which is suitable for
|
||||
lossy compression. The other mode is Modular mode, which is suitable for lossless
|
||||
compression. Modular mode can also do lossy compression (e.g. `jxl:m:q50`).
|
||||
|
||||
* `m` activates modular mode.
|
||||
|
||||
Other arguments to benchmark_xl include:
|
||||
|
||||
* `--save_compressed`: save codestreams to `output_dir`.
|
||||
* `--save_decompressed`: save decompressed outputs to `output_dir`.
|
||||
* `--output_extension`: selects the format used to output decoded images.
|
||||
* `--num_threads`: number of codec instances that will independently
|
||||
encode/decode images, or 0.
|
||||
* `--inner_threads`: how many threads each instance should use for parallel
|
||||
encoding/decoding, or 0.
|
||||
* `--encode_reps`/`--decode_reps`: how many times to repeat encoding/decoding
|
||||
each image, for more consistent measurements (we recommend 10).
|
||||
|
||||
The benchmark output begins with a header:
|
||||
|
||||
```
|
||||
Compr Input Compr Compr Compr Decomp Butteraugli
|
||||
Method Pixels Size BPP # MP/s MP/s Distance Error p norm BPP*pnorm Errors
|
||||
```
|
||||
|
||||
`ComprMethod` lists each each comma-separated codec. `InputPixels` is the number
|
||||
of pixels in the input image. `ComprSize` is the codestream size in bytes and
|
||||
`ComprBPP` the bitrate. `Compr MP/s` and `Decomp MP/s` are the
|
||||
compress/decompress throughput, in units of Megapixels/second.
|
||||
`Butteraugli Distance` indicates the maximum psychovisual error in the decoded
|
||||
image (larger is worse). `Error p norm` is a similar summary of the psychovisual
|
||||
error, but closer to an average, giving less weight to small low-quality
|
||||
regions. `BPP*pnorm` is the product of `ComprBPP` and `Error p norm`, which is a
|
||||
figure of merit for the codec (lower is better). `Errors` is nonzero if errors
|
||||
occurred while loading or encoding/decoding the image.
|
||||
If you encounter any difficulties, please use Docker instead.
|
||||
|
||||
## License
|
||||
|
||||
|
|
@ -207,19 +154,22 @@ format: Cloudinary and Google.
|
|||
|
||||
### Codec description
|
||||
|
||||
* [JPEG XL Format Overview](doc/format_overview.md)
|
||||
* [Introductory paper](https://www.spiedigitallibrary.org/proceedings/Download?fullDOI=10.1117%2F12.2529237) (open-access)
|
||||
* [XL Overview](doc/xl_overview.md) - a brief introduction to the source code modules
|
||||
* [JPEG XL white paper](http://ds.jpeg.org/whitepapers/jpeg-xl-whitepaper.pdf)
|
||||
* [JPEG XL website](https://jpeg.org/jpegxl/)
|
||||
* [Jon's JXL info page](https://sneyers.info/jxl/)
|
||||
* [JPEG XL official website](https://jpeg.org/jpegxl)
|
||||
* [JPEG XL community website](https://jpegxl.info)
|
||||
|
||||
### Development process
|
||||
* [Docker setup - **start here**](doc/developing_in_docker.md)
|
||||
* [Building on Debian](doc/developing_in_debian.md) - for experts only
|
||||
* [Building on Windows](doc/developing_in_windows.md) - for experts only
|
||||
|
||||
* [More information on testing/build options](doc/building_and_testing.md)
|
||||
* [Git guide for JPEG XL](doc/developing_in_github.md) - for developers only
|
||||
* [Git guide for JPEG XL](doc/developing_in_github.md) - for developers
|
||||
* [Fuzzing](doc/fuzzing.md) - for developers
|
||||
* [Building Web Assembly artifacts](doc/building_wasm.md)
|
||||
* [Test coverage on Codecov.io](https://app.codecov.io/gh/libjxl/libjxl) - for
|
||||
developers
|
||||
* [libjxl documentation on readthedocs.io](https://libjxl.readthedocs.io/)
|
||||
|
||||
### Contact
|
||||
|
||||
|
|
|
|||
26
third_party/jpeg-xl/bash_test.sh
vendored
Executable file → Normal file
26
third_party/jpeg-xl/bash_test.sh
vendored
Executable file → Normal file
|
|
@ -65,7 +65,7 @@ test_copyright() {
|
|||
local f
|
||||
for f in $(
|
||||
git ls-files | grep -E \
|
||||
'(Dockerfile.*|\.c|\.cc|\.cpp|\.gni|\.h|\.java|\.sh|\.m|\.py|\.ui)$'); do
|
||||
'(Dockerfile.*|\.c|\.cc|\.cpp|\.gni|\.h|\.java|\.sh|\.m|\.py|\.ui|\.yml)$'); do
|
||||
if [[ "${f#third_party/}" == "$f" ]]; then
|
||||
# $f is not in third_party/
|
||||
if ! head -n 10 "$f" |
|
||||
|
|
@ -173,6 +173,15 @@ test_deps_version() {
|
|||
cat >&2 <<EOF
|
||||
deps.sh: SHA for project ${line} is at ${deps_sha} but the git submodule is at
|
||||
${git_sha}. Please update deps.sh
|
||||
|
||||
If you did not intend to change the submodule's SHA value, it is possible that
|
||||
you accidentally included this change in your commit after a rebase or checkout
|
||||
without running "git submodule --init". To revert the submodule change run from
|
||||
the top checkout directory:
|
||||
|
||||
git -C ${line} checkout ${deps_sha}
|
||||
git commit --amend ${line}
|
||||
|
||||
EOF
|
||||
return 1
|
||||
fi
|
||||
|
|
@ -199,6 +208,21 @@ EOF
|
|||
return $ret
|
||||
}
|
||||
|
||||
# Test that we don't use %n in C++ code to avoid using it in printf and scanf.
|
||||
# This test is not very precise but in cases where "module n" is needed we would
|
||||
# normally have "% n" instead of "%n". Using %n is not allowed in Android 10+.
|
||||
test_percent_n() {
|
||||
local ret=0
|
||||
local f
|
||||
for f in $(git ls-files | grep -E '(\.cc|\.cpp|\.h)$'); do
|
||||
if grep -i -H -n -E '%h*n' "$f" >&2; then
|
||||
echo "Don't use \"%n\"." >&2
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
return ${ret}
|
||||
}
|
||||
|
||||
main() {
|
||||
local ret=0
|
||||
cd "${MYDIR}"
|
||||
|
|
|
|||
198
third_party/jpeg-xl/ci.sh
vendored
Executable file → Normal file
198
third_party/jpeg-xl/ci.sh
vendored
Executable file → Normal file
|
|
@ -89,7 +89,7 @@ if [[ ! -z "${HWY_BASELINE_TARGETS}" ]]; then
|
|||
fi
|
||||
|
||||
# Version inferred from the CI variables.
|
||||
CI_COMMIT_SHA=${CI_COMMIT_SHA:-}
|
||||
CI_COMMIT_SHA=${CI_COMMIT_SHA:-${GITHUB_SHA:-}}
|
||||
JPEGXL_VERSION=${JPEGXL_VERSION:-${CI_COMMIT_SHA:0:8}}
|
||||
|
||||
# Benchmark parameters
|
||||
|
|
@ -226,8 +226,13 @@ merge_request_commits() {
|
|||
{ set +x; } 2>/dev/null
|
||||
# GITHUB_SHA is the current reference being build in GitHub Actions.
|
||||
if [[ -n "${GITHUB_SHA:-}" ]]; then
|
||||
git -C "${MYDIR}" fetch -q origin "${GITHUB_SHA}"
|
||||
MR_HEAD_SHA="${GITHUB_SHA}"
|
||||
# GitHub normally does a checkout of a merge commit on a shallow repository
|
||||
# by default. We want to get a bit more of the history to be able to diff
|
||||
# changes on the Pull Request if needed. This fetches 10 more commits which
|
||||
# should be enough given that PR normally should have 1 commit.
|
||||
git -C "${MYDIR}" fetch -q origin "${GITHUB_SHA}" --depth 10
|
||||
MR_HEAD_SHA="$(git rev-parse "FETCH_HEAD^2" 2>/dev/null ||
|
||||
echo "${GITHUB_SHA}")"
|
||||
else
|
||||
# CI_BUILD_REF is the reference currently being build in the CI workflow.
|
||||
MR_HEAD_SHA=$(git -C "${MYDIR}" rev-parse -q "${CI_BUILD_REF:-HEAD}")
|
||||
|
|
@ -355,6 +360,8 @@ cmake_configure() {
|
|||
-DJPEGXL_ENABLE_VIEWERS=ON
|
||||
-DJPEGXL_ENABLE_PLUGINS=ON
|
||||
-DJPEGXL_ENABLE_DEVTOOLS=ON
|
||||
# We always use libfuzzer in the ci.sh wrapper.
|
||||
-DJPEGXL_FUZZER_LINK_FLAGS="-fsanitize=fuzzer"
|
||||
)
|
||||
if [[ "${BUILD_TARGET}" != *mingw32 ]]; then
|
||||
args+=(
|
||||
|
|
@ -544,10 +551,12 @@ cmd_coverage_report() {
|
|||
local gcovr_args=(
|
||||
-r "${real_build_dir}"
|
||||
--gcov-executable "${LLVM_COV} gcov"
|
||||
# Only print coverage information for the jxl and fuif directories. The rest
|
||||
# Only print coverage information for the libjxl directories. The rest
|
||||
# is not part of the code under test.
|
||||
--filter '.*jxl/.*'
|
||||
--exclude '.*_test.cc'
|
||||
--exclude '.*_test-only..*'
|
||||
--exclude '.*test_utils..*'
|
||||
--object-directory "${real_build_dir}"
|
||||
)
|
||||
|
||||
|
|
@ -587,6 +596,27 @@ cmd_gbench() {
|
|||
)
|
||||
}
|
||||
|
||||
cmd_asanfuzz() {
|
||||
CMAKE_CXX_FLAGS+=" -fsanitize=fuzzer-no-link"
|
||||
CMAKE_C_FLAGS+=" -fsanitize=fuzzer-no-link"
|
||||
cmd_asan -DJPEGXL_ENABLE_FUZZERS=ON "$@"
|
||||
}
|
||||
|
||||
cmd_msanfuzz() {
|
||||
# Install msan if needed before changing the flags.
|
||||
detect_clang_version
|
||||
local msan_prefix="${HOME}/.msan/${CLANG_VERSION}"
|
||||
if [[ ! -d "${msan_prefix}" || -e "${msan_prefix}/lib/libc++abi.a" ]]; then
|
||||
# Install msan libraries for this version if needed or if an older version
|
||||
# with libc++abi was installed.
|
||||
cmd_msan_install
|
||||
fi
|
||||
|
||||
CMAKE_CXX_FLAGS+=" -fsanitize=fuzzer-no-link"
|
||||
CMAKE_C_FLAGS+=" -fsanitize=fuzzer-no-link"
|
||||
cmd_msan -DJPEGXL_ENABLE_FUZZERS=ON "$@"
|
||||
}
|
||||
|
||||
cmd_asan() {
|
||||
SANITIZER="asan"
|
||||
CMAKE_C_FLAGS+=" -DJXL_ENABLE_ASSERT=1 -g -DADDRESS_SANITIZER \
|
||||
|
|
@ -722,6 +752,75 @@ cmd_msan_install() {
|
|||
done
|
||||
}
|
||||
|
||||
# Internal build step shared between all cmd_ossfuzz_* commands.
|
||||
_cmd_ossfuzz() {
|
||||
local sanitizer="$1"
|
||||
shift
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
local real_build_dir=$(realpath "${BUILD_DIR}")
|
||||
|
||||
# oss-fuzz defines three directories:
|
||||
# * /work, with the working directory to do re-builds
|
||||
# * /src, with the source code to build
|
||||
# * /out, with the output directory where to copy over the built files.
|
||||
# We use $BUILD_DIR as the /work and the script directory as the /src. The
|
||||
# /out directory is ignored as developers are used to look for the fuzzers in
|
||||
# $BUILD_DIR/tools/ directly.
|
||||
|
||||
if [[ "${sanitizer}" = "memory" && ! -d "${BUILD_DIR}/msan" ]]; then
|
||||
sudo docker run --rm -i \
|
||||
--user $(id -u):$(id -g) \
|
||||
-v "${real_build_dir}":/work \
|
||||
gcr.io/oss-fuzz-base/msan-libs-builder \
|
||||
bash -c "cp -r /msan /work"
|
||||
fi
|
||||
|
||||
# Args passed to ninja. These will be evaluated as a string separated by
|
||||
# spaces.
|
||||
local jpegxl_extra_args="$@"
|
||||
|
||||
sudo docker run --rm -i \
|
||||
-e JPEGXL_UID=$(id -u) \
|
||||
-e JPEGXL_GID=$(id -g) \
|
||||
-e FUZZING_ENGINE="${FUZZING_ENGINE:-libfuzzer}" \
|
||||
-e SANITIZER="${sanitizer}" \
|
||||
-e ARCHITECTURE=x86_64 \
|
||||
-e FUZZING_LANGUAGE=c++ \
|
||||
-e MSAN_LIBS_PATH="/work/msan" \
|
||||
-e JPEGXL_EXTRA_ARGS="${jpegxl_extra_args}" \
|
||||
-v "${MYDIR}":/src/libjxl \
|
||||
-v "${MYDIR}/tools/ossfuzz-build.sh":/src/build.sh \
|
||||
-v "${real_build_dir}":/work \
|
||||
gcr.io/oss-fuzz/libjxl
|
||||
}
|
||||
|
||||
cmd_ossfuzz_asan() {
|
||||
_cmd_ossfuzz address "$@"
|
||||
}
|
||||
cmd_ossfuzz_msan() {
|
||||
_cmd_ossfuzz memory "$@"
|
||||
}
|
||||
cmd_ossfuzz_ubsan() {
|
||||
_cmd_ossfuzz undefined "$@"
|
||||
}
|
||||
|
||||
cmd_ossfuzz_ninja() {
|
||||
[[ -e "${BUILD_DIR}/build.ninja" ]]
|
||||
local real_build_dir=$(realpath "${BUILD_DIR}")
|
||||
|
||||
if [[ -e "${BUILD_DIR}/msan" ]]; then
|
||||
echo "ossfuzz_ninja doesn't work with msan builds. Use ossfuzz_msan." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sudo docker run --rm -i \
|
||||
--user $(id -u):$(id -g) \
|
||||
-v "${MYDIR}":/src/libjxl \
|
||||
-v "${real_build_dir}":/work \
|
||||
gcr.io/oss-fuzz/libjxl \
|
||||
ninja -C /work "$@"
|
||||
}
|
||||
|
||||
cmd_fast_benchmark() {
|
||||
local small_corpus_tar="${BENCHMARK_CORPORA}/jyrki-full.tar"
|
||||
mkdir -p "${BENCHMARK_CORPORA}"
|
||||
|
|
@ -802,7 +901,7 @@ run_benchmark() {
|
|||
|
||||
local benchmark_args=(
|
||||
--input "${src_img_dir}/*.png"
|
||||
--codec=jpeg:yuv420:q85,webp:q80,jxl:fast:d1,jxl:fast:d1:downsampling=8,jxl:fast:d4,jxl:fast:d4:downsampling=8,jxl:m:cheetah:nl,jxl:cheetah:m,jxl:m:cheetah:P6,jxl:m:falcon:q80
|
||||
--codec=jpeg:yuv420:q85,webp:q80,jxl:fast:d1,jxl:fast:d1:downsampling=8,jxl:fast:d4,jxl:fast:d4:downsampling=8,jxl:cheetah:m,jxl:m:cheetah:P6,jxl:m:falcon:q80
|
||||
--output_dir "${output_dir}"
|
||||
--noprofiler --show_progress
|
||||
--num_threads="${num_threads}"
|
||||
|
|
@ -833,7 +932,7 @@ $(cat "${output_dir}/results.txt")
|
|||
# Helper function to wait for the CPU temperature to cool down on ARM.
|
||||
wait_for_temp() {
|
||||
{ set +x; } 2>/dev/null
|
||||
local temp_limit=${1:-37000}
|
||||
local temp_limit=${1:-38000}
|
||||
if [[ -z "${THERMAL_FILE:-}" ]]; then
|
||||
echo "Must define the THERMAL_FILE with the thermal_zoneX/temp file" \
|
||||
"to read the temperature from. This is normally set in the runner." >&2
|
||||
|
|
@ -844,9 +943,15 @@ wait_for_temp() {
|
|||
echo -n "Waiting for temp to get down from ${org_temp}... "
|
||||
fi
|
||||
local temp="${org_temp}"
|
||||
local secs=0
|
||||
while [[ "${temp}" -ge "${temp_limit}" ]]; do
|
||||
sleep 1
|
||||
temp=$(cat "${THERMAL_FILE}")
|
||||
echo -n "${temp} "
|
||||
secs=$((secs + 1))
|
||||
if [[ ${secs} -ge 5 ]]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [[ "${org_temp}" -ge "${temp_limit}" ]]; then
|
||||
echo "Done, temp=${temp}"
|
||||
|
|
@ -901,7 +1006,6 @@ cmd_arm_benchmark() {
|
|||
"--modular --responsive=1"
|
||||
# Near-lossless options:
|
||||
"--epf=0 --distance=0.3 --speed=fast"
|
||||
"--modular -N 3 -I 0"
|
||||
"--modular -Q 97"
|
||||
)
|
||||
|
||||
|
|
@ -1085,7 +1189,7 @@ cmd_fuzz() {
|
|||
cmd_lint() {
|
||||
merge_request_commits
|
||||
{ set +x; } 2>/dev/null
|
||||
local versions=(${1:-6.0 7 8 9})
|
||||
local versions=(${1:-6.0 7 8 9 10 11})
|
||||
local clang_format_bins=("${versions[@]/#/clang-format-}" clang-format)
|
||||
local tmpdir=$(mktemp -d)
|
||||
CLEANUP_FILES+=("${tmpdir}")
|
||||
|
|
@ -1108,7 +1212,7 @@ cmd_lint() {
|
|||
fi
|
||||
installed+=("${clang_format}")
|
||||
local tmppatch="${tmpdir}/${clang_format}.patch"
|
||||
# We include in this linter all the changes including the uncommited changes
|
||||
# We include in this linter all the changes including the uncommitted changes
|
||||
# to avoid printing changes already applied.
|
||||
set -x
|
||||
git -C "${MYDIR}" "${clang_format}" --binary "${clang_format}" \
|
||||
|
|
@ -1258,6 +1362,70 @@ cmd_debian_build() {
|
|||
esac
|
||||
}
|
||||
|
||||
get_version() {
|
||||
local varname=$1
|
||||
local line=$(grep -F "set(${varname} " lib/CMakeLists.txt | head -n 1)
|
||||
[[ -n "${line}" ]]
|
||||
line="${line#set(${varname} }"
|
||||
line="${line%)}"
|
||||
echo "${line}"
|
||||
}
|
||||
|
||||
cmd_bump_version() {
|
||||
local newver="${1:-}"
|
||||
|
||||
if ! which dch >/dev/null; then
|
||||
echo "Run:\n sudo apt install debhelper"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${newver}" ]]; then
|
||||
local major=$(get_version JPEGXL_MAJOR_VERSION)
|
||||
local minor=$(get_version JPEGXL_MINOR_VERSION)
|
||||
local patch=0
|
||||
minor=$(( ${minor} + 1))
|
||||
else
|
||||
local major="${newver%%.*}"
|
||||
newver="${newver#*.}"
|
||||
local minor="${newver%%.*}"
|
||||
newver="${newver#${minor}}"
|
||||
local patch="${newver#.}"
|
||||
if [[ -z "${patch}" ]]; then
|
||||
patch=0
|
||||
fi
|
||||
fi
|
||||
|
||||
newver="${major}.${minor}"
|
||||
if [[ "${patch}" != "0" ]]; then
|
||||
newver="${newver}.${patch}"
|
||||
fi
|
||||
echo "Bumping version to ${newver} (${major}.${minor}.${patch})"
|
||||
sed -E \
|
||||
-e "s/(set\\(JPEGXL_MAJOR_VERSION) [0-9]+\\)/\\1 ${major})/" \
|
||||
-e "s/(set\\(JPEGXL_MINOR_VERSION) [0-9]+\\)/\\1 ${minor})/" \
|
||||
-e "s/(set\\(JPEGXL_PATCH_VERSION) [0-9]+\\)/\\1 ${patch})/" \
|
||||
-i lib/CMakeLists.txt
|
||||
|
||||
# Update lib.gni
|
||||
tools/build_cleaner.py --update
|
||||
|
||||
# Mark the previous version as "unstable".
|
||||
DEBCHANGE_RELEASE_HEURISTIC=log dch -M --distribution unstable --release ''
|
||||
DEBCHANGE_RELEASE_HEURISTIC=log dch -M \
|
||||
--newversion "${newver}" \
|
||||
"Bump JPEG XL version to ${newver}."
|
||||
}
|
||||
|
||||
# Check that the AUTHORS file contains the email of the committer.
|
||||
cmd_authors() {
|
||||
merge_request_commits
|
||||
# TODO(deymo): Handle multiple commits and check that they are all the same
|
||||
# author.
|
||||
local email=$(git log --format='%ae' "${MR_HEAD_SHA}^!")
|
||||
local name=$(git log --format='%an' "${MR_HEAD_SHA}^!")
|
||||
"${MYDIR}"/tools/check_author.py "${email}" "${name}"
|
||||
}
|
||||
|
||||
main() {
|
||||
local cmd="${1:-}"
|
||||
if [[ -z "${cmd}" ]]; then
|
||||
|
|
@ -1272,6 +1440,8 @@ Where cmd is one of:
|
|||
msan Build and test an MSan (MemorySanitizer) build. Needs to have msan
|
||||
c++ libs installed with msan_install first.
|
||||
tsan Build and test a TSan (ThreadSanitizer) build.
|
||||
asanfuzz Build and test an ASan (AddressSanitizer) build for fuzzing.
|
||||
msanfuzz Build and test an MSan (MemorySanitizer) build for fuzzing.
|
||||
test Run the tests build by opt, debug, release, asan or msan. Useful when
|
||||
building with SKIP_TEST=1.
|
||||
gbench Run the Google benchmark tests.
|
||||
|
|
@ -1287,6 +1457,7 @@ Where cmd is one of:
|
|||
|
||||
lint Run the linter checks on the current commit or merge request.
|
||||
tidy Run clang-tidy on the current commit or merge request.
|
||||
authors Check that the last commit's author is listed in the AUTHORS file.
|
||||
|
||||
msan_install Install the libc++ libraries required to build in msan mode. This
|
||||
needs to be done once.
|
||||
|
|
@ -1294,6 +1465,15 @@ Where cmd is one of:
|
|||
debian_build <srcpkg> Build the given source package.
|
||||
debian_stats Print stats about the built packages.
|
||||
|
||||
oss-fuzz commands:
|
||||
ossfuzz_asan Build the local source inside oss-fuzz docker with asan.
|
||||
ossfuzz_msan Build the local source inside oss-fuzz docker with msan.
|
||||
ossfuzz_ubsan Build the local source inside oss-fuzz docker with ubsan.
|
||||
ossfuzz_ninja Run ninja on the BUILD_DIR inside the oss-fuzz docker. Extra
|
||||
parameters are passed to ninja, for example "djxl_fuzzer" will
|
||||
only build that ninja target. Use for faster build iteration
|
||||
after one of the ossfuzz_*san commands.
|
||||
|
||||
You can pass some optional environment variables as well:
|
||||
- BUILD_DIR: The output build directory (by default "$$repo/build")
|
||||
- BUILD_TARGET: The target triplet used when cross-compiling.
|
||||
|
|
|
|||
39
third_party/jpeg-xl/debian/changelog
vendored
39
third_party/jpeg-xl/debian/changelog
vendored
|
|
@ -1,57 +1,54 @@
|
|||
jpeg-xl (0.7) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.7.
|
||||
|
||||
-- JPEG XL Maintainers <jpegxl@google.com> Fri, 10 Sep 2021 16:08:17 +0200
|
||||
|
||||
jpeg-xl (0.6) unstable; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.6.
|
||||
|
||||
-- JPEG XL Maintainers <jpegxl@google.com> Fri, 10 Sep 2021 16:08:17 +0200
|
||||
|
||||
jpeg-xl (0.5.0) unstable; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.5.0.
|
||||
|
||||
-- JPEG XL Maintainers <jpegxl@google.com> Thu, 12 Aug 2021 23:49:40 +0200
|
||||
|
||||
jpeg-xl (0.3.7) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.7.
|
||||
* Fix a rounding issue in 8-bit decoding.
|
||||
|
||||
-- Sami Boukortt <sboukortt@google.com> Mon, 29 Mar 2021 12:14:20 +0200
|
||||
|
||||
jpeg-xl (0.3.6) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.6.
|
||||
* Fix a bug that could result in the generation of invalid codestreams as
|
||||
well as failure to decode valid streams.
|
||||
|
||||
-- Sami Boukortt <sboukortt@google.com> Thu, 25 Mar 2021 17:40:58 +0100
|
||||
|
||||
jpeg-xl (0.3.5) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.5.
|
||||
* Memory usage improvements.
|
||||
* New encode-time options for faster decoding at the cost of quality.
|
||||
* Faster decoding to 8-bit output with the C API.
|
||||
* GIMP plugin: avoid the sRGB conversion dialog for sRGB images, do not show
|
||||
a console window on Windows.
|
||||
* Various bug fixes.
|
||||
* Man pages for cjxl and djxl.
|
||||
|
||||
-- Sami Boukortt <sboukortt@google.com> Tue, 23 Mar 2021 15:20:44 +0100
|
||||
|
||||
jpeg-xl (0.3.4) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.4.
|
||||
* Improved box parsing.
|
||||
* Improved metadata handling.
|
||||
* Performance and memory usage improvements.
|
||||
|
||||
-- Sami Boukortt <sboukortt@google.com> Tue, 16 Mar 2021 12:13:59 +0100
|
||||
|
||||
jpeg-xl (0.3.3) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.3.
|
||||
* Performance improvements for small images.
|
||||
* Add a (flag-protected) non-high-precision mode with better speed.
|
||||
* Significantly speed up the PQ EOTF.
|
||||
* Allow optional HDR tone mapping in djxl (--tone_map, --display_nits).
|
||||
* Change the behavior of djxl -j to make it consistent with cjxl (#153).
|
||||
* Improve image quality.
|
||||
* Improve EXIF handling.
|
||||
|
||||
-- Sami Boukortt <sboukortt@google.com> Fri, 5 Mar 2021 19:15:26 +0100
|
||||
|
||||
jpeg-xl (0.3.2) UNRELEASED; urgency=medium
|
||||
|
||||
* Bump JPEG XL version to 0.3.2.
|
||||
* Fix embedded ICC encoding regression #149.
|
||||
|
||||
-- Alex Deymo <deymo@google.com> Fri, 12 Feb 2021 21:00:12 +0100
|
||||
|
||||
|
|
|
|||
55
third_party/jpeg-xl/debian/control
vendored
55
third_party/jpeg-xl/debian/control
vendored
|
|
@ -3,20 +3,26 @@ Maintainer: JPEG XL Maintainers <jpegxl@google.com>
|
|||
Section: misc
|
||||
Priority: optional
|
||||
Standards-Version: 3.9.8
|
||||
Build-Depends: cmake,
|
||||
debhelper (>= 9),
|
||||
libbrotli-dev,
|
||||
libgif-dev,
|
||||
libgmock-dev,
|
||||
libgoogle-perftools-dev,
|
||||
libgtest-dev,
|
||||
libhwy-dev,
|
||||
libjpeg-dev,
|
||||
libopenexr-dev,
|
||||
libpng-dev,
|
||||
libwebp-dev,
|
||||
pkg-config,
|
||||
Homepage: https://gitlab.com/wg1/jpeg-xl
|
||||
Build-Depends:
|
||||
asciidoc,
|
||||
cmake,
|
||||
debhelper (>= 9),
|
||||
libbrotli-dev,
|
||||
libgdk-pixbuf-2.0-dev | libgdk-pixbuf2.0-dev,
|
||||
libgif-dev,
|
||||
libgimp2.0-dev,
|
||||
libgmock-dev,
|
||||
libgoogle-perftools-dev,
|
||||
libgtest-dev,
|
||||
libhwy-dev,
|
||||
libjpeg-dev,
|
||||
libopenexr-dev,
|
||||
libpng-dev,
|
||||
libwebp-dev,
|
||||
pkg-config,
|
||||
xdg-utils,
|
||||
xmlto,
|
||||
Homepage: https://github.com/libjxl/libjxl
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: jxl
|
||||
|
|
@ -36,6 +42,7 @@ Package: libjxl-dev
|
|||
Architecture: any
|
||||
Section: libdevel
|
||||
Depends: libjxl (= ${binary:Version}), ${misc:Depends}
|
||||
libhwy-dev,
|
||||
Description: JPEG XL Image Coding System - "JXL" (development files)
|
||||
The JPEG XL Image Coding System (ISO/IEC 18181) is a lossy and
|
||||
lossless image compression format. It has a rich feature set and is
|
||||
|
|
@ -59,3 +66,23 @@ Description: JPEG XL Image Coding System - "JXL" (shared libraries)
|
|||
several features that help transition from the legacy JPEG format.
|
||||
.
|
||||
This package installs shared libraries.
|
||||
|
||||
Package: libjxl-gdk-pixbuf
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Section: libs
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Description: JPEG XL Plugin for gdk-pixbuf
|
||||
This package installs the required files for reading JPEG XL files in
|
||||
GTK applications.
|
||||
|
||||
Package: libjxl-gimp-plugin
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Section: graphics
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Pre-Depends: ${misc:Pre-Depends}
|
||||
Enhances: gimp
|
||||
Description: JPEG XL Import and Export Plugin for GIMP
|
||||
This is a plugin for GIMP version 2.10.x to import and export JPEG XL images.
|
||||
|
|
|
|||
4
third_party/jpeg-xl/debian/jxl.install
vendored
4
third_party/jpeg-xl/debian/jxl.install
vendored
|
|
@ -1 +1,3 @@
|
|||
debian/tmp/usr/bin/*
|
||||
usr/bin/*
|
||||
usr/share/man/man1/cjxl.1
|
||||
usr/share/man/man1/djxl.1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
debian/tmp/usr/include/jxl/*.h
|
||||
debian/tmp/usr/lib/*/*.a
|
||||
debian/tmp/usr/lib/*/*.so
|
||||
debian/tmp/usr/lib/*/pkgconfig/*.pc
|
||||
usr/include/jxl/*.h
|
||||
usr/lib/*/*.a
|
||||
usr/lib/*/*.so
|
||||
usr/lib/*/pkgconfig/*.pc
|
||||
|
|
|
|||
3
third_party/jpeg-xl/debian/libjxl-gdk-pixbuf.install
vendored
Normal file
3
third_party/jpeg-xl/debian/libjxl-gdk-pixbuf.install
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
usr/lib/*/gdk-pixbuf-*/*/loaders/*
|
||||
usr/share/mime/packages/image-jxl.xml
|
||||
usr/share/thumbnailers/jxl.thumbnailer
|
||||
1
third_party/jpeg-xl/debian/libjxl-gimp-plugin.install
vendored
Normal file
1
third_party/jpeg-xl/debian/libjxl-gimp-plugin.install
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
usr/lib/gimp
|
||||
2
third_party/jpeg-xl/debian/libjxl.install
vendored
2
third_party/jpeg-xl/debian/libjxl.install
vendored
|
|
@ -1 +1 @@
|
|||
debian/tmp/usr/lib/*/libjxl*.so.*
|
||||
usr/lib/*/libjxl*.so.*
|
||||
|
|
|
|||
7
third_party/jpeg-xl/debian/rules
vendored
Executable file → Normal file
7
third_party/jpeg-xl/debian/rules
vendored
Executable file → Normal file
|
|
@ -1,4 +1,7 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
include /usr/share/dpkg/pkg-info.mk
|
||||
|
||||
%:
|
||||
dh $@ --buildsystem=cmake
|
||||
|
||||
|
|
@ -6,7 +9,9 @@ override_dh_auto_configure:
|
|||
# TODO(deymo): Remove the DCMAKE_BUILD_TYPE once builds without NDEBUG
|
||||
# are as useful as Release builds.
|
||||
dh_auto_configure -- \
|
||||
-DJPEGXL_VERSION=$(DEB_VERSION) \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DJPEGXL_FORCE_SYSTEM_GTEST=ON \
|
||||
-DJPEGXL_FORCE_SYSTEM_BROTLI=ON \
|
||||
-DJPEGXL_FORCE_SYSTEM_HWY=ON
|
||||
-DJPEGXL_FORCE_SYSTEM_HWY=ON \
|
||||
-DJPEGXL_ENABLE_PLUGINS=ON
|
||||
|
|
|
|||
4
third_party/jpeg-xl/deps.sh
vendored
Executable file → Normal file
4
third_party/jpeg-xl/deps.sh
vendored
Executable file → Normal file
|
|
@ -13,7 +13,7 @@ MYDIR=$(dirname $(realpath "$0"))
|
|||
|
||||
# Git revisions we use for the given submodules. Update these whenever you
|
||||
# update a git submodule.
|
||||
THIRD_PARTY_HIGHWAY="ca1a57c342cd815053abfcffa29b44eaead4f20b"
|
||||
THIRD_PARTY_HIGHWAY="e2397743fe092df68b760d358253773699a16c93"
|
||||
THIRD_PARTY_LODEPNG="48e5364ef48ec2408f44c727657ac1b6703185f8"
|
||||
THIRD_PARTY_SKCMS="64374756e03700d649f897dbd98c95e78c30c7da"
|
||||
THIRD_PARTY_SJPEG="868ab558fad70fcbe8863ba4e85179eeb81cc840"
|
||||
|
|
@ -59,7 +59,7 @@ download_github() {
|
|||
main() {
|
||||
if git -C "${MYDIR}" rev-parse; then
|
||||
cat >&2 <<EOF
|
||||
Currenty directory is a git repository, downloading dependencies via git:
|
||||
Current directory is a git repository, downloading dependencies via git:
|
||||
|
||||
git submodule update --init --recursive
|
||||
|
||||
|
|
|
|||
0
third_party/jpeg-xl/docker/build.sh
vendored
Executable file → Normal file
0
third_party/jpeg-xl/docker/build.sh
vendored
Executable file → Normal file
4
third_party/jpeg-xl/docker/scripts/emsdk_install.sh
vendored
Executable file → Normal file
4
third_party/jpeg-xl/docker/scripts/emsdk_install.sh
vendored
Executable file → Normal file
|
|
@ -4,10 +4,10 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
EMSDK_URL="https://github.com/emscripten-core/emsdk/archive/master.tar.gz"
|
||||
EMSDK_URL="https://github.com/emscripten-core/emsdk/archive/main.tar.gz"
|
||||
EMSDK_DIR="/opt/emsdk"
|
||||
|
||||
EMSDK_RELEASE="2.0.4"
|
||||
EMSDK_RELEASE="2.0.23"
|
||||
|
||||
set -eu -x
|
||||
|
||||
|
|
|
|||
18
third_party/jpeg-xl/docker/scripts/jpegxl_builder.sh
vendored
Executable file → Normal file
18
third_party/jpeg-xl/docker/scripts/jpegxl_builder.sh
vendored
Executable file → Normal file
|
|
@ -57,7 +57,7 @@ BENCHMARK_FLAGS="-DCMAKE_BUILD_TYPE=Release -DBENCHMARK_ENABLE_TESTING=OFF \
|
|||
-DCMAKE_POSITION_INDEPENDENT_CODE=ON"
|
||||
|
||||
# V8
|
||||
V8_VERSION="8.7.230"
|
||||
V8_VERSION="9.3.22"
|
||||
|
||||
# Temporary files cleanup hooks.
|
||||
CLEANUP_FILES=()
|
||||
|
|
@ -168,6 +168,11 @@ install_pkgs() {
|
|||
parallel
|
||||
pkg-config
|
||||
|
||||
# For compiling / testing JNI wrapper. JDK8 is almost 2x smaller than JDK11
|
||||
# openjdk-8-jdk-headless would be 50MB smaller, unfortunately, CMake
|
||||
# does mistakenly thinks it does not contain JNI feature.
|
||||
openjdk-8-jdk
|
||||
|
||||
# These are used by the ./ci.sh lint in the native builder.
|
||||
clang-format-7
|
||||
clang-format-8
|
||||
|
|
@ -358,7 +363,7 @@ install_from_source() {
|
|||
fi
|
||||
|
||||
if [[ -e "${srcdir}/CMakeLists.txt" ]]; then
|
||||
# Most pacakges use cmake for building which is easier to configure for
|
||||
# Most packages use cmake for building which is easier to configure for
|
||||
# cross-compiling.
|
||||
if [[ "${package}" == "JPEG_TURBO" && "${target}" == wasm* ]]; then
|
||||
# JT erroneously detects WASM CPU as i386 and tries to use asm.
|
||||
|
|
@ -399,6 +404,10 @@ install_from_source() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# CMake mistakenly uses ".so" libraries and EMCC fails to link properly.
|
||||
if [[ "${target}" == wasm* ]]; then
|
||||
rm -f "${prefix}/lib"/*.so*
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
|
@ -431,6 +440,9 @@ main() {
|
|||
install_binutils
|
||||
apt clean
|
||||
|
||||
# Remove prebuilt Java classes cache.
|
||||
rm /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server/classes.jsa
|
||||
|
||||
# Manually extract packages for the target arch that can't install it directly
|
||||
# at the same time as the native ones.
|
||||
local ubarch
|
||||
|
|
@ -492,7 +504,7 @@ main() {
|
|||
|
||||
install_from_source BENCHMARK "${LIST_TARGETS[@]}" "${LIST_MINGW_TARGETS[@]}"
|
||||
|
||||
# Install v8. v8 has better WASM SIMD support than NodeJS 14.
|
||||
# Install v8. v8 has better WASM SIMD support than NodeJS 14 (LTS).
|
||||
# First we need the installer to install v8.
|
||||
npm install jsvu -g
|
||||
# install specific version;
|
||||
|
|
|
|||
0
third_party/jpeg-xl/docker/scripts/msan_install.sh
vendored
Executable file → Normal file
0
third_party/jpeg-xl/docker/scripts/msan_install.sh
vendored
Executable file → Normal file
0
third_party/jpeg-xl/docker/scripts/qemu_install.sh
vendored
Executable file → Normal file
0
third_party/jpeg-xl/docker/scripts/qemu_install.sh
vendored
Executable file → Normal file
55
third_party/jpeg-xl/examples/CMakeLists.txt
vendored
55
third_party/jpeg-xl/examples/CMakeLists.txt
vendored
|
|
@ -3,17 +3,54 @@
|
|||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
# Example project using libjxl.
|
||||
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
project(SAMPLE_LIBJXL LANGUAGES C CXX)
|
||||
|
||||
# Use pkg-config to find libjxl.
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(Jxl REQUIRED IMPORTED_TARGET libjxl)
|
||||
pkg_check_modules(JxlThreads REQUIRED IMPORTED_TARGET libjxl_threads)
|
||||
|
||||
# Build the example encoder/decoder binaries using the default shared libraries
|
||||
# installed.
|
||||
add_executable(decode_oneshot decode_oneshot.cc)
|
||||
target_link_libraries(decode_oneshot jxl_dec jxl_threads)
|
||||
target_link_libraries(decode_oneshot PkgConfig::Jxl PkgConfig::JxlThreads)
|
||||
|
||||
add_executable(encode_oneshot encode_oneshot.cc)
|
||||
target_link_libraries(encode_oneshot jxl jxl_threads)
|
||||
target_link_libraries(encode_oneshot PkgConfig::Jxl PkgConfig::JxlThreads)
|
||||
|
||||
add_executable(jxlinfo jxlinfo.c)
|
||||
target_link_libraries(jxlinfo jxl)
|
||||
target_link_libraries(jxlinfo PkgConfig::Jxl)
|
||||
|
||||
if(NOT ${SANITIZER} STREQUAL "none")
|
||||
# Linking a C test binary with the C++ JPEG XL implementation when using
|
||||
# address sanitizer is not well supported by clang 9, so force using clang++
|
||||
# for linking this test if a sanitizer is used.
|
||||
set_target_properties(jxlinfo PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif() # SANITIZER != "none"
|
||||
|
||||
# Building a static binary with the static libjxl dependencies. How to load
|
||||
# static library configs from pkg-config and how to build static binaries
|
||||
# depends on the platform, and building static binaries in general has problems.
|
||||
# If you don't need static binaries you can remove this section.
|
||||
add_library(StaticJxl INTERFACE IMPORTED GLOBAL)
|
||||
set_target_properties(StaticJxl PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Jxl_STATIC_INCLUDE_DIR}"
|
||||
INTERFACE_COMPILE_OPTIONS "${Jxl_STATIC_CFLAGS_OTHER}"
|
||||
INTERFACE_LINK_LIBRARIES "${Jxl_STATIC_LDFLAGS}"
|
||||
)
|
||||
add_library(StaticJxlThreads INTERFACE IMPORTED GLOBAL)
|
||||
set_target_properties(StaticJxlThreads PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${JxlThreads_STATIC_INCLUDE_DIR}"
|
||||
INTERFACE_COMPILE_OPTIONS "${JxlThreads_STATIC_CFLAGS_OTHER}"
|
||||
# libgcc uses weak symbols for pthread which means that -lpthread is not
|
||||
# linked when compiling a static binary. This is a platform-specific fix for
|
||||
# that.
|
||||
INTERFACE_LINK_LIBRARIES
|
||||
"${JxlThreads_STATIC_LDFLAGS} -Wl,--whole-archive -lpthread -Wl,--no-whole-archive"
|
||||
)
|
||||
|
||||
add_executable(decode_oneshot_static decode_oneshot.cc)
|
||||
target_link_libraries(decode_oneshot_static
|
||||
-static StaticJxl StaticJxlThreads)
|
||||
|
||||
add_executable(encode_oneshot_static encode_oneshot.cc)
|
||||
target_link_libraries(encode_oneshot_static
|
||||
-static StaticJxl StaticJxlThreads)
|
||||
|
|
|
|||
165
third_party/jpeg-xl/examples/decode_exif_metadata.cc
vendored
Normal file
165
third_party/jpeg-xl/examples/decode_exif_metadata.cc
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This C++ example decodes a JPEG XL image in one shot (all input bytes
|
||||
// available at once). The example outputs the pixels and color information to a
|
||||
// floating point image and an ICC profile on disk.
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "jxl/decode.h"
|
||||
#include "jxl/decode_cxx.h"
|
||||
|
||||
bool DecodeJpegXlExif(const uint8_t* jxl, size_t size,
|
||||
std::vector<uint8_t>* exif) {
|
||||
auto dec = JxlDecoderMake(nullptr);
|
||||
|
||||
// We're only interested in the Exif boxes in this example, so don't
|
||||
// subscribe to events related to pixel data.
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderSubscribeEvents(dec.get(), JXL_DEC_BOX)) {
|
||||
fprintf(stderr, "JxlDecoderSubscribeEvents failed\n");
|
||||
return false;
|
||||
}
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderSetDecompressBoxes(dec.get(), JXL_TRUE)) {
|
||||
fprintf(stderr, "JxlDecoderSetDecompressBoxes failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
JxlDecoderSetInput(dec.get(), jxl, size);
|
||||
|
||||
const constexpr size_t kChunkSize = 65536;
|
||||
size_t output_pos = 0;
|
||||
|
||||
for (;;) {
|
||||
JxlDecoderStatus status = JxlDecoderProcessInput(dec.get());
|
||||
|
||||
if (status == JXL_DEC_ERROR) {
|
||||
fprintf(stderr, "Decoder error\n");
|
||||
return false;
|
||||
} else if (status == JXL_DEC_NEED_MORE_INPUT) {
|
||||
fprintf(stderr, "Error, already provided all input\n");
|
||||
return false;
|
||||
} else if (status == JXL_DEC_BOX) {
|
||||
if (!exif->empty()) {
|
||||
size_t remaining = JxlDecoderReleaseBoxBuffer(dec.get());
|
||||
exif->resize(exif->size() - remaining);
|
||||
// No need to wait for JXL_DEC_SUCCESS or decode other boxes.
|
||||
return true;
|
||||
}
|
||||
JxlBoxType type;
|
||||
if (!JxlDecoderGetBoxType(dec.get(), &type, JXL_TRUE)) {
|
||||
fprintf(stderr, "Error, failed to get box type\n");
|
||||
}
|
||||
if (!memcmp(type, "Exif", 4)) {
|
||||
exif->resize(kChunkSize);
|
||||
JxlDecoderSetBoxBuffer(dec.get(), exif->data(), exif->size());
|
||||
}
|
||||
} else if (status == JXL_DEC_BOX_NEED_MORE_OUTPUT) {
|
||||
size_t remaining = JxlDecoderReleaseBoxBuffer(dec.get());
|
||||
output_pos += kChunkSize - remaining;
|
||||
exif->resize(exif->size() + kChunkSize);
|
||||
JxlDecoderSetBoxBuffer(dec.get(), exif->data() + output_pos,
|
||||
exif->size() - output_pos);
|
||||
} else if (status == JXL_DEC_SUCCESS) {
|
||||
if (!exif->empty()) {
|
||||
size_t remaining = JxlDecoderReleaseBoxBuffer(dec.get());
|
||||
exif->resize(exif->size() - remaining);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
fprintf(stderr, "Unknown decoder status\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadFile(const char* filename, std::vector<uint8_t>* out) {
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fseek(file, 0, SEEK_END) != 0) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
long size = ftell(file);
|
||||
// Avoid invalid file or directory.
|
||||
if (size >= LONG_MAX || size < 0) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fseek(file, 0, SEEK_SET) != 0) {
|
||||
fclose(file);
|
||||
return false;
|
||||
}
|
||||
|
||||
out->resize(size);
|
||||
size_t readsize = fread(out->data(), 1, size, file);
|
||||
if (fclose(file) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return readsize == static_cast<size_t>(size);
|
||||
}
|
||||
|
||||
bool WriteFile(const char* filename, const uint8_t* data, size_t size) {
|
||||
FILE* file = fopen(filename, "wb");
|
||||
if (!file) {
|
||||
fprintf(stderr, "Could not open %s for writing", filename);
|
||||
return false;
|
||||
}
|
||||
fwrite(data, 1, size, file);
|
||||
if (fclose(file) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s <jxl> <exif>\n"
|
||||
"Where:\n"
|
||||
" jxl = input JPEG XL image filename\n"
|
||||
" exif = output exif filename\n"
|
||||
"Output files will be overwritten.\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* jxl_filename = argv[1];
|
||||
const char* exif_filename = argv[2];
|
||||
|
||||
std::vector<uint8_t> jxl;
|
||||
if (!LoadFile(jxl_filename, &jxl)) {
|
||||
fprintf(stderr, "couldn't load %s\n", jxl_filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> exif;
|
||||
if (!DecodeJpegXlExif(jxl.data(), jxl.size(), &exif)) {
|
||||
fprintf(stderr, "Error while decoding the jxl file\n");
|
||||
return 1;
|
||||
}
|
||||
if (exif.empty()) {
|
||||
printf("No exif data present in this image\n");
|
||||
} else {
|
||||
if (!WriteFile(exif_filename, exif.data(), exif.size())) {
|
||||
fprintf(stderr, "Error while writing the exif file\n");
|
||||
return 1;
|
||||
}
|
||||
printf("Successfully wrote %s\n", exif_filename);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
12
third_party/jpeg-xl/examples/decode_oneshot.cc
vendored
12
third_party/jpeg-xl/examples/decode_oneshot.cc
vendored
|
|
@ -16,8 +16,8 @@
|
|||
|
||||
#include "jxl/decode.h"
|
||||
#include "jxl/decode_cxx.h"
|
||||
#include "jxl/thread_parallel_runner.h"
|
||||
#include "jxl/thread_parallel_runner_cxx.h"
|
||||
#include "jxl/resizable_parallel_runner.h"
|
||||
#include "jxl/resizable_parallel_runner_cxx.h"
|
||||
|
||||
/** Decodes JPEG XL image to floating point pixels and ICC Profile. Pixel are
|
||||
* stored as floating point, as interleaved RGBA (4 floating point values per
|
||||
|
|
@ -29,8 +29,7 @@ bool DecodeJpegXlOneShot(const uint8_t* jxl, size_t size,
|
|||
std::vector<float>* pixels, size_t* xsize,
|
||||
size_t* ysize, std::vector<uint8_t>* icc_profile) {
|
||||
// Multi-threaded parallel runner.
|
||||
auto runner = JxlThreadParallelRunnerMake(
|
||||
nullptr, JxlThreadParallelRunnerDefaultNumWorkerThreads());
|
||||
auto runner = JxlResizableParallelRunnerMake(nullptr);
|
||||
|
||||
auto dec = JxlDecoderMake(nullptr);
|
||||
if (JXL_DEC_SUCCESS !=
|
||||
|
|
@ -42,7 +41,7 @@ bool DecodeJpegXlOneShot(const uint8_t* jxl, size_t size,
|
|||
}
|
||||
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderSetParallelRunner(dec.get(),
|
||||
JxlThreadParallelRunner,
|
||||
JxlResizableParallelRunner,
|
||||
runner.get())) {
|
||||
fprintf(stderr, "JxlDecoderSetParallelRunner failed\n");
|
||||
return false;
|
||||
|
|
@ -69,6 +68,9 @@ bool DecodeJpegXlOneShot(const uint8_t* jxl, size_t size,
|
|||
}
|
||||
*xsize = info.xsize;
|
||||
*ysize = info.ysize;
|
||||
JxlResizableParallelRunnerSetThreads(
|
||||
runner.get(),
|
||||
JxlResizableParallelRunnerSuggestThreads(info.xsize, info.ysize));
|
||||
} else if (status == JXL_DEC_COLOR_ENCODING) {
|
||||
// Get the ICC color profile of the pixel data
|
||||
size_t icc_size;
|
||||
|
|
|
|||
|
|
@ -162,13 +162,12 @@ bool EncodeJxlOneshot(const std::vector<float>& pixels, const uint32_t xsize,
|
|||
|
||||
JxlPixelFormat pixel_format = {3, JXL_TYPE_FLOAT, JXL_NATIVE_ENDIAN, 0};
|
||||
|
||||
JxlBasicInfo basic_info = {};
|
||||
JxlBasicInfo basic_info;
|
||||
JxlEncoderInitBasicInfo(&basic_info);
|
||||
basic_info.xsize = xsize;
|
||||
basic_info.ysize = ysize;
|
||||
basic_info.bits_per_sample = 32;
|
||||
basic_info.exponent_bits_per_sample = 8;
|
||||
basic_info.alpha_exponent_bits = 0;
|
||||
basic_info.alpha_bits = 0;
|
||||
basic_info.uses_original_profile = JXL_FALSE;
|
||||
if (JXL_ENC_SUCCESS != JxlEncoderSetBasicInfo(enc.get(), &basic_info)) {
|
||||
fprintf(stderr, "JxlEncoderSetBasicInfo failed\n");
|
||||
|
|
|
|||
19
third_party/jpeg-xl/examples/examples.cmake
vendored
Normal file
19
third_party/jpeg-xl/examples/examples.cmake
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style
|
||||
# license that can be found in the LICENSE file.
|
||||
|
||||
add_executable(decode_oneshot ${CMAKE_CURRENT_LIST_DIR}/decode_oneshot.cc)
|
||||
target_link_libraries(decode_oneshot jxl_dec jxl_threads)
|
||||
add_executable(encode_oneshot ${CMAKE_CURRENT_LIST_DIR}/encode_oneshot.cc)
|
||||
target_link_libraries(encode_oneshot jxl jxl_threads)
|
||||
|
||||
add_executable(jxlinfo ${CMAKE_CURRENT_LIST_DIR}/jxlinfo.c)
|
||||
target_link_libraries(jxlinfo jxl)
|
||||
|
||||
if(NOT ${SANITIZER} STREQUAL "none")
|
||||
# Linking a C test binary with the C++ JPEG XL implementation when using
|
||||
# address sanitizer is not well supported by clang 9, so force using clang++
|
||||
# for linking this test if a sanitizer is used.
|
||||
set_target_properties(jxlinfo PROPERTIES LINKER_LANGUAGE CXX)
|
||||
endif() # SANITIZER != "none"
|
||||
227
third_party/jpeg-xl/examples/jxlinfo.c
vendored
227
third_party/jpeg-xl/examples/jxlinfo.c
vendored
|
|
@ -26,8 +26,8 @@ int PrintBasicInfo(FILE* file) {
|
|||
JxlDecoderSetKeepOrientation(dec, 1);
|
||||
|
||||
if (JXL_DEC_SUCCESS !=
|
||||
JxlDecoderSubscribeEvents(dec,
|
||||
JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING)) {
|
||||
JxlDecoderSubscribeEvents(
|
||||
dec, JXL_DEC_BASIC_INFO | JXL_DEC_COLOR_ENCODING | JXL_DEC_FRAME)) {
|
||||
fprintf(stderr, "JxlDecoderSubscribeEvents failed\n");
|
||||
JxlDecoderDestroy(dec);
|
||||
return 0;
|
||||
|
|
@ -35,6 +35,7 @@ int PrintBasicInfo(FILE* file) {
|
|||
|
||||
JxlBasicInfo info;
|
||||
int seen_basic_info = 0;
|
||||
JxlFrameHeader frame_header;
|
||||
|
||||
for (;;) {
|
||||
// The first time, this will output JXL_DEC_NEED_MORE_INPUT because no
|
||||
|
|
@ -75,16 +76,21 @@ int PrintBasicInfo(FILE* file) {
|
|||
|
||||
seen_basic_info = 1;
|
||||
|
||||
printf("xsize: %u\n", info.xsize);
|
||||
printf("ysize: %u\n", info.ysize);
|
||||
printf("dimensions: %ux%u\n", info.xsize, info.ysize);
|
||||
printf("have_container: %d\n", info.have_container);
|
||||
printf("uses_original_profile: %d\n", info.uses_original_profile);
|
||||
printf("bits_per_sample: %d\n", info.bits_per_sample);
|
||||
printf("exponent_bits_per_sample: %d\n", info.exponent_bits_per_sample);
|
||||
printf("intensity_target: %f\n", info.intensity_target);
|
||||
printf("min_nits: %f\n", info.min_nits);
|
||||
printf("relative_to_max_display: %d\n", info.relative_to_max_display);
|
||||
printf("linear_below: %f\n", info.linear_below);
|
||||
if (info.exponent_bits_per_sample)
|
||||
printf("float, with exponent_bits_per_sample: %d\n",
|
||||
info.exponent_bits_per_sample);
|
||||
if (info.intensity_target != 255.f || info.min_nits != 0.f ||
|
||||
info.relative_to_max_display != 0 ||
|
||||
info.relative_to_max_display != 0.f) {
|
||||
printf("intensity_target: %f\n", info.intensity_target);
|
||||
printf("min_nits: %f\n", info.min_nits);
|
||||
printf("relative_to_max_display: %d\n", info.relative_to_max_display);
|
||||
printf("linear_below: %f\n", info.linear_below);
|
||||
}
|
||||
printf("have_preview: %d\n", info.have_preview);
|
||||
if (info.have_preview) {
|
||||
printf("preview xsize: %u\n", info.preview.xsize);
|
||||
|
|
@ -97,25 +103,45 @@ int PrintBasicInfo(FILE* file) {
|
|||
printf("num_loops: %u\n", info.animation.num_loops);
|
||||
printf("have_timecodes: %d\n", info.animation.have_timecodes);
|
||||
}
|
||||
printf("orientation: %d\n", info.orientation);
|
||||
const char* const orientation_string[8] = {
|
||||
"Normal", "Flipped horizontally",
|
||||
"Upside down", "Flipped vertically",
|
||||
"Transposed", "90 degrees clockwise",
|
||||
"Anti-Transposed", "90 degrees counter-clockwise"};
|
||||
if (info.orientation > 0 && info.orientation < 9) {
|
||||
printf("orientation: %d (%s)\n", info.orientation,
|
||||
orientation_string[info.orientation - 1]);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid orientation\n");
|
||||
}
|
||||
printf("num_color_channels: %d\n", info.num_color_channels);
|
||||
printf("num_extra_channels: %d\n", info.num_extra_channels);
|
||||
printf("alpha_bits: %d\n", info.alpha_bits);
|
||||
printf("alpha_exponent_bits: %d\n", info.alpha_exponent_bits);
|
||||
printf("alpha_premultiplied: %d\n", info.alpha_premultiplied);
|
||||
|
||||
const char* const ec_type_names[7] = {"Alpha", "Depth",
|
||||
"Spot color", "Selection mask",
|
||||
"K (of CMYK)", "CFA (Bayer data)",
|
||||
"Thermal"};
|
||||
for (uint32_t i = 0; i < info.num_extra_channels; i++) {
|
||||
JxlExtraChannelInfo extra;
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderGetExtraChannelInfo(dec, i, &extra)) {
|
||||
fprintf(stderr, "JxlDecoderGetExtraChannelInfo failed\n");
|
||||
break;
|
||||
}
|
||||
printf("extra channel: %u info:\n", i);
|
||||
printf(" type: %d\n", extra.type);
|
||||
printf("extra channel %u:\n", i);
|
||||
printf(" type: %s\n",
|
||||
(extra.type < 7 ? ec_type_names[extra.type]
|
||||
: (extra.type == JXL_CHANNEL_OPTIONAL
|
||||
? "Unknown but can be ignored"
|
||||
: "Unknown, please update your libjxl")));
|
||||
printf(" bits_per_sample: %u\n", extra.bits_per_sample);
|
||||
printf(" exponent_bits_per_sample: %u\n",
|
||||
extra.exponent_bits_per_sample);
|
||||
printf(" dim_shift: %u\n", extra.dim_shift);
|
||||
printf(" name_length: %u\n", extra.name_length);
|
||||
if (extra.exponent_bits_per_sample > 0) {
|
||||
printf(" float, with exponent_bits_per_sample: %u\n",
|
||||
extra.exponent_bits_per_sample);
|
||||
}
|
||||
if (extra.dim_shift > 0) {
|
||||
printf(" dim_shift: %u (upsampled %ux)\n", extra.dim_shift,
|
||||
1 << extra.dim_shift);
|
||||
}
|
||||
if (extra.name_length) {
|
||||
char* name = malloc(extra.name_length + 1);
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderGetExtraChannelName(
|
||||
|
|
@ -127,37 +153,52 @@ int PrintBasicInfo(FILE* file) {
|
|||
free(name);
|
||||
printf(" name: %s\n", name);
|
||||
}
|
||||
printf(" alpha_associated: %d\n", extra.alpha_associated);
|
||||
printf(" spot_color: %f %f %f %f\n", extra.spot_color[0],
|
||||
extra.spot_color[1], extra.spot_color[2], extra.spot_color[3]);
|
||||
printf(" cfa_channel: %u\n", extra.cfa_channel);
|
||||
if (extra.type == JXL_CHANNEL_ALPHA)
|
||||
printf(" alpha_premultiplied: %d (%s)\n", extra.alpha_premultiplied,
|
||||
extra.alpha_premultiplied ? "Premultiplied"
|
||||
: "Non-premultiplied");
|
||||
if (extra.type == JXL_CHANNEL_SPOT_COLOR) {
|
||||
printf(" spot_color: (%f, %f, %f) with opacity %f\n",
|
||||
extra.spot_color[0], extra.spot_color[1], extra.spot_color[2],
|
||||
extra.spot_color[3]);
|
||||
}
|
||||
if (extra.type == JXL_CHANNEL_CFA)
|
||||
printf(" cfa_channel: %u\n", extra.cfa_channel);
|
||||
}
|
||||
} else if (status == JXL_DEC_COLOR_ENCODING) {
|
||||
JxlPixelFormat format = {4, JXL_TYPE_FLOAT, JXL_LITTLE_ENDIAN, 0};
|
||||
JxlColorProfileTarget targets[2] = {JXL_COLOR_PROFILE_TARGET_ORIGINAL,
|
||||
JXL_COLOR_PROFILE_TARGET_DATA};
|
||||
for (size_t i = 0; i < 2; i++) {
|
||||
JxlColorProfileTarget target = targets[i];
|
||||
if (info.uses_original_profile) {
|
||||
if (target != JXL_COLOR_PROFILE_TARGET_ORIGINAL) continue;
|
||||
printf("color profile:\n");
|
||||
} else {
|
||||
printf(target == JXL_COLOR_PROFILE_TARGET_ORIGINAL
|
||||
? "original color profile:\n"
|
||||
: "data color profile:\n");
|
||||
}
|
||||
printf("color profile:\n");
|
||||
|
||||
JxlColorEncoding color_encoding;
|
||||
if (JXL_DEC_SUCCESS == JxlDecoderGetColorAsEncodedProfile(
|
||||
dec, &format, target, &color_encoding)) {
|
||||
printf(" format: JPEG XL encoded color profile\n");
|
||||
printf(" color_space: %d\n", color_encoding.color_space);
|
||||
printf(" white_point: %d\n", color_encoding.white_point);
|
||||
JxlColorEncoding color_encoding;
|
||||
if (JXL_DEC_SUCCESS ==
|
||||
JxlDecoderGetColorAsEncodedProfile(dec, &format,
|
||||
JXL_COLOR_PROFILE_TARGET_ORIGINAL,
|
||||
&color_encoding)) {
|
||||
printf(" format: JPEG XL encoded color profile\n");
|
||||
const char* const cs_string[4] = {"RGB color", "Grayscale", "XYB",
|
||||
"Unknown"};
|
||||
const char* const wp_string[12] = {"", "D65", "Custom", "", "", "",
|
||||
"", "", "", "", "E", "P3"};
|
||||
const char* const pr_string[12] = {
|
||||
"", "sRGB", "Custom", "", "", "", "", "", "", "Rec.2100", "", "P3"};
|
||||
const char* const tf_string[19] = {
|
||||
"", "709", "Unknown", "", "", "", "", "", "Linear", "",
|
||||
"", "", "", "sRGB", "", "", "PQ", "DCI", "HLG"};
|
||||
const char* const ri_string[4] = {"Perceptual", "Relative",
|
||||
"Saturation", "Absolute"};
|
||||
printf(" color_space: %d (%s)\n", color_encoding.color_space,
|
||||
cs_string[color_encoding.color_space]);
|
||||
printf(" white_point: %d (%s)\n", color_encoding.white_point,
|
||||
wp_string[color_encoding.white_point]);
|
||||
if (color_encoding.white_point == JXL_WHITE_POINT_CUSTOM) {
|
||||
printf(" white_point XY: %f %f\n", color_encoding.white_point_xy[0],
|
||||
color_encoding.white_point_xy[1]);
|
||||
if (color_encoding.color_space == JXL_COLOR_SPACE_RGB ||
|
||||
color_encoding.color_space == JXL_COLOR_SPACE_UNKNOWN) {
|
||||
printf(" primaries: %d\n", color_encoding.primaries);
|
||||
}
|
||||
if (color_encoding.color_space == JXL_COLOR_SPACE_RGB ||
|
||||
color_encoding.color_space == JXL_COLOR_SPACE_UNKNOWN) {
|
||||
printf(" primaries: %d (%s)\n", color_encoding.primaries,
|
||||
pr_string[color_encoding.primaries]);
|
||||
if (color_encoding.primaries == JXL_PRIMARIES_CUSTOM) {
|
||||
printf(" red primaries XY: %f %f\n",
|
||||
color_encoding.primaries_red_xy[0],
|
||||
color_encoding.primaries_red_xy[1]);
|
||||
|
|
@ -168,40 +209,78 @@ int PrintBasicInfo(FILE* file) {
|
|||
color_encoding.primaries_blue_xy[0],
|
||||
color_encoding.primaries_blue_xy[1]);
|
||||
}
|
||||
printf(" transfer_function: %d\n", color_encoding.transfer_function);
|
||||
if (color_encoding.transfer_function == JXL_TRANSFER_FUNCTION_GAMMA) {
|
||||
printf(" transfer_function gamma: %f\n", color_encoding.gamma);
|
||||
}
|
||||
printf(" rendering_intent: %d\n", color_encoding.rendering_intent);
|
||||
}
|
||||
if (color_encoding.transfer_function == JXL_TRANSFER_FUNCTION_GAMMA) {
|
||||
printf(" transfer_function: gamma: %f\n", color_encoding.gamma);
|
||||
} else {
|
||||
// The profile is not in JPEG XL encoded form, get as ICC profile
|
||||
// instead.
|
||||
printf(" format: ICC profile\n");
|
||||
size_t profile_size;
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderGetICCProfileSize(
|
||||
dec, &format, target, &profile_size)) {
|
||||
fprintf(stderr, "JxlDecoderGetICCProfileSize failed\n");
|
||||
continue;
|
||||
}
|
||||
printf(" ICC profile size: %zu\n", profile_size);
|
||||
if (profile_size < 132) {
|
||||
fprintf(stderr, "ICC profile too small\n");
|
||||
continue;
|
||||
}
|
||||
uint8_t* profile = (uint8_t*)malloc(profile_size);
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsICCProfile(dec, &format,
|
||||
target, profile,
|
||||
profile_size)) {
|
||||
fprintf(stderr, "JxlDecoderGetColorAsICCProfile failed\n");
|
||||
free(profile);
|
||||
continue;
|
||||
}
|
||||
printf(" CMM type: \"%.4s\"\n", profile + 4);
|
||||
printf(" color space: \"%.4s\"\n", profile + 16);
|
||||
printf(" rendering intent: %d\n", (int)profile[67]);
|
||||
printf(" transfer_function: %d (%s)\n",
|
||||
color_encoding.transfer_function,
|
||||
tf_string[color_encoding.transfer_function]);
|
||||
}
|
||||
printf(" rendering_intent: %d (%s)\n", color_encoding.rendering_intent,
|
||||
ri_string[color_encoding.rendering_intent]);
|
||||
|
||||
} else {
|
||||
// The profile is not in JPEG XL encoded form, get as ICC profile
|
||||
// instead.
|
||||
printf(" format: ICC profile\n");
|
||||
size_t profile_size;
|
||||
if (JXL_DEC_SUCCESS !=
|
||||
JxlDecoderGetICCProfileSize(dec, &format,
|
||||
JXL_COLOR_PROFILE_TARGET_ORIGINAL,
|
||||
&profile_size)) {
|
||||
fprintf(stderr, "JxlDecoderGetICCProfileSize failed\n");
|
||||
continue;
|
||||
}
|
||||
printf(" ICC profile size: %zu\n", profile_size);
|
||||
if (profile_size < 132) {
|
||||
fprintf(stderr, "ICC profile too small\n");
|
||||
continue;
|
||||
}
|
||||
uint8_t* profile = (uint8_t*)malloc(profile_size);
|
||||
if (JXL_DEC_SUCCESS !=
|
||||
JxlDecoderGetColorAsICCProfile(dec, &format,
|
||||
JXL_COLOR_PROFILE_TARGET_ORIGINAL,
|
||||
profile, profile_size)) {
|
||||
fprintf(stderr, "JxlDecoderGetColorAsICCProfile failed\n");
|
||||
free(profile);
|
||||
continue;
|
||||
}
|
||||
printf(" CMM type: \"%.4s\"\n", profile + 4);
|
||||
printf(" color space: \"%.4s\"\n", profile + 16);
|
||||
printf(" rendering intent: %d\n", (int)profile[67]);
|
||||
free(profile);
|
||||
}
|
||||
|
||||
} else if (status == JXL_DEC_FRAME) {
|
||||
if (JXL_DEC_SUCCESS != JxlDecoderGetFrameHeader(dec, &frame_header)) {
|
||||
fprintf(stderr, "JxlDecoderGetFrameHeader failed\n");
|
||||
break;
|
||||
}
|
||||
printf("frame:\n");
|
||||
if (frame_header.name_length) {
|
||||
char* name = malloc(frame_header.name_length + 1);
|
||||
if (JXL_DEC_SUCCESS !=
|
||||
JxlDecoderGetFrameName(dec, name, frame_header.name_length + 1)) {
|
||||
fprintf(stderr, "JxlDecoderGetFrameName failed\n");
|
||||
free(name);
|
||||
break;
|
||||
}
|
||||
free(name);
|
||||
printf(" name: %s\n", name);
|
||||
}
|
||||
float ms = frame_header.duration * 1000.f *
|
||||
info.animation.tps_denominator / info.animation.tps_numerator;
|
||||
if (info.have_animation) {
|
||||
printf(" duration: %u ticks (%f ms)\n", frame_header.duration, ms);
|
||||
if (info.animation.have_timecodes) {
|
||||
printf(" time code: %X\n", frame_header.timecode);
|
||||
}
|
||||
}
|
||||
if (!frame_header.name_length && !info.have_animation) {
|
||||
printf(" still frame, unnamed\n");
|
||||
}
|
||||
|
||||
// This is the last expected event, no need to read the rest of the file.
|
||||
} else {
|
||||
fprintf(stderr, "Unexpected decoder status\n");
|
||||
|
|
|
|||
0
third_party/jpeg-xl/js-wasm-wrapper.sh
vendored
Executable file → Normal file
0
third_party/jpeg-xl/js-wasm-wrapper.sh
vendored
Executable file → Normal file
8
third_party/jpeg-xl/lib/CMakeLists.txt
vendored
8
third_party/jpeg-xl/lib/CMakeLists.txt
vendored
|
|
@ -4,8 +4,8 @@
|
|||
# license that can be found in the LICENSE file.
|
||||
|
||||
set(JPEGXL_MAJOR_VERSION 0)
|
||||
set(JPEGXL_MINOR_VERSION 3)
|
||||
set(JPEGXL_PATCH_VERSION 7)
|
||||
set(JPEGXL_MINOR_VERSION 7)
|
||||
set(JPEGXL_PATCH_VERSION 0)
|
||||
set(JPEGXL_LIBRARY_VERSION
|
||||
"${JPEGXL_MAJOR_VERSION}.${JPEGXL_MINOR_VERSION}.${JPEGXL_PATCH_VERSION}")
|
||||
|
||||
|
|
@ -43,7 +43,6 @@ set(JPEGXL_INTERNAL_FLAGS
|
|||
# Warning flags supported by clang.
|
||||
if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||
list(APPEND JPEGXL_INTERNAL_FLAGS
|
||||
-Wc++2a-extensions
|
||||
-Wdeprecated-increment-bool
|
||||
# TODO(deymo): Add -Wextra-semi once we update third_party/highway.
|
||||
# -Wextra-semi
|
||||
|
|
@ -64,6 +63,9 @@ if (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
|||
-Wunreachable-code
|
||||
-Wunused-comparison
|
||||
)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0)
|
||||
list(APPEND HWY_FLAGS -Wc++2a-extensions)
|
||||
endif()
|
||||
endif() # Clang
|
||||
|
||||
if (WIN32)
|
||||
|
|
|
|||
64
third_party/jpeg-xl/lib/extras/codec.cc
vendored
64
third_party/jpeg-xl/lib/extras/codec.cc
vendored
|
|
@ -84,39 +84,45 @@ Codec CodecFromExtension(const std::string& extension,
|
|||
return Codec::kUnknown;
|
||||
}
|
||||
|
||||
Status SetFromBytes(const Span<const uint8_t> bytes, CodecInOut* io,
|
||||
Status SetFromBytes(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, CodecInOut* io,
|
||||
ThreadPool* pool, Codec* orig_codec) {
|
||||
if (bytes.size() < kMinBytes) return JXL_FAILURE("Too few bytes");
|
||||
|
||||
io->metadata.m.bit_depth.bits_per_sample = 0; // (For is-set check below)
|
||||
|
||||
Codec codec;
|
||||
if (DecodeImagePNG(bytes, pool, io)) {
|
||||
if (extras::DecodeImagePNG(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kPNG;
|
||||
}
|
||||
#if JPEGXL_ENABLE_APNG
|
||||
else if (DecodeImageAPNG(bytes, pool, io)) {
|
||||
else if (extras::DecodeImageAPNG(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kPNG;
|
||||
}
|
||||
#endif
|
||||
else if (DecodeImagePGX(bytes, pool, io)) {
|
||||
else if (extras::DecodeImagePGX(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kPGX;
|
||||
} else if (DecodeImagePNM(bytes, pool, io)) {
|
||||
} else if (extras::DecodeImagePNM(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kPNM;
|
||||
}
|
||||
#if JPEGXL_ENABLE_GIF
|
||||
else if (DecodeImageGIF(bytes, pool, io)) {
|
||||
else if (extras::DecodeImageGIF(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kGIF;
|
||||
}
|
||||
#endif
|
||||
else if (DecodeImageJPG(bytes, pool, io)) {
|
||||
else if (io->dec_target == DecodeTarget::kQuantizedCoeffs &&
|
||||
extras::DecodeImageJPGCoefficients(bytes, io)) {
|
||||
// TODO(deymo): In this case the tools should use a different API to
|
||||
// transcode the input JPEG to JXL.
|
||||
codec = Codec::kJPG;
|
||||
}
|
||||
else if (DecodeImagePSD(bytes, pool, io)) {
|
||||
} else if (io->dec_target == DecodeTarget::kPixels &&
|
||||
extras::DecodeImageJPG(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kJPG;
|
||||
} else if (extras::DecodeImagePSD(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kPSD;
|
||||
}
|
||||
#if JPEGXL_ENABLE_EXR
|
||||
else if (DecodeImageEXR(bytes, pool, io)) {
|
||||
else if (extras::DecodeImageEXR(bytes, color_hints, pool, io)) {
|
||||
codec = Codec::kEXR;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -129,12 +135,12 @@ Status SetFromBytes(const Span<const uint8_t> bytes, CodecInOut* io,
|
|||
return true;
|
||||
}
|
||||
|
||||
Status SetFromFile(const std::string& pathname, CodecInOut* io,
|
||||
ThreadPool* pool, Codec* orig_codec) {
|
||||
Status SetFromFile(const std::string& pathname, const ColorHints& color_hints,
|
||||
CodecInOut* io, ThreadPool* pool, Codec* orig_codec) {
|
||||
PaddedBytes encoded;
|
||||
JXL_RETURN_IF_ERROR(ReadFile(pathname, &encoded));
|
||||
JXL_RETURN_IF_ERROR(
|
||||
SetFromBytes(Span<const uint8_t>(encoded), io, pool, orig_codec));
|
||||
JXL_RETURN_IF_ERROR(SetFromBytes(Span<const uint8_t>(encoded), color_hints,
|
||||
io, pool, orig_codec));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -152,28 +158,36 @@ Status Encode(const CodecInOut& io, const Codec codec,
|
|||
|
||||
switch (codec) {
|
||||
case Codec::kPNG:
|
||||
return EncodeImagePNG(&io, c_desired, bits_per_sample, pool, bytes);
|
||||
return extras::EncodeImagePNG(&io, c_desired, bits_per_sample, pool,
|
||||
bytes);
|
||||
case Codec::kJPG:
|
||||
if (io.Main().IsJPEG()) {
|
||||
return extras::EncodeImageJPGCoefficients(&io, bytes);
|
||||
} else {
|
||||
#if JPEGXL_ENABLE_JPEG
|
||||
return EncodeImageJPG(
|
||||
&io, io.use_sjpeg ? JpegEncoder::kSJpeg : JpegEncoder::kLibJpeg,
|
||||
io.jpeg_quality, YCbCrChromaSubsampling(), pool, bytes,
|
||||
io.Main().IsJPEG() ? DecodeTarget::kQuantizedCoeffs
|
||||
: DecodeTarget::kPixels);
|
||||
return EncodeImageJPG(&io,
|
||||
io.use_sjpeg ? extras::JpegEncoder::kSJpeg
|
||||
: extras::JpegEncoder::kLibJpeg,
|
||||
io.jpeg_quality, YCbCrChromaSubsampling(), pool,
|
||||
bytes);
|
||||
#else
|
||||
return JXL_FAILURE("JPEG XL was built without JPEG support");
|
||||
return JXL_FAILURE("JPEG XL was built without JPEG support");
|
||||
#endif
|
||||
}
|
||||
case Codec::kPNM:
|
||||
return EncodeImagePNM(&io, c_desired, bits_per_sample, pool, bytes);
|
||||
return extras::EncodeImagePNM(&io, c_desired, bits_per_sample, pool,
|
||||
bytes);
|
||||
case Codec::kPGX:
|
||||
return EncodeImagePGX(&io, c_desired, bits_per_sample, pool, bytes);
|
||||
return extras::EncodeImagePGX(&io, c_desired, bits_per_sample, pool,
|
||||
bytes);
|
||||
case Codec::kGIF:
|
||||
return JXL_FAILURE("Encoding to GIF is not implemented");
|
||||
case Codec::kPSD:
|
||||
return EncodeImagePSD(&io, c_desired, bits_per_sample, pool, bytes);
|
||||
return extras::EncodeImagePSD(&io, c_desired, bits_per_sample, pool,
|
||||
bytes);
|
||||
case Codec::kEXR:
|
||||
#if JPEGXL_ENABLE_EXR
|
||||
return EncodeImageEXR(&io, c_desired, pool, bytes);
|
||||
return extras::EncodeImageEXR(&io, c_desired, pool, bytes);
|
||||
#else
|
||||
return JXL_FAILURE("JPEG XL was built without OpenEXR support");
|
||||
#endif
|
||||
|
|
|
|||
19
third_party/jpeg-xl/lib/extras/codec.h
vendored
19
third_party/jpeg-xl/lib/extras/codec.h
vendored
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/compiler_specific.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
|
|
@ -58,13 +59,21 @@ Codec CodecFromExtension(const std::string& extension,
|
|||
size_t* JXL_RESTRICT bits_per_sample);
|
||||
|
||||
// Decodes "bytes" and sets io->metadata.m.
|
||||
// dec_hints may specify the "color_space" (otherwise, defaults to sRGB).
|
||||
Status SetFromBytes(const Span<const uint8_t> bytes, CodecInOut* io,
|
||||
ThreadPool* pool = nullptr, Codec* orig_codec = nullptr);
|
||||
// color_space_hint may specify the color space, otherwise, defaults to sRGB.
|
||||
Status SetFromBytes(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, CodecInOut* io,
|
||||
ThreadPool* pool, Codec* orig_codec);
|
||||
// Helper function to use no color_space_hint.
|
||||
JXL_INLINE Status SetFromBytes(const Span<const uint8_t> bytes, CodecInOut* io,
|
||||
ThreadPool* pool = nullptr,
|
||||
Codec* orig_codec = nullptr) {
|
||||
return SetFromBytes(bytes, ColorHints(), io, pool, orig_codec);
|
||||
}
|
||||
|
||||
// Reads from file and calls SetFromBytes.
|
||||
Status SetFromFile(const std::string& pathname, CodecInOut* io,
|
||||
ThreadPool* pool = nullptr, Codec* orig_codec = nullptr);
|
||||
Status SetFromFile(const std::string& pathname, const ColorHints& color_hints,
|
||||
CodecInOut* io, ThreadPool* pool = nullptr,
|
||||
Codec* orig_codec = nullptr);
|
||||
|
||||
// Replaces "bytes" with an encoding of pixels transformed from c_current
|
||||
// color space to c_desired.
|
||||
|
|
|
|||
114
third_party/jpeg-xl/lib/extras/codec_apng.cc
vendored
114
third_party/jpeg-xl/lib/extras/codec_apng.cc
vendored
|
|
@ -39,14 +39,6 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif // NOMINMAX
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
|
@ -63,26 +55,45 @@
|
|||
#include "png.h" /* original (unpatched) libpng is ok */
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr bool isAbc(char c) {
|
||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||
}
|
||||
#define notabc(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
|
||||
|
||||
#define id_IHDR 0x52444849
|
||||
#define id_acTL 0x4C546361
|
||||
#define id_fcTL 0x4C546366
|
||||
#define id_IDAT 0x54414449
|
||||
#define id_fdAT 0x54416466
|
||||
#define id_IEND 0x444E4549
|
||||
constexpr uint32_t kId_IHDR = 0x52444849;
|
||||
constexpr uint32_t kId_acTL = 0x4C546361;
|
||||
constexpr uint32_t kId_fcTL = 0x4C546366;
|
||||
constexpr uint32_t kId_IDAT = 0x54414449;
|
||||
constexpr uint32_t kId_fdAT = 0x54416466;
|
||||
constexpr uint32_t kId_IEND = 0x444E4549;
|
||||
|
||||
struct CHUNK {
|
||||
unsigned char* p;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct APNGFrame {
|
||||
unsigned char *p, **rows;
|
||||
unsigned int w, h, delay_num, delay_den;
|
||||
};
|
||||
|
||||
struct Reader {
|
||||
const uint8_t* next;
|
||||
const uint8_t* last;
|
||||
bool Read(void* data, size_t len) {
|
||||
size_t cap = last - next;
|
||||
size_t to_copy = std::min(cap, len);
|
||||
memcpy(data, next, to_copy);
|
||||
next += to_copy;
|
||||
return (len == to_copy);
|
||||
}
|
||||
bool Eof() { return next == last; }
|
||||
};
|
||||
|
||||
const unsigned long cMaxPNGSize = 1000000UL;
|
||||
const size_t kMaxPNGChunkSize = 100000000; // 100 MB
|
||||
|
||||
|
|
@ -102,11 +113,11 @@ void row_fn(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num,
|
|||
png_progressive_combine_row(png_ptr, frame->rows[row_num], new_row);
|
||||
}
|
||||
|
||||
inline unsigned int read_chunk(FILE* f, CHUNK* pChunk) {
|
||||
inline unsigned int read_chunk(Reader* r, CHUNK* pChunk) {
|
||||
unsigned char len[4];
|
||||
pChunk->size = 0;
|
||||
pChunk->p = 0;
|
||||
if (fread(&len, 4, 1, f) == 1) {
|
||||
if (r->Read(&len, 4)) {
|
||||
const auto size = png_get_uint_32(len);
|
||||
// Check first, to avoid overflow.
|
||||
if (size > kMaxPNGChunkSize) {
|
||||
|
|
@ -116,8 +127,9 @@ inline unsigned int read_chunk(FILE* f, CHUNK* pChunk) {
|
|||
pChunk->size = size + 12;
|
||||
pChunk->p = new unsigned char[pChunk->size];
|
||||
memcpy(pChunk->p, len, 4);
|
||||
if (fread(pChunk->p + 4, pChunk->size - 4, 1, f) == 1)
|
||||
if (r->Read(pChunk->p + 4, pChunk->size - 4)) {
|
||||
return *(unsigned int*)(pChunk->p + 4);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -179,29 +191,11 @@ int processing_finish(png_structp png_ptr, png_infop info_ptr) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
FILE* fmemopen(void* buf, size_t size, const char* mode) {
|
||||
char temp[999];
|
||||
if (!GetTempPath(sizeof(temp), temp)) return nullptr;
|
||||
|
||||
char pathname[999];
|
||||
if (!GetTempFileName(temp, "jpegxl", 0, pathname)) return nullptr;
|
||||
|
||||
FILE* f = fopen(pathname, "wb");
|
||||
if (f == nullptr) return nullptr;
|
||||
fwrite(buf, 1, size, f);
|
||||
JXL_CHECK(fclose(f) == 0);
|
||||
|
||||
return fopen(pathname, mode);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
FILE* f;
|
||||
Status DecodeImageAPNG(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
ThreadPool* pool, CodecInOut* io) {
|
||||
Reader r;
|
||||
unsigned int id, i, j, w, h, w0, h0, x0, y0;
|
||||
unsigned int delay_num, delay_den, dop, bop, rowbytes, imagesize;
|
||||
unsigned char sig[8];
|
||||
|
|
@ -216,16 +210,13 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
bool all_dispose_bg = true;
|
||||
APNGFrame frameRaw = {};
|
||||
|
||||
if (!(f = fmemopen((void*)bytes.data(), bytes.size(), "rb"))) {
|
||||
return JXL_FAILURE("Failed to fmemopen");
|
||||
}
|
||||
r = {bytes.data(), bytes.data() + bytes.size()};
|
||||
// Not an aPNG => not an error
|
||||
unsigned char png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
if (fread(sig, 1, 8, f) != 8 || memcmp(sig, png_signature, 8) != 0) {
|
||||
fclose(f);
|
||||
if (!r.Read(sig, 8) || memcmp(sig, png_signature, 8) != 0) {
|
||||
return false;
|
||||
}
|
||||
id = read_chunk(f, &chunkIHDR);
|
||||
id = read_chunk(&r, &chunkIHDR);
|
||||
|
||||
io->frames.clear();
|
||||
io->dec_pixels = 0;
|
||||
|
|
@ -233,19 +224,15 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
io->metadata.m.SetAlphaBits(8);
|
||||
io->metadata.m.color_encoding =
|
||||
ColorEncoding::SRGB(); // todo: get data from png metadata
|
||||
(void)io->dec_hints.Foreach(
|
||||
[](const std::string& key, const std::string& /*value*/) {
|
||||
JXL_WARNING("APNG decoder ignoring %s hint", key.c_str());
|
||||
return true;
|
||||
});
|
||||
JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, /*color_already_set=*/true,
|
||||
/*is_gray=*/false, io));
|
||||
|
||||
bool errorstate = true;
|
||||
if (id == id_IHDR && chunkIHDR.size == 25) {
|
||||
if (id == kId_IHDR && chunkIHDR.size == 25) {
|
||||
w0 = w = png_get_uint_32(chunkIHDR.p + 8);
|
||||
h0 = h = png_get_uint_32(chunkIHDR.p + 12);
|
||||
|
||||
if (w > cMaxPNGSize || h > cMaxPNGSize) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -265,18 +252,18 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
if (!processing_start(png_ptr, info_ptr, (void*)&frameRaw, hasInfo,
|
||||
chunkIHDR, chunksInfo)) {
|
||||
bool last_base_was_none = true;
|
||||
while (!feof(f)) {
|
||||
id = read_chunk(f, &chunk);
|
||||
while (!r.Eof()) {
|
||||
id = read_chunk(&r, &chunk);
|
||||
if (!id) break;
|
||||
JXL_ASSERT(chunk.p != nullptr);
|
||||
|
||||
if (id == id_acTL && !hasInfo && !isAnimated) {
|
||||
if (id == kId_acTL && !hasInfo && !isAnimated) {
|
||||
isAnimated = true;
|
||||
skipFirst = true;
|
||||
io->metadata.m.have_animation = true;
|
||||
io->metadata.m.animation.tps_numerator = 1000;
|
||||
} else if (id == id_IEND ||
|
||||
(id == id_fcTL && (!hasInfo || isAnimated))) {
|
||||
} else if (id == kId_IEND ||
|
||||
(id == kId_fcTL && (!hasInfo || isAnimated))) {
|
||||
if (hasInfo) {
|
||||
if (!processing_finish(png_ptr, info_ptr)) {
|
||||
ImageBundle bundle(&io->metadata.m);
|
||||
|
|
@ -339,7 +326,7 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
}
|
||||
}
|
||||
|
||||
if (id == id_IEND) {
|
||||
if (id == kId_IEND) {
|
||||
errorstate = false;
|
||||
break;
|
||||
}
|
||||
|
|
@ -353,6 +340,8 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
dop = chunk.p[32];
|
||||
bop = chunk.p[33];
|
||||
|
||||
if (!delay_den) delay_den = 100;
|
||||
|
||||
if (w0 > cMaxPNGSize || h0 > cMaxPNGSize || x0 > cMaxPNGSize ||
|
||||
y0 > cMaxPNGSize || x0 + w0 > w || y0 + h0 > h || dop > 2 ||
|
||||
bop > 1) {
|
||||
|
|
@ -374,21 +363,21 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
bop = 0;
|
||||
if (dop == 2) dop = 1;
|
||||
}
|
||||
} else if (id == id_IDAT) {
|
||||
} else if (id == kId_IDAT) {
|
||||
hasInfo = true;
|
||||
if (processing_data(png_ptr, info_ptr, chunk.p, chunk.size)) {
|
||||
delete[] chunk.p;
|
||||
break;
|
||||
}
|
||||
} else if (id == id_fdAT && isAnimated) {
|
||||
} else if (id == kId_fdAT && isAnimated) {
|
||||
png_save_uint_32(chunk.p + 4, chunk.size - 16);
|
||||
memcpy(chunk.p + 8, "IDAT", 4);
|
||||
if (processing_data(png_ptr, info_ptr, chunk.p + 4, chunk.size - 4)) {
|
||||
delete[] chunk.p;
|
||||
break;
|
||||
}
|
||||
} else if (notabc(chunk.p[4]) || notabc(chunk.p[5]) ||
|
||||
notabc(chunk.p[6]) || notabc(chunk.p[7])) {
|
||||
} else if (!isAbc(chunk.p[4]) || !isAbc(chunk.p[5]) ||
|
||||
!isAbc(chunk.p[6]) || !isAbc(chunk.p[7])) {
|
||||
delete[] chunk.p;
|
||||
break;
|
||||
} else if (!hasInfo) {
|
||||
|
|
@ -411,11 +400,10 @@ Status DecodeImageAPNG(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
chunksInfo.clear();
|
||||
delete[] chunkIHDR.p;
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (errorstate) return false;
|
||||
SetIntensityTarget(io);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
8
third_party/jpeg-xl/lib/extras/codec_apng.h
vendored
8
third_party/jpeg-xl/lib/extras/codec_apng.h
vendored
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -17,11 +18,14 @@
|
|||
#include "lib/jxl/codec_in_out.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints are ignored.
|
||||
Status DecodeImageAPNG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
// Decodes `bytes` into `io`. color_space_hint is ignored.
|
||||
Status DecodeImageAPNG(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_APNG_H_
|
||||
|
|
|
|||
6
third_party/jpeg-xl/lib/extras/codec_exr.cc
vendored
6
third_party/jpeg-xl/lib/extras/codec_exr.cc
vendored
|
|
@ -17,6 +17,7 @@
|
|||
#include "lib/jxl/color_management.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
@ -127,8 +128,8 @@ class InMemoryOStream : public OpenEXR::OStream {
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImageEXR(Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
Status DecodeImageEXR(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
ThreadPool* pool, CodecInOut* io) {
|
||||
// Get the number of threads we should be using for OpenEXR.
|
||||
// OpenEXR creates its own set of threads, independent from ours. `pool` is
|
||||
// only used for converting from a buffer of OpenEXR::Rgba to Image3F.
|
||||
|
|
@ -347,4 +348,5 @@ Status EncodeImageEXR(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
return true;
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
9
third_party/jpeg-xl/lib/extras/codec_exr.h
vendored
9
third_party/jpeg-xl/lib/extras/codec_exr.h
vendored
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
// Encodes OpenEXR images in memory.
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -16,16 +17,18 @@
|
|||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints are ignored.
|
||||
Status DecodeImageEXR(Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
// Decodes `bytes` into `io`. color_hints are ignored.
|
||||
Status DecodeImageEXR(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
ThreadPool* pool, CodecInOut* io);
|
||||
|
||||
// Transforms from io->c_current to `c_desired` (with the transfer function set
|
||||
// to linear as that is the OpenEXR convention) and encodes into `bytes`.
|
||||
Status EncodeImageEXR(const CodecInOut* io, const ColorEncoding& c_desired,
|
||||
ThreadPool* pool, PaddedBytes* bytes);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_EXR_H_
|
||||
|
|
|
|||
60
third_party/jpeg-xl/lib/extras/codec_gif.cc
vendored
60
third_party/jpeg-xl/lib/extras/codec_gif.cc
vendored
|
|
@ -21,12 +21,10 @@
|
|||
#include "lib/jxl/image_bundle.h"
|
||||
#include "lib/jxl/image_ops.h"
|
||||
#include "lib/jxl/luminance.h"
|
||||
|
||||
#ifdef MEMORY_SANITIZER
|
||||
#include "sanitizer/msan_interface.h"
|
||||
#endif
|
||||
#include "lib/jxl/sanitizers.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
@ -55,8 +53,8 @@ bool AllOpaque(const ImageF& alpha) {
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
Status DecodeImageGIF(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
ThreadPool* pool, CodecInOut* io) {
|
||||
int error = GIF_OK;
|
||||
ReadState state = {bytes};
|
||||
const auto ReadFromSpan = [](GifFileType* const gif, GifByteType* const bytes,
|
||||
|
|
@ -84,16 +82,15 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return JXL_FAILURE("Failed to read GIF: %s", GifErrorString(gif->Error));
|
||||
}
|
||||
|
||||
#ifdef MEMORY_SANITIZER
|
||||
__msan_unpoison(gif.get(), sizeof(*gif));
|
||||
msan::UnpoisonMemory(gif.get(), sizeof(*gif));
|
||||
if (gif->SColorMap) {
|
||||
__msan_unpoison(gif->SColorMap, sizeof(*gif->SColorMap));
|
||||
__msan_unpoison(gif->SColorMap->Colors, sizeof(*gif->SColorMap->Colors) *
|
||||
gif->SColorMap->ColorCount);
|
||||
msan::UnpoisonMemory(gif->SColorMap, sizeof(*gif->SColorMap));
|
||||
msan::UnpoisonMemory(
|
||||
gif->SColorMap->Colors,
|
||||
sizeof(*gif->SColorMap->Colors) * gif->SColorMap->ColorCount);
|
||||
}
|
||||
__msan_unpoison(gif->SavedImages,
|
||||
sizeof(*gif->SavedImages) * gif->ImageCount);
|
||||
#endif
|
||||
msan::UnpoisonMemory(gif->SavedImages,
|
||||
sizeof(*gif->SavedImages) * gif->ImageCount);
|
||||
|
||||
const SizeConstraints* constraints = &io->constraints;
|
||||
|
||||
|
|
@ -135,24 +132,18 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
io->dec_pixels = 0;
|
||||
|
||||
io->metadata.m.SetUintSamples(8);
|
||||
io->metadata.m.color_encoding = ColorEncoding::SRGB();
|
||||
io->metadata.m.SetAlphaBits(0);
|
||||
(void)io->dec_hints.Foreach(
|
||||
[](const std::string& key, const std::string& /*value*/) {
|
||||
JXL_WARNING("GIF decoder ignoring %s hint", key.c_str());
|
||||
return true;
|
||||
});
|
||||
JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, /*color_already_set=*/false,
|
||||
/*is_gray=*/false, io));
|
||||
|
||||
Image3F canvas(gif->SWidth, gif->SHeight);
|
||||
io->SetSize(gif->SWidth, gif->SHeight);
|
||||
ImageF alpha(gif->SWidth, gif->SHeight);
|
||||
GifColorType background_color;
|
||||
if (gif->SColorMap == nullptr) {
|
||||
if (gif->SColorMap == nullptr ||
|
||||
gif->SBackGroundColor >= gif->SColorMap->ColorCount) {
|
||||
background_color = {0, 0, 0};
|
||||
} else {
|
||||
if (gif->SBackGroundColor >= gif->SColorMap->ColorCount) {
|
||||
return JXL_FAILURE("GIF specifies out-of-bounds background color");
|
||||
}
|
||||
background_color = gif->SColorMap->Colors[gif->SBackGroundColor];
|
||||
}
|
||||
FillPlane<float>(background_color.Red, &canvas.Plane(0));
|
||||
|
|
@ -167,11 +158,9 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
bool last_base_was_none = true;
|
||||
for (int i = 0; i < gif->ImageCount; ++i) {
|
||||
const SavedImage& image = gif->SavedImages[i];
|
||||
#ifdef MEMORY_SANITIZER
|
||||
__msan_unpoison(image.RasterBits, sizeof(*image.RasterBits) *
|
||||
image.ImageDesc.Width *
|
||||
image.ImageDesc.Height);
|
||||
#endif
|
||||
msan::UnpoisonMemory(image.RasterBits, sizeof(*image.RasterBits) *
|
||||
image.ImageDesc.Width *
|
||||
image.ImageDesc.Height);
|
||||
const Rect image_rect(image.ImageDesc.Left, image.ImageDesc.Top,
|
||||
image.ImageDesc.Width, image.ImageDesc.Height);
|
||||
io->dec_pixels += image_rect.xsize() * image_rect.ysize();
|
||||
|
|
@ -203,16 +192,12 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
const ColorMapObject* const color_map =
|
||||
image.ImageDesc.ColorMap ? image.ImageDesc.ColorMap : gif->SColorMap;
|
||||
JXL_CHECK(color_map);
|
||||
#ifdef MEMORY_SANITIZER
|
||||
__msan_unpoison(color_map, sizeof(*color_map));
|
||||
__msan_unpoison(color_map->Colors,
|
||||
sizeof(*color_map->Colors) * color_map->ColorCount);
|
||||
#endif
|
||||
msan::UnpoisonMemory(color_map, sizeof(*color_map));
|
||||
msan::UnpoisonMemory(color_map->Colors,
|
||||
sizeof(*color_map->Colors) * color_map->ColorCount);
|
||||
GraphicsControlBlock gcb;
|
||||
DGifSavedExtensionToGCB(gif.get(), i, &gcb);
|
||||
#ifdef MEMORY_SANITIZER
|
||||
__msan_unpoison(&gcb, sizeof(gcb));
|
||||
#endif
|
||||
msan::UnpoisonMemory(&gcb, sizeof(gcb));
|
||||
|
||||
ImageBundle bundle(&io->metadata.m);
|
||||
if (io->metadata.m.have_animation) {
|
||||
|
|
@ -350,4 +335,5 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return true;
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
8
third_party/jpeg-xl/lib/extras/codec_gif.h
vendored
8
third_party/jpeg-xl/lib/extras/codec_gif.h
vendored
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -17,11 +18,14 @@
|
|||
#include "lib/jxl/codec_in_out.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints are ignored.
|
||||
Status DecodeImageGIF(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
// Decodes `bytes` into `io`. color_hints are ignored.
|
||||
Status DecodeImageGIF(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_GIF_H_
|
||||
|
|
|
|||
112
third_party/jpeg-xl/lib/extras/codec_jpg.cc
vendored
112
third_party/jpeg-xl/lib/extras/codec_jpg.cc
vendored
|
|
@ -21,9 +21,9 @@
|
|||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "lib/extras/time.h"
|
||||
#include "lib/jxl/base/compiler_specific.h"
|
||||
#include "lib/jxl/base/status.h"
|
||||
#include "lib/jxl/base/time.h"
|
||||
#include "lib/jxl/color_encoding_internal.h"
|
||||
#include "lib/jxl/color_management.h"
|
||||
#include "lib/jxl/common.h"
|
||||
|
|
@ -34,15 +34,13 @@
|
|||
#include "lib/jxl/jpeg/enc_jpeg_data.h"
|
||||
#include "lib/jxl/jpeg/enc_jpeg_data_reader.h"
|
||||
#include "lib/jxl/luminance.h"
|
||||
#include "lib/jxl/sanitizers.h"
|
||||
#if JPEGXL_ENABLE_SJPEG
|
||||
#include "sjpeg.h"
|
||||
#endif
|
||||
|
||||
#ifdef MEMORY_SANITIZER
|
||||
#include "sanitizer/msan_interface.h"
|
||||
#endif
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
#if JPEGXL_ENABLE_JPEG
|
||||
namespace {
|
||||
|
|
@ -86,12 +84,10 @@ Status ReadICCProfile(jpeg_decompress_struct* const cinfo,
|
|||
bool has_num_markers = false;
|
||||
for (jpeg_saved_marker_ptr marker = cinfo->marker_list; marker != nullptr;
|
||||
marker = marker->next) {
|
||||
#ifdef MEMORY_SANITIZER
|
||||
// marker is initialized by libjpeg, which we are not instrumenting with
|
||||
// msan.
|
||||
__msan_unpoison(marker, sizeof(*marker));
|
||||
__msan_unpoison(marker->data, marker->data_length);
|
||||
#endif
|
||||
msan::UnpoisonMemory(marker, sizeof(*marker));
|
||||
msan::UnpoisonMemory(marker->data, marker->data_length);
|
||||
if (!MarkerIsICC(marker)) continue;
|
||||
|
||||
const int current_marker = marker->data[kICCSignatureSize];
|
||||
|
|
@ -157,12 +153,10 @@ void ReadExif(jpeg_decompress_struct* const cinfo, PaddedBytes* const exif) {
|
|||
constexpr size_t kExifSignatureSize = sizeof kExifSignature;
|
||||
for (jpeg_saved_marker_ptr marker = cinfo->marker_list; marker != nullptr;
|
||||
marker = marker->next) {
|
||||
#ifdef MEMORY_SANITIZER
|
||||
// marker is initialized by libjpeg, which we are not instrumenting with
|
||||
// msan.
|
||||
__msan_unpoison(marker, sizeof(*marker));
|
||||
__msan_unpoison(marker->data, marker->data_length);
|
||||
#endif
|
||||
msan::UnpoisonMemory(marker, sizeof(*marker));
|
||||
msan::UnpoisonMemory(marker->data, marker->data_length);
|
||||
if (!MarkerIsExif(marker)) continue;
|
||||
size_t marker_length = marker->data_length - kExifSignatureSize;
|
||||
exif->resize(marker_length);
|
||||
|
|
@ -242,17 +236,22 @@ void MyOutputMessage(j_common_ptr cinfo) {
|
|||
} // namespace
|
||||
#endif // JPEGXL_ENABLE_JPEG
|
||||
|
||||
Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImageJPGCoefficients(Span<const uint8_t> bytes, CodecInOut* io) {
|
||||
if (!IsJPG(bytes)) return false;
|
||||
// Use brunsli JPEG decoder to read quantized coefficients.
|
||||
if (!jpeg::DecodeImageJPG(bytes, io)) {
|
||||
fprintf(stderr, "Corrupt or CMYK JPEG.\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Status DecodeImageJPG(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io, double* const elapsed_deinterleave) {
|
||||
if (elapsed_deinterleave != nullptr) *elapsed_deinterleave = 0;
|
||||
// Don't do anything for non-JPEG files (no need to report an error)
|
||||
if (!IsJPG(bytes)) return false;
|
||||
const DecodeTarget target = io->dec_target;
|
||||
|
||||
// Use brunsli JPEG decoder to read quantized coefficients.
|
||||
if (target == DecodeTarget::kQuantizedCoeffs) {
|
||||
return jxl::jpeg::DecodeImageJPG(bytes, io);
|
||||
}
|
||||
|
||||
#if JPEGXL_ENABLE_JPEG
|
||||
// TODO(veluca): use JPEGData also for pixels?
|
||||
|
|
@ -267,11 +266,9 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
|
||||
const auto try_catch_block = [&]() -> bool {
|
||||
jpeg_decompress_struct cinfo;
|
||||
#ifdef MEMORY_SANITIZER
|
||||
// cinfo is initialized by libjpeg, which we are not instrumenting with
|
||||
// msan, therefore we need to initialize cinfo here.
|
||||
memset(&cinfo, 0, sizeof(cinfo));
|
||||
#endif
|
||||
msan::UnpoisonMemory(&cinfo, sizeof(cinfo));
|
||||
// Setup error handling in jpeg library so we can deal with broken jpegs in
|
||||
// the fuzzer.
|
||||
jpeg_error_mgr jerr;
|
||||
|
|
@ -290,17 +287,22 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
jpeg_save_markers(&cinfo, kICCMarker, 0xFFFF);
|
||||
jpeg_save_markers(&cinfo, kExifMarker, 0xFFFF);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
if (!VerifyDimensions(&io->constraints, cinfo.image_width,
|
||||
cinfo.image_height)) {
|
||||
const auto failure = [&cinfo](const char* str) -> Status {
|
||||
jpeg_abort_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return JXL_FAILURE("image too big");
|
||||
return JXL_FAILURE("%s", str);
|
||||
};
|
||||
if (!VerifyDimensions(&io->constraints, cinfo.image_width,
|
||||
cinfo.image_height)) {
|
||||
return failure("image too big");
|
||||
}
|
||||
// Might cause CPU-zip bomb.
|
||||
if (cinfo.arith_code) {
|
||||
return failure("arithmetic code JPEGs are not supported");
|
||||
}
|
||||
if (ReadICCProfile(&cinfo, &icc)) {
|
||||
if (!color_encoding.SetICC(std::move(icc))) {
|
||||
jpeg_abort_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return JXL_FAILURE("read an invalid ICC profile");
|
||||
return failure("read an invalid ICC profile");
|
||||
}
|
||||
} else {
|
||||
color_encoding = ColorEncoding::SRGB(cinfo.output_components == 1);
|
||||
|
|
@ -310,16 +312,11 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
io->metadata.m.color_encoding = color_encoding;
|
||||
int nbcomp = cinfo.num_components;
|
||||
if (nbcomp != 1 && nbcomp != 3) {
|
||||
jpeg_abort_decompress(&cinfo);
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return JXL_FAILURE("unsupported number of components (%d) in JPEG",
|
||||
cinfo.output_components);
|
||||
return failure("unsupported number of components in JPEG");
|
||||
}
|
||||
if (!ApplyColorHints(color_hints, /*color_already_set=*/true, false, io)) {
|
||||
return failure("ApplyColorHints failed");
|
||||
}
|
||||
(void)io->dec_hints.Foreach(
|
||||
[](const std::string& key, const std::string& /*value*/) {
|
||||
JXL_WARNING("JPEG decoder ignoring %s hint", key.c_str());
|
||||
return true;
|
||||
});
|
||||
|
||||
jpeg_start_decompress(&cinfo);
|
||||
JXL_ASSERT(cinfo.output_components == nbcomp);
|
||||
|
|
@ -328,10 +325,9 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
for (size_t y = 0; y < image.ysize(); ++y) {
|
||||
JSAMPROW rows[] = {row.get()};
|
||||
jpeg_read_scanlines(&cinfo, rows, 1);
|
||||
#ifdef MEMORY_SANITIZER
|
||||
__msan_unpoison(row.get(), sizeof(JSAMPLE) * cinfo.output_components *
|
||||
cinfo.image_width);
|
||||
#endif
|
||||
msan::UnpoisonMemory(
|
||||
row.get(),
|
||||
sizeof(JSAMPLE) * cinfo.output_components * cinfo.image_width);
|
||||
auto start = Now();
|
||||
float* const JXL_RESTRICT output_row[] = {
|
||||
image.PlaneRow(0, y), image.PlaneRow(1, y), image.PlaneRow(2, y)};
|
||||
|
|
@ -361,7 +357,7 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
};
|
||||
|
||||
return try_catch_block();
|
||||
#else // JPEGXL_ENABLE_JPEG
|
||||
#else // JPEGXL_ENABLE_JPEG
|
||||
return JXL_FAILURE("JPEG decoding not enabled at build time.");
|
||||
#endif // JPEGXL_ENABLE_JPEG
|
||||
}
|
||||
|
|
@ -372,11 +368,9 @@ Status EncodeWithLibJpeg(const ImageBundle* ib, const CodecInOut* io,
|
|||
const YCbCrChromaSubsampling& chroma_subsampling,
|
||||
PaddedBytes* bytes) {
|
||||
jpeg_compress_struct cinfo;
|
||||
#ifdef MEMORY_SANITIZER
|
||||
// cinfo is initialized by libjpeg, which we are not instrumenting with
|
||||
// msan.
|
||||
__msan_unpoison(&cinfo, sizeof(cinfo));
|
||||
#endif
|
||||
msan::UnpoisonMemory(&cinfo, sizeof(cinfo));
|
||||
jpeg_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
|
@ -427,11 +421,9 @@ Status EncodeWithLibJpeg(const ImageBundle* ib, const CodecInOut* io,
|
|||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
bytes->resize(size);
|
||||
#ifdef MEMORY_SANITIZER
|
||||
// Compressed image data is initialized by libjpeg, which we are not
|
||||
// instrumenting with msan.
|
||||
__msan_unpoison(buffer, size);
|
||||
#endif
|
||||
msan::UnpoisonMemory(buffer, size);
|
||||
std::copy_n(buffer, size, bytes->data());
|
||||
std::free(buffer);
|
||||
return true;
|
||||
|
|
@ -481,10 +473,17 @@ Status EncodeWithSJpeg(const ImageBundle* ib, size_t quality,
|
|||
}
|
||||
#endif // JPEGXL_ENABLE_JPEG
|
||||
|
||||
Status EncodeImageJPGCoefficients(const CodecInOut* io, PaddedBytes* bytes) {
|
||||
auto write = [&bytes](const uint8_t* buf, size_t len) {
|
||||
bytes->append(buf, buf + len);
|
||||
return len;
|
||||
};
|
||||
return jpeg::WriteJpeg(*io->Main().jpeg_data, write);
|
||||
}
|
||||
|
||||
Status EncodeImageJPG(const CodecInOut* io, JpegEncoder encoder, size_t quality,
|
||||
YCbCrChromaSubsampling chroma_subsampling,
|
||||
ThreadPool* pool, PaddedBytes* bytes,
|
||||
const DecodeTarget target) {
|
||||
ThreadPool* pool, PaddedBytes* bytes) {
|
||||
if (io->Main().HasAlpha()) {
|
||||
return JXL_FAILURE("alpha is not supported");
|
||||
}
|
||||
|
|
@ -492,14 +491,6 @@ Status EncodeImageJPG(const CodecInOut* io, JpegEncoder encoder, size_t quality,
|
|||
return JXL_FAILURE("please specify a 0-100 JPEG quality");
|
||||
}
|
||||
|
||||
if (target == DecodeTarget::kQuantizedCoeffs) {
|
||||
auto write = [&bytes](const uint8_t* buf, size_t len) {
|
||||
bytes->append(buf, buf + len);
|
||||
return len;
|
||||
};
|
||||
return jpeg::WriteJpeg(*io->Main().jpeg_data, write);
|
||||
}
|
||||
|
||||
#if JPEGXL_ENABLE_JPEG
|
||||
const ImageBundle* ib;
|
||||
ImageMetadata metadata = io->metadata.m;
|
||||
|
|
@ -521,9 +512,10 @@ Status EncodeImageJPG(const CodecInOut* io, JpegEncoder encoder, size_t quality,
|
|||
}
|
||||
|
||||
return true;
|
||||
#else // JPEGXL_ENABLE_JPEG
|
||||
#else // JPEGXL_ENABLE_JPEG
|
||||
return JXL_FAILURE("JPEG pixel encoding not enabled at build time");
|
||||
#endif // JPEGXL_ENABLE_JPEG
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
23
third_party/jpeg-xl/lib/extras/codec_jpg.h
vendored
23
third_party/jpeg-xl/lib/extras/codec_jpg.h
vendored
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "lib/extras/codec.h"
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
#include "lib/jxl/codec_in_out.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
enum class JpegEncoder {
|
||||
kLibJpeg,
|
||||
|
|
@ -30,18 +32,29 @@ static inline bool IsJPG(const Span<const uint8_t> bytes) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints are ignored.
|
||||
// Decodes `bytes` into `io`. color_hints are ignored.
|
||||
// `elapsed_deinterleave`, if non-null, will be set to the time (in seconds)
|
||||
// that it took to deinterleave the raw JSAMPLEs to planar floats.
|
||||
Status DecodeImageJPG(Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
CodecInOut* io, double* elapsed_deinterleave = nullptr);
|
||||
Status DecodeImageJPG(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
ThreadPool* pool, CodecInOut* io,
|
||||
double* elapsed_deinterleave = nullptr);
|
||||
|
||||
// Encodes into `bytes`.
|
||||
Status EncodeImageJPG(const CodecInOut* io, JpegEncoder encoder, size_t quality,
|
||||
YCbCrChromaSubsampling chroma_subsampling,
|
||||
ThreadPool* pool, PaddedBytes* bytes,
|
||||
DecodeTarget target = DecodeTarget::kPixels);
|
||||
ThreadPool* pool, PaddedBytes* bytes);
|
||||
|
||||
// Temporary wrappers to load the JPEG coefficients to a CodecInOut. This should
|
||||
// be replaced by calling the corresponding JPEG input and output functions on
|
||||
// the API.
|
||||
|
||||
// Decodes the JPEG image coefficients to a CodecIO for lossless recompression.
|
||||
Status DecodeImageJPGCoefficients(Span<const uint8_t> bytes, CodecInOut* io);
|
||||
|
||||
// Reconstructs the JPEG from the coefficients and metadata in CodecInOut.
|
||||
Status EncodeImageJPGCoefficients(const CodecInOut* io, PaddedBytes* bytes);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_JPG_H_
|
||||
|
|
|
|||
107
third_party/jpeg-xl/lib/extras/codec_pgx.cc
vendored
107
third_party/jpeg-xl/lib/extras/codec_pgx.cc
vendored
|
|
@ -27,6 +27,7 @@
|
|||
#include "lib/jxl/luminance.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
struct HeaderPGX {
|
||||
|
|
@ -171,46 +172,10 @@ Status EncodeHeader(const ImageBundle& ib, const size_t bits_per_sample,
|
|||
}
|
||||
|
||||
// Use ML (Big Endian), LM may not be well supported by all decoders.
|
||||
snprintf(header, kMaxHeaderSize, "PG ML + %zu %zu %zu\n%n", bits_per_sample,
|
||||
ib.xsize(), ib.ysize(), chars_written);
|
||||
return true;
|
||||
}
|
||||
|
||||
Status ApplyHints(CodecInOut* io) {
|
||||
bool got_color_space = false;
|
||||
|
||||
JXL_RETURN_IF_ERROR(io->dec_hints.Foreach(
|
||||
[io, &got_color_space](const std::string& key,
|
||||
const std::string& value) -> Status {
|
||||
ColorEncoding* c_original = &io->metadata.m.color_encoding;
|
||||
if (key == "color_space") {
|
||||
if (!ParseDescription(value, c_original) ||
|
||||
!c_original->CreateICC()) {
|
||||
return JXL_FAILURE("PGX: Failed to apply color_space");
|
||||
}
|
||||
|
||||
if (!io->metadata.m.color_encoding.IsGray()) {
|
||||
return JXL_FAILURE("PGX: color_space hint must be grayscale");
|
||||
}
|
||||
|
||||
got_color_space = true;
|
||||
} else if (key == "icc_pathname") {
|
||||
PaddedBytes icc;
|
||||
JXL_RETURN_IF_ERROR(ReadFile(value, &icc));
|
||||
JXL_RETURN_IF_ERROR(c_original->SetICC(std::move(icc)));
|
||||
got_color_space = true;
|
||||
} else {
|
||||
JXL_WARNING("PGX decoder ignoring %s hint", key.c_str());
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
if (!got_color_space) {
|
||||
JXL_WARNING("PGX: no color_space/icc_pathname given, assuming sRGB");
|
||||
JXL_RETURN_IF_ERROR(
|
||||
io->metadata.m.color_encoding.SetSRGB(ColorSpace::kGray));
|
||||
}
|
||||
|
||||
*chars_written = snprintf(header, kMaxHeaderSize, "PG ML + %zu %zu %zu\n",
|
||||
bits_per_sample, ib.xsize(), ib.ysize());
|
||||
JXL_RETURN_IF_ERROR(static_cast<unsigned int>(*chars_written) <
|
||||
kMaxHeaderSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +191,8 @@ Span<const uint8_t> MakeSpan(const char* str) {
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImagePGX(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePGX(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
Parser parser(bytes);
|
||||
HeaderPGX header = {};
|
||||
|
|
@ -238,7 +204,8 @@ Status DecodeImagePGX(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return JXL_FAILURE("PGX: bits_per_sample invalid");
|
||||
}
|
||||
|
||||
JXL_RETURN_IF_ERROR(ApplyHints(io));
|
||||
JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, /*color_already_set=*/false,
|
||||
/*is_gray=*/true, io));
|
||||
io->metadata.m.SetUintSamples(header.bits_per_sample);
|
||||
io->metadata.m.SetAlphaBits(0);
|
||||
io->dec_pixels = header.xsize * header.ysize;
|
||||
|
|
@ -256,7 +223,7 @@ Status DecodeImagePGX(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
/*alpha_is_premultiplied=*/false,
|
||||
io->metadata.m.bit_depth.bits_per_sample,
|
||||
header.big_endian ? JXL_BIG_ENDIAN : JXL_LITTLE_ENDIAN, flipped_y, pool,
|
||||
&ib));
|
||||
&ib, /*float_in=*/false));
|
||||
io->frames.push_back(std::move(ib));
|
||||
SetIntensityTarget(io);
|
||||
return true;
|
||||
|
|
@ -302,57 +269,5 @@ Status EncodeImagePGX(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
return true;
|
||||
}
|
||||
|
||||
void TestCodecPGX() {
|
||||
{
|
||||
std::string pgx = "PG ML + 8 2 3\npixels";
|
||||
|
||||
CodecInOut io;
|
||||
ThreadPool* pool = nullptr;
|
||||
|
||||
Status ok = DecodeImagePGX(MakeSpan(pgx.c_str()), pool, &io);
|
||||
JXL_CHECK(ok == true);
|
||||
|
||||
ScaleImage(255.f, io.Main().color());
|
||||
|
||||
JXL_CHECK(!io.metadata.m.bit_depth.floating_point_sample);
|
||||
JXL_CHECK(io.metadata.m.bit_depth.bits_per_sample == 8);
|
||||
JXL_CHECK(io.metadata.m.color_encoding.IsGray());
|
||||
JXL_CHECK(io.xsize() == 2);
|
||||
JXL_CHECK(io.ysize() == 3);
|
||||
float eps = 1e-5;
|
||||
ExpectNear<float>('p', io.Main().color()->Plane(0).Row(0)[0], eps);
|
||||
ExpectNear<float>('i', io.Main().color()->Plane(0).Row(0)[1], eps);
|
||||
ExpectNear<float>('x', io.Main().color()->Plane(0).Row(1)[0], eps);
|
||||
ExpectNear<float>('e', io.Main().color()->Plane(0).Row(1)[1], eps);
|
||||
ExpectNear<float>('l', io.Main().color()->Plane(0).Row(2)[0], eps);
|
||||
ExpectNear<float>('s', io.Main().color()->Plane(0).Row(2)[1], eps);
|
||||
}
|
||||
|
||||
{
|
||||
std::string pgx = "PG ML + 16 2 3\np_i_x_e_l_s_";
|
||||
|
||||
CodecInOut io;
|
||||
ThreadPool* pool = nullptr;
|
||||
|
||||
Status ok = DecodeImagePGX(MakeSpan(pgx.c_str()), pool, &io);
|
||||
JXL_CHECK(ok == true);
|
||||
|
||||
ScaleImage(255.f, io.Main().color());
|
||||
|
||||
JXL_CHECK(!io.metadata.m.bit_depth.floating_point_sample);
|
||||
JXL_CHECK(io.metadata.m.bit_depth.bits_per_sample == 16);
|
||||
JXL_CHECK(io.metadata.m.color_encoding.IsGray());
|
||||
JXL_CHECK(io.xsize() == 2);
|
||||
JXL_CHECK(io.ysize() == 3);
|
||||
float eps = 1e-7;
|
||||
const auto& plane = io.Main().color()->Plane(0);
|
||||
ExpectNear(256.0f * 'p' + '_', plane.Row(0)[0] * 257, eps);
|
||||
ExpectNear(256.0f * 'i' + '_', plane.Row(0)[1] * 257, eps);
|
||||
ExpectNear(256.0f * 'x' + '_', plane.Row(1)[0] * 257, eps);
|
||||
ExpectNear(256.0f * 'e' + '_', plane.Row(1)[1] * 257, eps);
|
||||
ExpectNear(256.0f * 'l' + '_', plane.Row(2)[0] * 257, eps);
|
||||
ExpectNear(256.0f * 's' + '_', plane.Row(2)[1] * 257, eps);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
10
third_party/jpeg-xl/lib/extras/codec_pgx.h
vendored
10
third_party/jpeg-xl/lib/extras/codec_pgx.h
vendored
|
|
@ -11,6 +11,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -19,10 +20,11 @@
|
|||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints may specify "color_space", which
|
||||
// defaults to sRGB.
|
||||
Status DecodeImagePGX(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
// Decodes `bytes` into `io`.
|
||||
Status DecodeImagePGX(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
// Transforms from io->c_current to `c_desired` and encodes into `bytes`.
|
||||
|
|
@ -30,7 +32,7 @@ Status EncodeImagePGX(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
size_t bits_per_sample, ThreadPool* pool,
|
||||
PaddedBytes* bytes);
|
||||
|
||||
void TestCodecPGX();
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_PGX_H_
|
||||
|
|
|
|||
74
third_party/jpeg-xl/lib/extras/codec_pgx_test.cc
vendored
Normal file
74
third_party/jpeg-xl/lib/extras/codec_pgx_test.cc
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "lib/extras/codec_pgx.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
Span<const uint8_t> MakeSpan(const char* str) {
|
||||
return Span<const uint8_t>(reinterpret_cast<const uint8_t*>(str),
|
||||
strlen(str));
|
||||
}
|
||||
|
||||
TEST(CodecPGXTest, Test8bits) {
|
||||
std::string pgx = "PG ML + 8 2 3\npixels";
|
||||
|
||||
CodecInOut io;
|
||||
ThreadPool* pool = nullptr;
|
||||
|
||||
EXPECT_TRUE(DecodeImagePGX(MakeSpan(pgx.c_str()), ColorHints(), pool, &io));
|
||||
|
||||
ScaleImage(255.f, io.Main().color());
|
||||
|
||||
EXPECT_FALSE(io.metadata.m.bit_depth.floating_point_sample);
|
||||
EXPECT_EQ(8u, io.metadata.m.bit_depth.bits_per_sample);
|
||||
EXPECT_TRUE(io.metadata.m.color_encoding.IsGray());
|
||||
EXPECT_EQ(2u, io.xsize());
|
||||
EXPECT_EQ(3u, io.ysize());
|
||||
|
||||
float eps = 1e-5;
|
||||
EXPECT_NEAR('p', io.Main().color()->Plane(0).Row(0)[0], eps);
|
||||
EXPECT_NEAR('i', io.Main().color()->Plane(0).Row(0)[1], eps);
|
||||
EXPECT_NEAR('x', io.Main().color()->Plane(0).Row(1)[0], eps);
|
||||
EXPECT_NEAR('e', io.Main().color()->Plane(0).Row(1)[1], eps);
|
||||
EXPECT_NEAR('l', io.Main().color()->Plane(0).Row(2)[0], eps);
|
||||
EXPECT_NEAR('s', io.Main().color()->Plane(0).Row(2)[1], eps);
|
||||
}
|
||||
|
||||
TEST(CodecPGXTest, Test16bits) {
|
||||
std::string pgx = "PG ML + 16 2 3\np_i_x_e_l_s_";
|
||||
|
||||
CodecInOut io;
|
||||
ThreadPool* pool = nullptr;
|
||||
|
||||
EXPECT_TRUE(DecodeImagePGX(MakeSpan(pgx.c_str()), ColorHints(), pool, &io));
|
||||
|
||||
ScaleImage(255.f, io.Main().color());
|
||||
|
||||
EXPECT_FALSE(io.metadata.m.bit_depth.floating_point_sample);
|
||||
EXPECT_EQ(16u, io.metadata.m.bit_depth.bits_per_sample);
|
||||
EXPECT_TRUE(io.metadata.m.color_encoding.IsGray());
|
||||
EXPECT_EQ(2u, io.xsize());
|
||||
EXPECT_EQ(3u, io.ysize());
|
||||
|
||||
float eps = 1e-7;
|
||||
const auto& plane = io.Main().color()->Plane(0);
|
||||
EXPECT_NEAR(256.0f * 'p' + '_', plane.Row(0)[0] * 257, eps);
|
||||
EXPECT_NEAR(256.0f * 'i' + '_', plane.Row(0)[1] * 257, eps);
|
||||
EXPECT_NEAR(256.0f * 'x' + '_', plane.Row(1)[0] * 257, eps);
|
||||
EXPECT_NEAR(256.0f * 'e' + '_', plane.Row(1)[1] * 257, eps);
|
||||
EXPECT_NEAR(256.0f * 'l' + '_', plane.Row(2)[0] * 257, eps);
|
||||
EXPECT_NEAR(256.0f * 's' + '_', plane.Row(2)[1] * 257, eps);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
145
third_party/jpeg-xl/lib/extras/codec_png.cc
vendored
145
third_party/jpeg-xl/lib/extras/codec_png.cc
vendored
|
|
@ -31,6 +31,7 @@
|
|||
#include "lib/jxl/luminance.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
#define JXL_PNG_VERBOSE 0
|
||||
|
|
@ -123,17 +124,40 @@ class BlobsReaderPNG {
|
|||
if (type->length() > kMaxTypeLen) return false; // Type too long
|
||||
|
||||
// Header: freeform string and number of bytes
|
||||
// Expected format is:
|
||||
// \n
|
||||
// profile name/description\n
|
||||
// 40\n (the number of bytes after hex-decoding)
|
||||
// 01234566789abcdef....\n (72 bytes per line max).
|
||||
// 012345667\n (last line)
|
||||
const char* pos = encoded;
|
||||
|
||||
if (*(pos++) != '\n') return false;
|
||||
while (pos < encoded_end && *pos != '\n') {
|
||||
pos++;
|
||||
}
|
||||
if (pos == encoded_end) return false;
|
||||
// We parsed so far a \n, some number of non \n characters and are now
|
||||
// pointing at a \n.
|
||||
if (*(pos++) != '\n') return false;
|
||||
unsigned long bytes_to_decode;
|
||||
int header_len;
|
||||
std::vector<char> description((encoded_end - encoded) + 1);
|
||||
const int fields = sscanf(encoded, "\n%[^\n]\n%8lu%n", description.data(),
|
||||
&bytes_to_decode, &header_len);
|
||||
if (fields != 2) return false; // Failed to decode metadata header
|
||||
const int fields = sscanf(pos, "%8lu", &bytes_to_decode);
|
||||
if (fields != 1) return false; // Failed to decode metadata header
|
||||
JXL_ASSERT(pos + 8 <= encoded_end);
|
||||
pos += 8; // read %8lu
|
||||
|
||||
// We need 2*bytes for the hex values plus 1 byte every 36 values.
|
||||
const unsigned long needed_bytes =
|
||||
bytes_to_decode * 2 + 1 + DivCeil(bytes_to_decode, 36);
|
||||
if (needed_bytes != static_cast<size_t>(encoded_end - pos)) {
|
||||
return JXL_FAILURE("Not enough bytes to parse %lu bytes in hex",
|
||||
bytes_to_decode);
|
||||
}
|
||||
JXL_ASSERT(bytes->empty());
|
||||
bytes->reserve(bytes_to_decode);
|
||||
|
||||
// Encoding: base16 with newline after 72 chars.
|
||||
const char* pos = encoded + header_len;
|
||||
// pos points to the \n before the first line of hex values.
|
||||
for (size_t i = 0; i < bytes_to_decode; ++i) {
|
||||
if (i % 36 == 0) {
|
||||
if (pos + 1 >= encoded_end) return false; // Truncated base16 1
|
||||
|
|
@ -348,6 +372,7 @@ class ColorEncodingReaderPNG {
|
|||
Status DecodeSRGB(const unsigned char* payload, const size_t payload_size) {
|
||||
if (payload_size != 1) return JXL_FAILURE("Wrong sRGB size");
|
||||
// (PNG uses the same values as ICC.)
|
||||
if (payload[0] >= 4) return JXL_FAILURE("Invalid Rendering Intent");
|
||||
rendering_intent_ = static_cast<RenderingIntent>(payload[0]);
|
||||
have_srgb_ = true;
|
||||
return true;
|
||||
|
|
@ -462,45 +487,6 @@ class ColorEncodingReaderPNG {
|
|||
PrimariesCIExy primaries_;
|
||||
};
|
||||
|
||||
Status ApplyHints(const bool is_gray, CodecInOut* io) {
|
||||
bool got_color_space = false;
|
||||
|
||||
JXL_RETURN_IF_ERROR(io->dec_hints.Foreach(
|
||||
[is_gray, io, &got_color_space](const std::string& key,
|
||||
const std::string& value) -> Status {
|
||||
ColorEncoding* c_original = &io->metadata.m.color_encoding;
|
||||
if (key == "color_space") {
|
||||
if (!ParseDescription(value, c_original) ||
|
||||
!c_original->CreateICC()) {
|
||||
return JXL_FAILURE("PNG: Failed to apply color_space");
|
||||
}
|
||||
|
||||
if (is_gray != io->metadata.m.color_encoding.IsGray()) {
|
||||
return JXL_FAILURE(
|
||||
"PNG: mismatch between file and color_space hint");
|
||||
}
|
||||
|
||||
got_color_space = true;
|
||||
} else if (key == "icc_pathname") {
|
||||
PaddedBytes icc;
|
||||
JXL_RETURN_IF_ERROR(ReadFile(value, &icc));
|
||||
JXL_RETURN_IF_ERROR(c_original->SetICC(std::move(icc)));
|
||||
got_color_space = true;
|
||||
} else {
|
||||
JXL_WARNING("PNG decoder ignoring %s hint", key.c_str());
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
if (!got_color_space) {
|
||||
JXL_WARNING("PNG: no color_space/icc_pathname given, assuming sRGB");
|
||||
JXL_RETURN_IF_ERROR(io->metadata.m.color_encoding.SetSRGB(
|
||||
is_gray ? ColorSpace::kGray : ColorSpace::kRGB));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Stores ColorEncoding into PNG chunks.
|
||||
class ColorEncodingWriterPNG {
|
||||
public:
|
||||
|
|
@ -509,7 +495,9 @@ class ColorEncodingWriterPNG {
|
|||
if (c.IsSRGB()) {
|
||||
JXL_RETURN_IF_ERROR(AddSRGB(c, info));
|
||||
// PNG recommends not including both sRGB and iCCP, so skip the latter.
|
||||
} else {
|
||||
} else if (!c.HaveFields() || !c.tf.IsGamma()) {
|
||||
// Having a gamma value means that the source was a PNG with gAMA and
|
||||
// without iCCP.
|
||||
JXL_ASSERT(!c.ICC().empty());
|
||||
JXL_RETURN_IF_ERROR(AddICC(c.ICC(), info));
|
||||
}
|
||||
|
|
@ -568,8 +556,16 @@ class ColorEncodingWriterPNG {
|
|||
|
||||
static Status MaybeAddGAMA(const ColorEncoding& c,
|
||||
LodePNGInfo* JXL_RESTRICT info) {
|
||||
if (!c.tf.IsGamma()) return true;
|
||||
const double gamma = c.tf.GetGamma();
|
||||
double gamma;
|
||||
if (c.tf.IsGamma()) {
|
||||
gamma = c.tf.GetGamma();
|
||||
} else if (c.tf.IsLinear()) {
|
||||
gamma = 1;
|
||||
} else if (c.tf.IsSRGB()) {
|
||||
gamma = 0.45455;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
PaddedBytes payload(4);
|
||||
StoreBE32(U32FromF64(gamma), payload.data());
|
||||
|
|
@ -578,21 +574,31 @@ class ColorEncodingWriterPNG {
|
|||
|
||||
static Status MaybeAddCHRM(const ColorEncoding& c,
|
||||
LodePNGInfo* JXL_RESTRICT info) {
|
||||
// TODO(lode): remove this, PNG can also have cHRM for P3, sRGB, ...
|
||||
if (c.white_point != WhitePoint::kCustom &&
|
||||
c.primaries != Primaries::kCustom) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const CIExy white_point = c.GetWhitePoint();
|
||||
CIExy white_point = c.GetWhitePoint();
|
||||
// A PNG image stores both whitepoint and primaries in the cHRM chunk, but
|
||||
// for grayscale images we don't have primaries. It does not matter what
|
||||
// values are stored in the PNG though (all colors are a multiple of the
|
||||
// whitepoint), so choose default ones. See
|
||||
// http://www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html section 4.2.2.1.
|
||||
const PrimariesCIExy primaries =
|
||||
PrimariesCIExy primaries =
|
||||
c.IsGray() ? ColorEncoding().GetPrimaries() : c.GetPrimaries();
|
||||
|
||||
if (c.primaries == Primaries::kSRGB && c.white_point == WhitePoint::kD65) {
|
||||
// For sRGB, the cHRM chunk is supposed to have very specific values which
|
||||
// don't quite match the pre-quantized ones we have (red is off by
|
||||
// 0.00010). Technically, this is only required for full sRGB, but for
|
||||
// consistency, we might as well use them whenever the primaries and white
|
||||
// point are sRGB's.
|
||||
white_point.x = 0.31270;
|
||||
white_point.y = 0.32900;
|
||||
primaries.r.x = 0.64000;
|
||||
primaries.r.y = 0.33000;
|
||||
primaries.g.x = 0.30000;
|
||||
primaries.g.y = 0.60000;
|
||||
primaries.b.x = 0.15000;
|
||||
primaries.b.y = 0.06000;
|
||||
}
|
||||
|
||||
PaddedBytes payload(32);
|
||||
StoreBE32(U32FromF64(white_point.x), &payload[0]);
|
||||
StoreBE32(U32FromF64(white_point.y), &payload[4]);
|
||||
|
|
@ -629,7 +635,7 @@ Status CheckGray(const LodePNGColorMode& mode, bool has_icc, bool* is_gray) {
|
|||
case LCT_PALETTE: {
|
||||
if (has_icc) {
|
||||
// If an ICC profile is present, the PNG specification requires
|
||||
// palette to be intepreted as RGB colored, not grayscale, so we must
|
||||
// palette to be interpreted as RGB colored, not grayscale, so we must
|
||||
// output color in that case and unfortunately can't optimize it to
|
||||
// gray if the palette only has gray entries.
|
||||
*is_gray = false;
|
||||
|
|
@ -711,7 +717,8 @@ Status InspectChunkType(const Span<const uint8_t> bytes,
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImagePNG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePNG(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
unsigned w, h;
|
||||
PNGState state;
|
||||
|
|
@ -773,25 +780,18 @@ Status DecodeImagePNG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
|
||||
const JxlEndianness endianness = JXL_BIG_ENDIAN; // PNG requirement
|
||||
const Span<const uint8_t> span(out, out_size);
|
||||
const bool ok =
|
||||
ConvertFromExternal(span, w, h, io->metadata.m.color_encoding, has_alpha,
|
||||
/*alpha_is_premultiplied=*/false,
|
||||
io->metadata.m.bit_depth.bits_per_sample, endianness,
|
||||
/*flipped_y=*/false, pool, &io->Main());
|
||||
const bool ok = ConvertFromExternal(
|
||||
span, w, h, io->metadata.m.color_encoding, has_alpha,
|
||||
/*alpha_is_premultiplied=*/false,
|
||||
io->metadata.m.bit_depth.bits_per_sample, endianness,
|
||||
/*flipped_y=*/false, pool, &io->Main(), /*float_in=*/false);
|
||||
JXL_RETURN_IF_ERROR(ok);
|
||||
io->dec_pixels = w * h;
|
||||
io->metadata.m.bit_depth.bits_per_sample = io->Main().DetectRealBitdepth();
|
||||
io->metadata.m.xyb_encoded = false;
|
||||
SetIntensityTarget(io);
|
||||
if (!reader.HaveColorProfile()) {
|
||||
JXL_RETURN_IF_ERROR(ApplyHints(is_gray, io));
|
||||
} else {
|
||||
(void)io->dec_hints.Foreach(
|
||||
[](const std::string& key, const std::string& /*value*/) {
|
||||
JXL_WARNING("PNG decoder ignoring %s hint", key.c_str());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
JXL_RETURN_IF_ERROR(
|
||||
ApplyColorHints(color_hints, reader.HaveColorProfile(), is_gray, io));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -848,4 +848,5 @@ Status EncodeImagePNG(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
return true;
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
8
third_party/jpeg-xl/lib/extras/codec_png.h
vendored
8
third_party/jpeg-xl/lib/extras/codec_png.h
vendored
|
|
@ -14,6 +14,7 @@
|
|||
// TODO(janwas): workaround for incorrect Win64 codegen (cause unknown)
|
||||
#include <hwy/highway.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -22,9 +23,11 @@
|
|||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints are ignored.
|
||||
Status DecodeImagePNG(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
// Decodes `bytes` into `io`.
|
||||
Status DecodeImagePNG(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
// Transforms from io->c_current to `c_desired` and encodes into `bytes`.
|
||||
|
|
@ -32,6 +35,7 @@ Status EncodeImagePNG(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
size_t bits_per_sample, ThreadPool* pool,
|
||||
PaddedBytes* bytes);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_PNG_H_
|
||||
|
|
|
|||
87
third_party/jpeg-xl/lib/extras/codec_pnm.cc
vendored
87
third_party/jpeg-xl/lib/extras/codec_pnm.cc
vendored
|
|
@ -18,6 +18,7 @@
|
|||
#include "lib/jxl/base/byte_order.h"
|
||||
#include "lib/jxl/base/compiler_specific.h"
|
||||
#include "lib/jxl/base/file_io.h"
|
||||
#include "lib/jxl/base/status.h"
|
||||
#include "lib/jxl/color_management.h"
|
||||
#include "lib/jxl/dec_external_image.h"
|
||||
#include "lib/jxl/enc_external_image.h"
|
||||
|
|
@ -28,6 +29,7 @@
|
|||
#include "lib/jxl/luminance.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
struct HeaderPNM {
|
||||
|
|
@ -69,6 +71,8 @@ class Parser {
|
|||
header->is_gray = false;
|
||||
return ParseHeaderPNM(header, pos);
|
||||
|
||||
// TODO(jon): P7 (PAM)
|
||||
|
||||
case 'F':
|
||||
header->is_gray = false;
|
||||
return ParseHeaderPFM(header, pos);
|
||||
|
|
@ -179,6 +183,18 @@ class Parser {
|
|||
return true;
|
||||
}
|
||||
|
||||
Status ReadChar(char* out) {
|
||||
// Unlikely to happen.
|
||||
if (pos_ + 1 < pos_) return JXL_FAILURE("Y4M: overflow");
|
||||
|
||||
if (pos_ >= end_) {
|
||||
return JXL_FAILURE("Y4M: unexpected end of input");
|
||||
}
|
||||
*out = *pos_;
|
||||
pos_++;
|
||||
return true;
|
||||
}
|
||||
|
||||
Status ParseHeaderPNM(HeaderPNM* header, const uint8_t** pos) {
|
||||
JXL_RETURN_IF_ERROR(SkipWhitespace());
|
||||
JXL_RETURN_IF_ERROR(ParseUnsigned(&header->xsize));
|
||||
|
|
@ -240,63 +256,32 @@ Status EncodeHeader(const ImageBundle& ib, const size_t bits_per_sample,
|
|||
if (bits_per_sample == 32) { // PFM
|
||||
const char type = ib.IsGray() ? 'f' : 'F';
|
||||
const double scale = little_endian ? -1.0 : 1.0;
|
||||
snprintf(header, kMaxHeaderSize, "P%c\n%zu %zu\n%.1f\n%n", type,
|
||||
ib.oriented_xsize(), ib.oriented_ysize(), scale, chars_written);
|
||||
*chars_written =
|
||||
snprintf(header, kMaxHeaderSize, "P%c\n%zu %zu\n%.1f\n", type,
|
||||
ib.oriented_xsize(), ib.oriented_ysize(), scale);
|
||||
JXL_RETURN_IF_ERROR(static_cast<unsigned int>(*chars_written) <
|
||||
kMaxHeaderSize);
|
||||
} else if (bits_per_sample == 1) { // PBM
|
||||
if (!ib.IsGray()) {
|
||||
return JXL_FAILURE("Cannot encode color as PBM");
|
||||
}
|
||||
snprintf(header, kMaxHeaderSize, "P4\n%zu %zu\n%n", ib.oriented_xsize(),
|
||||
ib.oriented_ysize(), chars_written);
|
||||
*chars_written = snprintf(header, kMaxHeaderSize, "P4\n%zu %zu\n",
|
||||
ib.oriented_xsize(), ib.oriented_ysize());
|
||||
JXL_RETURN_IF_ERROR(static_cast<unsigned int>(*chars_written) <
|
||||
kMaxHeaderSize);
|
||||
} else { // PGM/PPM
|
||||
const uint32_t max_val = (1U << bits_per_sample) - 1;
|
||||
if (max_val >= 65536) return JXL_FAILURE("PNM cannot have > 16 bits");
|
||||
const char type = ib.IsGray() ? '5' : '6';
|
||||
snprintf(header, kMaxHeaderSize, "P%c\n%zu %zu\n%u\n%n", type,
|
||||
ib.oriented_xsize(), ib.oriented_ysize(), max_val, chars_written);
|
||||
*chars_written =
|
||||
snprintf(header, kMaxHeaderSize, "P%c\n%zu %zu\n%u\n", type,
|
||||
ib.oriented_xsize(), ib.oriented_ysize(), max_val);
|
||||
JXL_RETURN_IF_ERROR(static_cast<unsigned int>(*chars_written) <
|
||||
kMaxHeaderSize);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Status ApplyHints(const bool is_gray, CodecInOut* io) {
|
||||
bool got_color_space = false;
|
||||
|
||||
JXL_RETURN_IF_ERROR(io->dec_hints.Foreach(
|
||||
[is_gray, io, &got_color_space](const std::string& key,
|
||||
const std::string& value) -> Status {
|
||||
ColorEncoding* c_original = &io->metadata.m.color_encoding;
|
||||
if (key == "color_space") {
|
||||
if (!ParseDescription(value, c_original) ||
|
||||
!c_original->CreateICC()) {
|
||||
return JXL_FAILURE("PNM: Failed to apply color_space");
|
||||
}
|
||||
|
||||
if (is_gray != io->metadata.m.color_encoding.IsGray()) {
|
||||
return JXL_FAILURE(
|
||||
"PNM: mismatch between file and color_space hint");
|
||||
}
|
||||
|
||||
got_color_space = true;
|
||||
} else if (key == "icc_pathname") {
|
||||
PaddedBytes icc;
|
||||
JXL_RETURN_IF_ERROR(ReadFile(value, &icc));
|
||||
JXL_RETURN_IF_ERROR(c_original->SetICC(std::move(icc)));
|
||||
got_color_space = true;
|
||||
} else {
|
||||
JXL_WARNING("PNM decoder ignoring %s hint", key.c_str());
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
if (!got_color_space) {
|
||||
JXL_WARNING("PNM: no color_space/icc_pathname given, assuming sRGB");
|
||||
JXL_RETURN_IF_ERROR(io->metadata.m.color_encoding.SetSRGB(
|
||||
is_gray ? ColorSpace::kGray : ColorSpace::kRGB));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Span<const uint8_t> MakeSpan(const char* str) {
|
||||
return Span<const uint8_t>(reinterpret_cast<const uint8_t*>(str),
|
||||
strlen(str));
|
||||
|
|
@ -320,7 +305,8 @@ void VerticallyFlipImage(Image3F* const image) {
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImagePNM(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePNM(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
Parser parser(bytes);
|
||||
HeaderPNM header = {};
|
||||
|
|
@ -333,7 +319,9 @@ Status DecodeImagePNM(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return JXL_FAILURE("PNM: bits_per_sample invalid");
|
||||
}
|
||||
|
||||
JXL_RETURN_IF_ERROR(ApplyHints(header.is_gray, io));
|
||||
JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, /*color_already_set=*/false,
|
||||
header.is_gray, io));
|
||||
|
||||
if (header.floating_point) {
|
||||
io->metadata.m.SetFloat32Samples();
|
||||
} else {
|
||||
|
|
@ -343,13 +331,15 @@ Status DecodeImagePNM(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
io->dec_pixels = header.xsize * header.ysize;
|
||||
|
||||
const bool flipped_y = header.bits_per_sample == 32; // PFMs are flipped
|
||||
const bool float_in = header.bits_per_sample == 32;
|
||||
const Span<const uint8_t> span(pos, bytes.data() + bytes.size() - pos);
|
||||
JXL_RETURN_IF_ERROR(ConvertFromExternal(
|
||||
span, header.xsize, header.ysize, io->metadata.m.color_encoding,
|
||||
/*has_alpha=*/false, /*alpha_is_premultiplied=*/false,
|
||||
io->metadata.m.bit_depth.bits_per_sample,
|
||||
header.big_endian ? JXL_BIG_ENDIAN : JXL_LITTLE_ENDIAN, flipped_y, pool,
|
||||
&io->Main()));
|
||||
&io->Main(), float_in));
|
||||
|
||||
if (!header.floating_point) {
|
||||
io->metadata.m.bit_depth.bits_per_sample = io->Main().DetectRealBitdepth();
|
||||
}
|
||||
|
|
@ -450,4 +440,5 @@ void TestCodecPNM() {
|
|||
JXL_CHECK(std::abs(d - -3.141592) < 1E-15);
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
8
third_party/jpeg-xl/lib/extras/codec_pnm.h
vendored
8
third_party/jpeg-xl/lib/extras/codec_pnm.h
vendored
|
|
@ -14,6 +14,7 @@
|
|||
// TODO(janwas): workaround for incorrect Win64 codegen (cause unknown)
|
||||
#include <hwy/highway.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
|
|
@ -22,10 +23,12 @@
|
|||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`. io->dec_hints may specify "color_space", which
|
||||
// Decodes `bytes` into `io`. color_hints may specify "color_space", which
|
||||
// defaults to sRGB.
|
||||
Status DecodeImagePNM(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePNM(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
// Transforms from io->c_current to `c_desired` and encodes into `bytes`.
|
||||
|
|
@ -35,6 +38,7 @@ Status EncodeImagePNM(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
|
||||
void TestCodecPNM();
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_PNM_H_
|
||||
|
|
|
|||
25
third_party/jpeg-xl/lib/extras/codec_psd.cc
vendored
25
third_party/jpeg-xl/lib/extras/codec_psd.cc
vendored
|
|
@ -28,6 +28,7 @@
|
|||
#include "lib/jxl/luminance.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
uint64_t get_be_int(int bytes, const uint8_t*& pos, const uint8_t* maxpos) {
|
||||
|
|
@ -187,7 +188,8 @@ Status decode_layer(const uint8_t*& pos, const uint8_t* maxpos,
|
|||
|
||||
} // namespace
|
||||
|
||||
Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePSD(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io) {
|
||||
const uint8_t* pos = bytes.data();
|
||||
const uint8_t* maxpos = bytes.data() + bytes.size();
|
||||
|
|
@ -229,6 +231,7 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
bool hasmergeddata = true;
|
||||
bool have_alpha = false;
|
||||
bool merged_has_alpha = false;
|
||||
bool color_already_set = false;
|
||||
size_t metalength = get_be_int(4, pos, maxpos);
|
||||
const uint8_t* metaoffset = pos;
|
||||
while (pos < metaoffset + metalength) {
|
||||
|
|
@ -257,6 +260,7 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
if (!io->metadata.m.color_encoding.SetICC(std::move(icc))) {
|
||||
return JXL_FAILURE("PSD: Invalid color profile");
|
||||
}
|
||||
color_already_set = true;
|
||||
} else if (id == 1057) { // compatibility mode or not?
|
||||
if (get_be_int(4, pos, maxpos) != 1) {
|
||||
return JXL_FAILURE("PSD: expected version=1 in id=1057 resource block");
|
||||
|
|
@ -310,6 +314,9 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
if (blocklength & 1) pos++; // padding again
|
||||
}
|
||||
|
||||
JXL_RETURN_IF_ERROR(ApplyColorHints(color_hints, color_already_set,
|
||||
/*is_gray=*/false, io));
|
||||
|
||||
size_t layerlength = get_be_int(4 * version, pos, maxpos);
|
||||
const uint8_t* after_layers_pos = pos + layerlength;
|
||||
if (after_layers_pos < pos) return JXL_FAILURE("PSD: invalid layer length");
|
||||
|
|
@ -349,6 +356,7 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return JXL_FAILURE("PSD: Invalid layer count");
|
||||
}
|
||||
JXL_DEBUG_V(PSD_VERBOSITY, "Real layer count: %i", layercount);
|
||||
if (layercount > 1) have_alpha = true;
|
||||
break;
|
||||
}
|
||||
if (!safe_strncmp(tpos, maxpos, "Mtrn", 4) ||
|
||||
|
|
@ -356,7 +364,6 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
!safe_strncmp(tpos, maxpos, "Mt32", 4)) {
|
||||
JXL_DEBUG_V(PSD_VERBOSITY, "Merged layer has transparency channel");
|
||||
if (nb_channels > real_nb_channels) {
|
||||
real_nb_channels++;
|
||||
have_alpha = true;
|
||||
merged_has_alpha = true;
|
||||
}
|
||||
|
|
@ -366,14 +373,12 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
} else if (layercount < 0) {
|
||||
// negative layer count indicates merged has alpha and it is to be shown
|
||||
if (nb_channels > real_nb_channels) {
|
||||
real_nb_channels++;
|
||||
have_alpha = true;
|
||||
merged_has_alpha = true;
|
||||
}
|
||||
layercount = -layercount;
|
||||
} else {
|
||||
// multiple layers implies there is alpha
|
||||
real_nb_channels++;
|
||||
have_alpha = true;
|
||||
}
|
||||
|
||||
|
|
@ -387,6 +392,7 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
}
|
||||
if (have_alpha) {
|
||||
JXL_DEBUG_V(PSD_VERBOSITY, "Have alpha");
|
||||
real_nb_channels++;
|
||||
info.type = ExtraChannel::kAlpha;
|
||||
info.alpha_associated =
|
||||
false; // true? PSD is not consistent with this, need to check
|
||||
|
|
@ -527,9 +533,11 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
JXL_DEBUG_V(PSD_VERBOSITY, "At position %i (%zu)",
|
||||
(int)(pos - bytes.data()), (size_t)pos);
|
||||
ImageBundle& layer = io->frames[il++];
|
||||
JXL_RETURN_IF_ERROR(decode_layer(pos, maxpos, layer, layer_chan_id[l],
|
||||
invert, layer.xsize(), layer.ysize(),
|
||||
version, colormodel, true, bitdepth));
|
||||
std::vector<int>& chan_id = layer_chan_id[l];
|
||||
if (chan_id.size() > invert.size()) invert.resize(chan_id.size(), false);
|
||||
JXL_RETURN_IF_ERROR(decode_layer(pos, maxpos, layer, chan_id, invert,
|
||||
layer.xsize(), layer.ysize(), version,
|
||||
colormodel, true, bitdepth));
|
||||
}
|
||||
} else
|
||||
return JXL_FAILURE("PSD: no layer data found");
|
||||
|
|
@ -573,7 +581,7 @@ Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
|||
return JXL_FAILURE("Inconsistent layer configuration");
|
||||
}
|
||||
if (!merged_has_alpha) {
|
||||
if (colormodel <= real_nb_channels) {
|
||||
if (colormodel >= real_nb_channels) {
|
||||
return JXL_FAILURE("Inconsistent layer configuration");
|
||||
}
|
||||
chan_id.erase(chan_id.begin() + colormodel);
|
||||
|
|
@ -605,4 +613,5 @@ Status EncodeImagePSD(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
return JXL_FAILURE("PSD encoding not yet implemented");
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
6
third_party/jpeg-xl/lib/extras/codec_psd.h
vendored
6
third_party/jpeg-xl/lib/extras/codec_psd.h
vendored
|
|
@ -11,6 +11,7 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
#include "lib/jxl/base/span.h"
|
||||
#include "lib/jxl/base/status.h"
|
||||
|
|
@ -18,9 +19,11 @@
|
|||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
// Decodes `bytes` into `io`.
|
||||
Status DecodeImagePSD(const Span<const uint8_t> bytes, ThreadPool* pool,
|
||||
Status DecodeImagePSD(const Span<const uint8_t> bytes,
|
||||
const ColorHints& color_hints, ThreadPool* pool,
|
||||
CodecInOut* io);
|
||||
|
||||
// Not implemented yet
|
||||
|
|
@ -28,6 +31,7 @@ Status EncodeImagePSD(const CodecInOut* io, const ColorEncoding& c_desired,
|
|||
size_t bits_per_sample, ThreadPool* pool,
|
||||
PaddedBytes* bytes);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_CODEC_PSD_H_
|
||||
|
|
|
|||
23
third_party/jpeg-xl/lib/extras/codec_test.cc
vendored
23
third_party/jpeg-xl/lib/extras/codec_test.cc
vendored
|
|
@ -25,6 +25,7 @@
|
|||
#include "lib/jxl/testdata.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
namespace {
|
||||
|
||||
CodecInOut CreateTestImage(const size_t xsize, const size_t ysize,
|
||||
|
|
@ -104,12 +105,14 @@ void TestRoundTrip(Codec codec, const size_t xsize, const size_t ysize,
|
|||
JXL_CHECK(Encode(io, codec, c_external, bits_per_sample, &encoded, pool));
|
||||
|
||||
CodecInOut io2;
|
||||
ColorHints color_hints;
|
||||
io2.target_nits = io.metadata.m.IntensityTarget();
|
||||
// Only for PNM because PNG will warn about ignoring them.
|
||||
if (codec == Codec::kPNM) {
|
||||
io2.dec_hints.Add("color_space", Description(c_external));
|
||||
color_hints.Add("color_space", Description(c_external));
|
||||
}
|
||||
JXL_CHECK(SetFromBytes(Span<const uint8_t>(encoded), &io2, pool));
|
||||
JXL_CHECK(SetFromBytes(Span<const uint8_t>(encoded), color_hints, &io2, pool,
|
||||
nullptr));
|
||||
ImageBundle& ib2 = io2.Main();
|
||||
|
||||
EXPECT_EQ(Description(c_external),
|
||||
|
|
@ -183,11 +186,11 @@ TEST(CodecTest, TestRoundTrip) {
|
|||
|
||||
CodecInOut DecodeRoundtrip(const std::string& pathname, Codec expected_codec,
|
||||
ThreadPool* pool,
|
||||
const DecoderHints& dec_hints = DecoderHints()) {
|
||||
const ColorHints& color_hints = ColorHints()) {
|
||||
CodecInOut io;
|
||||
io.dec_hints = dec_hints;
|
||||
const PaddedBytes orig = ReadTestData(pathname);
|
||||
JXL_CHECK(SetFromBytes(Span<const uint8_t>(orig), &io, pool));
|
||||
JXL_CHECK(
|
||||
SetFromBytes(Span<const uint8_t>(orig), color_hints, &io, pool, nullptr));
|
||||
const ImageBundle& ib1 = io.Main();
|
||||
|
||||
// Encode/Decode again to make sure Encode carries through all metadata.
|
||||
|
|
@ -196,8 +199,8 @@ CodecInOut DecodeRoundtrip(const std::string& pathname, Codec expected_codec,
|
|||
io.metadata.m.bit_depth.bits_per_sample, &encoded, pool));
|
||||
|
||||
CodecInOut io2;
|
||||
io2.dec_hints = dec_hints;
|
||||
JXL_CHECK(SetFromBytes(Span<const uint8_t>(encoded), &io2, pool));
|
||||
JXL_CHECK(SetFromBytes(Span<const uint8_t>(encoded), color_hints, &io2, pool,
|
||||
nullptr));
|
||||
const ImageBundle& ib2 = io2.Main();
|
||||
EXPECT_EQ(Description(ib1.metadata()->color_encoding),
|
||||
Description(ib2.metadata()->color_encoding));
|
||||
|
|
@ -344,9 +347,9 @@ void VerifyWideGamutMetadata(const std::string& relative_pathname,
|
|||
const Primaries primaries, ThreadPool* pool) {
|
||||
const CodecInOut io = DecodeRoundtrip(relative_pathname, Codec::kPNG, pool);
|
||||
|
||||
EXPECT_EQ(8, io.metadata.m.bit_depth.bits_per_sample);
|
||||
EXPECT_EQ(8u, io.metadata.m.bit_depth.bits_per_sample);
|
||||
EXPECT_FALSE(io.metadata.m.bit_depth.floating_point_sample);
|
||||
EXPECT_EQ(0, io.metadata.m.bit_depth.exponent_bits_per_sample);
|
||||
EXPECT_EQ(0u, io.metadata.m.bit_depth.exponent_bits_per_sample);
|
||||
|
||||
const ColorEncoding& c_original = io.metadata.m.color_encoding;
|
||||
EXPECT_FALSE(c_original.ICC().empty());
|
||||
|
|
@ -369,7 +372,7 @@ TEST(CodecTest, TestWideGamut) {
|
|||
}
|
||||
|
||||
TEST(CodecTest, TestPNM) { TestCodecPNM(); }
|
||||
TEST(CodecTest, TestPGX) { TestCodecPGX(); }
|
||||
|
||||
} // namespace
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
|
|
|||
218
third_party/jpeg-xl/lib/extras/color_description.cc
vendored
Normal file
218
third_party/jpeg-xl/lib/extras/color_description.cc
vendored
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "lib/extras/color_description.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <cmath>
|
||||
|
||||
namespace jxl {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct EnumName {
|
||||
const char* name;
|
||||
T value;
|
||||
};
|
||||
|
||||
const EnumName<JxlColorSpace> kJxlColorSpaceNames[] = {
|
||||
{"RGB", JXL_COLOR_SPACE_RGB},
|
||||
{"Gra", JXL_COLOR_SPACE_GRAY},
|
||||
{"XYB", JXL_COLOR_SPACE_XYB},
|
||||
{"CS?", JXL_COLOR_SPACE_UNKNOWN},
|
||||
};
|
||||
|
||||
const EnumName<JxlWhitePoint> kJxlWhitePointNames[] = {
|
||||
{"D65", JXL_WHITE_POINT_D65},
|
||||
{"Cst", JXL_WHITE_POINT_CUSTOM},
|
||||
{"EER", JXL_WHITE_POINT_E},
|
||||
{"DCI", JXL_WHITE_POINT_DCI},
|
||||
};
|
||||
|
||||
const EnumName<JxlPrimaries> kJxlPrimariesNames[] = {
|
||||
{"SRG", JXL_PRIMARIES_SRGB},
|
||||
{"Cst", JXL_PRIMARIES_CUSTOM},
|
||||
{"202", JXL_PRIMARIES_2100},
|
||||
{"DCI", JXL_PRIMARIES_P3},
|
||||
};
|
||||
|
||||
const EnumName<JxlTransferFunction> kJxlTransferFunctionNames[] = {
|
||||
{"709", JXL_TRANSFER_FUNCTION_709},
|
||||
{"TF?", JXL_TRANSFER_FUNCTION_UNKNOWN},
|
||||
{"Lin", JXL_TRANSFER_FUNCTION_LINEAR},
|
||||
{"SRG", JXL_TRANSFER_FUNCTION_SRGB},
|
||||
{"PeQ", JXL_TRANSFER_FUNCTION_PQ},
|
||||
{"DCI", JXL_TRANSFER_FUNCTION_DCI},
|
||||
{"HLG", JXL_TRANSFER_FUNCTION_HLG},
|
||||
{"", JXL_TRANSFER_FUNCTION_GAMMA},
|
||||
};
|
||||
|
||||
const EnumName<JxlRenderingIntent> kJxlRenderingIntentNames[] = {
|
||||
{"Per", JXL_RENDERING_INTENT_PERCEPTUAL},
|
||||
{"Rel", JXL_RENDERING_INTENT_RELATIVE},
|
||||
{"Sat", JXL_RENDERING_INTENT_SATURATION},
|
||||
{"Abs", JXL_RENDERING_INTENT_ABSOLUTE},
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Status ParseEnum(const std::string& token, const EnumName<T>* enum_values,
|
||||
size_t enum_len, T* value) {
|
||||
std::string str;
|
||||
for (size_t i = 0; i < enum_len; i++) {
|
||||
if (enum_values[i].name == token) {
|
||||
*value = enum_values[i].value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#define ARRAYSIZE(X) (sizeof(X) / sizeof((X)[0]))
|
||||
#define PARSE_ENUM(type, token, value) \
|
||||
ParseEnum<type>(token, k##type##Names, ARRAYSIZE(k##type##Names), value)
|
||||
|
||||
class Tokenizer {
|
||||
public:
|
||||
Tokenizer(const std::string* input, char separator)
|
||||
: input_(input), separator_(separator) {}
|
||||
|
||||
Status Next(std::string* next) {
|
||||
const size_t end = input_->find(separator_, start_);
|
||||
if (end == std::string::npos) {
|
||||
*next = input_->substr(start_); // rest of string
|
||||
} else {
|
||||
*next = input_->substr(start_, end - start_);
|
||||
}
|
||||
if (next->empty()) return JXL_FAILURE("Missing token");
|
||||
start_ = end + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string* const input_; // not owned
|
||||
const char separator_;
|
||||
size_t start_ = 0; // of next token
|
||||
};
|
||||
|
||||
Status ParseDouble(const std::string& num, double* d) {
|
||||
char* end;
|
||||
errno = 0;
|
||||
*d = strtod(num.c_str(), &end);
|
||||
if (*d == 0.0 && end == num.c_str()) {
|
||||
return JXL_FAILURE("Invalid double: %s", num.c_str());
|
||||
}
|
||||
if (std::isnan(*d)) {
|
||||
return JXL_FAILURE("Invalid double: %s", num.c_str());
|
||||
}
|
||||
if (errno == ERANGE) {
|
||||
return JXL_FAILURE("Double out of range: %s", num.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Status ParseDouble(Tokenizer* tokenizer, double* d) {
|
||||
std::string num;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&num));
|
||||
return ParseDouble(num, d);
|
||||
}
|
||||
|
||||
Status ParseColorSpace(Tokenizer* tokenizer, JxlColorEncoding* c) {
|
||||
std::string str;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
|
||||
JxlColorSpace cs;
|
||||
if (PARSE_ENUM(JxlColorSpace, str, &cs)) {
|
||||
c->color_space = cs;
|
||||
return true;
|
||||
}
|
||||
|
||||
return JXL_FAILURE("Unknown ColorSpace %s", str.c_str());
|
||||
}
|
||||
|
||||
Status ParseWhitePoint(Tokenizer* tokenizer, JxlColorEncoding* c) {
|
||||
if (c->color_space == JXL_COLOR_SPACE_XYB) {
|
||||
// Implicit white point.
|
||||
c->white_point = JXL_WHITE_POINT_D65;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
|
||||
if (PARSE_ENUM(JxlWhitePoint, str, &c->white_point)) return true;
|
||||
|
||||
Tokenizer xy_tokenizer(&str, ';');
|
||||
c->white_point = JXL_WHITE_POINT_CUSTOM;
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->white_point_xy + 0));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->white_point_xy + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
Status ParsePrimaries(Tokenizer* tokenizer, JxlColorEncoding* c) {
|
||||
if (c->color_space == JXL_COLOR_SPACE_GRAY ||
|
||||
c->color_space == JXL_COLOR_SPACE_XYB) {
|
||||
// No primaries case.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
|
||||
if (PARSE_ENUM(JxlPrimaries, str, &c->primaries)) return true;
|
||||
|
||||
Tokenizer xy_tokenizer(&str, ';');
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_red_xy + 0));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_red_xy + 1));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_green_xy + 0));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_green_xy + 1));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_blue_xy + 0));
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_blue_xy + 1));
|
||||
c->primaries = JXL_PRIMARIES_CUSTOM;
|
||||
|
||||
return JXL_FAILURE("Invalid primaries %s", str.c_str());
|
||||
}
|
||||
|
||||
Status ParseRenderingIntent(Tokenizer* tokenizer, JxlColorEncoding* c) {
|
||||
std::string str;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
|
||||
if (PARSE_ENUM(JxlRenderingIntent, str, &c->rendering_intent)) return true;
|
||||
|
||||
return JXL_FAILURE("Invalid RenderingIntent %s\n", str.c_str());
|
||||
}
|
||||
|
||||
Status ParseTransferFunction(Tokenizer* tokenizer, JxlColorEncoding* c) {
|
||||
if (c->color_space == JXL_COLOR_SPACE_XYB) {
|
||||
// Implicit TF.
|
||||
c->transfer_function = JXL_TRANSFER_FUNCTION_GAMMA;
|
||||
c->gamma = 1 / 3.;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string str;
|
||||
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
|
||||
if (PARSE_ENUM(JxlTransferFunction, str, &c->transfer_function)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (str[0] == 'g') {
|
||||
JXL_RETURN_IF_ERROR(ParseDouble(str.substr(1), &c->gamma));
|
||||
c->transfer_function = JXL_TRANSFER_FUNCTION_GAMMA;
|
||||
return true;
|
||||
}
|
||||
|
||||
return JXL_FAILURE("Invalid gamma %s", str.c_str());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Status ParseDescription(const std::string& description, JxlColorEncoding* c) {
|
||||
*c = {};
|
||||
Tokenizer tokenizer(&description, '_');
|
||||
JXL_RETURN_IF_ERROR(ParseColorSpace(&tokenizer, c));
|
||||
JXL_RETURN_IF_ERROR(ParseWhitePoint(&tokenizer, c));
|
||||
JXL_RETURN_IF_ERROR(ParsePrimaries(&tokenizer, c));
|
||||
JXL_RETURN_IF_ERROR(ParseRenderingIntent(&tokenizer, c));
|
||||
JXL_RETURN_IF_ERROR(ParseTransferFunction(&tokenizer, c));
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace jxl
|
||||
22
third_party/jpeg-xl/lib/extras/color_description.h
vendored
Normal file
22
third_party/jpeg-xl/lib/extras/color_description.h
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef LIB_EXTRAS_COLOR_DESCRIPTION_H_
|
||||
#define LIB_EXTRAS_COLOR_DESCRIPTION_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "jxl/color_encoding.h"
|
||||
#include "lib/jxl/base/status.h"
|
||||
|
||||
namespace jxl {
|
||||
|
||||
// Parse the color description into a JxlColorEncoding "RGB_D65_SRG_Rel_Lin".
|
||||
Status ParseDescription(const std::string& description,
|
||||
JxlColorEncoding* JXL_RESTRICT c);
|
||||
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_COLOR_DESCRIPTION_H_
|
||||
38
third_party/jpeg-xl/lib/extras/color_description_test.cc
vendored
Normal file
38
third_party/jpeg-xl/lib/extras/color_description_test.cc
vendored
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "lib/extras/color_description.h"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "lib/jxl/color_encoding_internal.h"
|
||||
#include "lib/jxl/test_utils.h"
|
||||
|
||||
namespace jxl {
|
||||
|
||||
// Verify ParseDescription(Description) yields the same ColorEncoding
|
||||
TEST(ColorDescriptionTest, RoundTripAll) {
|
||||
for (const auto& cdesc : test::AllEncodings()) {
|
||||
const ColorEncoding c_original = test::ColorEncodingFromDescriptor(cdesc);
|
||||
const std::string description = Description(c_original);
|
||||
printf("%s\n", description.c_str());
|
||||
|
||||
JxlColorEncoding c_external = {};
|
||||
EXPECT_TRUE(ParseDescription(description, &c_external));
|
||||
ColorEncoding c_internal;
|
||||
EXPECT_TRUE(
|
||||
ConvertExternalToInternalColorEncoding(c_external, &c_internal));
|
||||
EXPECT_TRUE(c_original.SameColorEncoding(c_internal))
|
||||
<< "Where c_original=" << c_original
|
||||
<< " and c_internal=" << c_internal;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ColorDescriptionTest, NanGamma) {
|
||||
const std::string description = "Gra_2_Per_gnan";
|
||||
JxlColorEncoding c;
|
||||
EXPECT_FALSE(ParseDescription(description, &c));
|
||||
}
|
||||
|
||||
} // namespace jxl
|
||||
67
third_party/jpeg-xl/lib/extras/color_hints.cc
vendored
Normal file
67
third_party/jpeg-xl/lib/extras/color_hints.cc
vendored
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "lib/extras/color_hints.h"
|
||||
|
||||
#include "lib/extras/color_description.h"
|
||||
#include "lib/jxl/base/file_io.h"
|
||||
#include "lib/jxl/color_encoding_internal.h"
|
||||
|
||||
namespace jxl {
|
||||
namespace extras {
|
||||
|
||||
Status ApplyColorHints(const ColorHints& color_hints,
|
||||
const bool color_already_set, const bool is_gray,
|
||||
CodecInOut* io) {
|
||||
if (color_already_set) {
|
||||
return color_hints.Foreach(
|
||||
[](const std::string& key, const std::string& /*value*/) {
|
||||
JXL_WARNING("Decoder ignoring %s hint", key.c_str());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool got_color_space = false;
|
||||
|
||||
JXL_RETURN_IF_ERROR(color_hints.Foreach(
|
||||
[is_gray, io, &got_color_space](const std::string& key,
|
||||
const std::string& value) -> Status {
|
||||
ColorEncoding* c_original = &io->metadata.m.color_encoding;
|
||||
if (key == "color_space") {
|
||||
JxlColorEncoding c_original_external;
|
||||
if (!ParseDescription(value, &c_original_external) ||
|
||||
!ConvertExternalToInternalColorEncoding(c_original_external,
|
||||
c_original) ||
|
||||
!c_original->CreateICC()) {
|
||||
return JXL_FAILURE("Failed to apply color_space");
|
||||
}
|
||||
|
||||
if (is_gray != io->metadata.m.color_encoding.IsGray()) {
|
||||
return JXL_FAILURE("mismatch between file and color_space hint");
|
||||
}
|
||||
|
||||
got_color_space = true;
|
||||
} else if (key == "icc_pathname") {
|
||||
PaddedBytes icc;
|
||||
JXL_RETURN_IF_ERROR(ReadFile(value, &icc));
|
||||
JXL_RETURN_IF_ERROR(c_original->SetICC(std::move(icc)));
|
||||
got_color_space = true;
|
||||
} else {
|
||||
JXL_WARNING("Ignoring %s hint", key.c_str());
|
||||
}
|
||||
return true;
|
||||
}));
|
||||
|
||||
if (!got_color_space) {
|
||||
JXL_WARNING("No color_space/icc_pathname given, assuming sRGB");
|
||||
JXL_RETURN_IF_ERROR(io->metadata.m.color_encoding.SetSRGB(
|
||||
is_gray ? ColorSpace::kGray : ColorSpace::kRGB));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
73
third_party/jpeg-xl/lib/extras/color_hints.h
vendored
Normal file
73
third_party/jpeg-xl/lib/extras/color_hints.h
vendored
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef LIB_EXTRAS_COLOR_HINTS_H_
|
||||
#define LIB_EXTRAS_COLOR_HINTS_H_
|
||||
|
||||
// Not all the formats implemented in the extras lib support bundling color
|
||||
// information into the file, and those that support it may not have it.
|
||||
// To allow attaching color information to those file formats the caller can
|
||||
// define these color hints.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lib/jxl/base/status.h"
|
||||
#include "lib/jxl/codec_in_out.h"
|
||||
|
||||
namespace jxl {
|
||||
|
||||
class ColorHints {
|
||||
public:
|
||||
// key=color_space, value=Description(c/pp): specify the ColorEncoding of
|
||||
// the pixels for decoding. Otherwise, if the codec did not obtain an ICC
|
||||
// profile from the image, assume sRGB.
|
||||
//
|
||||
// Strings are taken from the command line, so avoid spaces for convenience.
|
||||
void Add(const std::string& key, const std::string& value) {
|
||||
kv_.emplace_back(key, value);
|
||||
}
|
||||
|
||||
// Calls `func(key, value)` for each key/value in the order they were added,
|
||||
// returning false immediately if `func` returns false.
|
||||
template <class Func>
|
||||
Status Foreach(const Func& func) const {
|
||||
for (const KeyValue& kv : kv_) {
|
||||
Status ok = func(kv.key, kv.value);
|
||||
if (!ok) {
|
||||
return JXL_FAILURE("ColorHints::Foreach returned false");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Splitting into key/value avoids parsing in each codec.
|
||||
struct KeyValue {
|
||||
KeyValue(std::string key, std::string value)
|
||||
: key(std::move(key)), value(std::move(value)) {}
|
||||
|
||||
std::string key;
|
||||
std::string value;
|
||||
};
|
||||
|
||||
std::vector<KeyValue> kv_;
|
||||
};
|
||||
|
||||
namespace extras {
|
||||
|
||||
// Apply the color hints to the decoded image in CodecInOut if any.
|
||||
// color_already_set tells whether the color encoding was already set, in which
|
||||
// case the hints are ignored if any hint is passed.
|
||||
Status ApplyColorHints(const ColorHints& color_hints, bool color_already_set,
|
||||
bool is_gray, CodecInOut* io);
|
||||
|
||||
} // namespace extras
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_EXTRAS_COLOR_HINTS_H_
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "lib/jxl/base/time.h"
|
||||
#include "lib/extras/time.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -3,8 +3,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#ifndef LIB_JXL_BASE_TIME_H_
|
||||
#define LIB_JXL_BASE_TIME_H_
|
||||
#ifndef LIB_EXTRAS_TIME_H_
|
||||
#define LIB_EXTRAS_TIME_H_
|
||||
|
||||
// OS-specific function for timing.
|
||||
|
||||
|
|
@ -16,4 +16,4 @@ double Now();
|
|||
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_JXL_BASE_TIME_H_
|
||||
#endif // LIB_EXTRAS_TIME_H_
|
||||
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file butteraugli.h
|
||||
/** @addtogroup libjxl_butteraugli
|
||||
* @{
|
||||
* @file butteraugli.h
|
||||
* @brief Butteraugli API for JPEG XL.
|
||||
*/
|
||||
|
||||
|
|
@ -154,3 +156,5 @@ JXL_EXPORT void JxlButteraugliResultGetDistmap(
|
|||
#endif
|
||||
|
||||
#endif /* JXL_BUTTERAUGLI_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/// @addtogroup libjxl_butteraugli
|
||||
/// @{
|
||||
///
|
||||
/// @file butteraugli_cxx.h
|
||||
/// @brief C++ header-only helper for @ref butteraugli.h.
|
||||
///
|
||||
|
|
@ -53,3 +56,5 @@ typedef std::unique_ptr<JxlButteraugliResult, JxlButteraugliResultDestroyStruct>
|
|||
JxlButteraugliResultPtr;
|
||||
|
||||
#endif // JXL_BUTTERAUGLI_CXX_H_
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file codestream_header.h
|
||||
/** @addtogroup libjxl_common
|
||||
* @{
|
||||
* @file codestream_header.h
|
||||
* @brief Definitions of structs and enums for the metadata from the JPEG XL
|
||||
* codestream headers (signature, metadata, preview dimensions, ...), excluding
|
||||
* color encoding which is in color_encoding.h.
|
||||
|
|
@ -92,7 +94,7 @@ typedef struct {
|
|||
/** Basic image information. This information is available from the file
|
||||
* signature and first part of the codestream header.
|
||||
*/
|
||||
typedef struct JxlBasicInfo {
|
||||
typedef struct {
|
||||
/* TODO(lode): need additional fields for (transcoded) JPEG? For reusable
|
||||
* fields orientation must be read from Exif APP1. For has_icc_profile: must
|
||||
* look up where ICC profile is guaranteed to be in a JPEG file to be able to
|
||||
|
|
@ -203,15 +205,20 @@ typedef struct JxlBasicInfo {
|
|||
uint32_t num_extra_channels;
|
||||
|
||||
/** Bit depth of the encoded alpha channel, or 0 if there is no alpha channel.
|
||||
* If present, matches the alpha_bits value of the JxlExtraChannelInfo
|
||||
* associated with this alpha channel.
|
||||
*/
|
||||
uint32_t alpha_bits;
|
||||
|
||||
/** Alpha channel floating point exponent bits, or 0 if they are unsigned
|
||||
* integer.
|
||||
/** Alpha channel floating point exponent bits, or 0 if they are unsigned. If
|
||||
* present, matches the alpha_bits value of the JxlExtraChannelInfo associated
|
||||
* with this alpha channel. integer.
|
||||
*/
|
||||
uint32_t alpha_exponent_bits;
|
||||
|
||||
/** Whether the alpha channel is premultiplied
|
||||
/** Whether the alpha channel is premultiplied. Only used if there is a main
|
||||
* alpha channel. Matches the alpha_premultiplied value of the
|
||||
* JxlExtraChannelInfo associated with this alpha channel.
|
||||
*/
|
||||
JXL_BOOL alpha_premultiplied;
|
||||
|
||||
|
|
@ -224,6 +231,11 @@ typedef struct JxlBasicInfo {
|
|||
* used if have_animation is JXL_TRUE.
|
||||
*/
|
||||
JxlAnimationHeader animation;
|
||||
|
||||
/** Padding for forwards-compatibility, in case more fields are exposed
|
||||
* in a future version of the library.
|
||||
*/
|
||||
uint8_t padding[108];
|
||||
} JxlBasicInfo;
|
||||
|
||||
/** Information for a single extra channel.
|
||||
|
|
@ -257,7 +269,7 @@ typedef struct {
|
|||
/** Whether alpha channel uses premultiplied alpha. Only applicable if
|
||||
* type is JXL_CHANNEL_ALPHA.
|
||||
*/
|
||||
JXL_BOOL alpha_associated;
|
||||
JXL_BOOL alpha_premultiplied;
|
||||
|
||||
/** Spot color of the current spot channel in linear RGBA. Only applicable if
|
||||
* type is JXL_CHANNEL_SPOT_COLOR.
|
||||
|
|
@ -309,3 +321,5 @@ typedef struct {
|
|||
#endif
|
||||
|
||||
#endif /* JXL_CODESTREAM_HEADER_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file color_encoding.h
|
||||
/** @addtogroup libjxl_common
|
||||
* @{
|
||||
* @file color_encoding.h
|
||||
* @brief Color Encoding definitions used by JPEG XL.
|
||||
* All CIE units are for the standard 1931 2 degree observer.
|
||||
*/
|
||||
|
|
@ -127,7 +129,7 @@ typedef struct {
|
|||
/** Numerical blue primary values in CIE xy space. */
|
||||
double primaries_blue_xy[2];
|
||||
|
||||
/** Transfer function is have_gamma is 0 */
|
||||
/** Transfer function if have_gamma is 0 */
|
||||
JxlTransferFunction transfer_function;
|
||||
|
||||
/** Gamma value used when transfer_function is JXL_TRANSFER_FUNCTION_GAMMA
|
||||
|
|
@ -138,27 +140,10 @@ typedef struct {
|
|||
JxlRenderingIntent rendering_intent;
|
||||
} JxlColorEncoding;
|
||||
|
||||
/** Color transform used for the XYB encoding. This affects how the internal
|
||||
* XYB color format is converted, and is not needed unless XYB color is used.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Inverse opsin matrix.
|
||||
*/
|
||||
float opsin_inv_matrix[3][3];
|
||||
|
||||
/** Opsin bias for opsin matrix. This affects how the internal XYB color
|
||||
* format is converted, and is not needed unless XYB color is used.
|
||||
*/
|
||||
float opsin_biases[3];
|
||||
|
||||
/** Quantization bias for opsin matrix. This affects how the internal XYB
|
||||
* color format is converted, and is not needed unless XYB color is used.
|
||||
*/
|
||||
float quant_biases[3];
|
||||
} JxlInverseOpsinMatrix;
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JXL_COLOR_ENCODING_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
392
third_party/jpeg-xl/lib/include/jxl/decode.h
vendored
392
third_party/jpeg-xl/lib/include/jxl/decode.h
vendored
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file decode.h
|
||||
/** @addtogroup libjxl_decoder
|
||||
* @{
|
||||
* @file decode.h
|
||||
* @brief Decoding API for JPEG XL.
|
||||
*/
|
||||
|
||||
|
|
@ -121,7 +123,7 @@ typedef enum {
|
|||
*/
|
||||
JXL_DEC_SUCCESS = 0,
|
||||
|
||||
/** An error occured, for example invalid input file or out of memory.
|
||||
/** An error occurred, for example invalid input file or out of memory.
|
||||
* TODO(lode): add function to get error information from decoder.
|
||||
*/
|
||||
JXL_DEC_ERROR = 1,
|
||||
|
|
@ -150,6 +152,8 @@ typedef enum {
|
|||
* requested and it is possible to decode a DC image from the codestream and
|
||||
* the DC out buffer was not yet set. This event re-occurs for new frames
|
||||
* if there are multiple animation frames.
|
||||
* DEPRECATED: the DC feature in this form will be removed. You can use
|
||||
* JxlDecoderFlushImage for progressive rendering.
|
||||
*/
|
||||
JXL_DEC_NEED_DC_OUT_BUFFER = 4,
|
||||
|
||||
|
|
@ -160,14 +164,19 @@ typedef enum {
|
|||
*/
|
||||
JXL_DEC_NEED_IMAGE_OUT_BUFFER = 5,
|
||||
|
||||
/** Informative event by JxlDecoderProcessInput: JPEG reconstruction buffer is
|
||||
* too small for reconstructed JPEG codestream to fit.
|
||||
* JxlDecoderSetJPEGBuffer must be called again to make room for remaining
|
||||
* bytes. This event may occur multiple times after
|
||||
* JXL_DEC_JPEG_RECONSTRUCTION
|
||||
/** The JPEG reconstruction buffer is too small for reconstructed JPEG
|
||||
* codestream to fit. JxlDecoderSetJPEGBuffer must be called again to make
|
||||
* room for remaining bytes. This event may occur multiple times after
|
||||
* JXL_DEC_JPEG_RECONSTRUCTION.
|
||||
*/
|
||||
JXL_DEC_JPEG_NEED_MORE_OUTPUT = 6,
|
||||
|
||||
/** The box contents output buffer is too small. JxlDecoderSetBoxBuffer must
|
||||
* be called again to make room for remaining bytes. This event may occur
|
||||
* multiple times after JXL_DEC_BOX.
|
||||
*/
|
||||
JXL_DEC_BOX_NEED_MORE_OUTPUT = 7,
|
||||
|
||||
/** Informative event by JxlDecoderProcessInput: basic information such as
|
||||
* image dimensions and extra channels. This event occurs max once per image.
|
||||
*/
|
||||
|
|
@ -214,6 +223,8 @@ typedef enum {
|
|||
* status only indicates we're past this point in the codestream. This event
|
||||
* occurs max once per frame and always later than JXL_DEC_FRAME_HEADER
|
||||
* and other header events and earlier than full resolution pixel data.
|
||||
* DEPRECATED: the DC feature in this form will be removed. You can use
|
||||
* JxlDecoderFlushImage for progressive rendering.
|
||||
*/
|
||||
JXL_DEC_DC_IMAGE = 0x800,
|
||||
|
||||
|
|
@ -234,8 +245,70 @@ typedef enum {
|
|||
* image and always before JXL_DEC_FULL_IMAGE.
|
||||
*/
|
||||
JXL_DEC_JPEG_RECONSTRUCTION = 0x2000,
|
||||
|
||||
/** Informative event by JxlDecoderProcessInput: The header of a box of the
|
||||
* container format (BMFF) is decoded. The following API functions related to
|
||||
* boxes can be used after this event:
|
||||
* @see JxlDecoderSetBoxBuffer and JxlDecoderReleaseBoxBuffer: set and release
|
||||
* a buffer to get the box data.
|
||||
* @see JxlDecoderGetBoxType get the 4-character box typename.
|
||||
* @see JxlDecoderGetBoxSizeRaw get the size of the box as it appears in the
|
||||
* container file, not decompressed.
|
||||
* @see JxlDecoderSetDecompressBoxes to configure whether to get the box
|
||||
* data decompressed, or possibly compressed.
|
||||
*
|
||||
* Boxes can be compressed. This is so when their box type is "brob". In that
|
||||
* case, they have an underlying decompressed box type and decompressed data.
|
||||
* Use JxlDecoderSetDecompressBoxes to configure which data to get,
|
||||
* decompressing them requires Brotli. JxlDecoderGetBoxType has a flag to
|
||||
* get the compressed box type, which can be "brob", or the decompressed box
|
||||
* type. If a box is not compressed (its compressed type is not "brob"), then
|
||||
* you get the same decompressed box type and data no matter what setting is
|
||||
* configured.
|
||||
*
|
||||
* The buffer set with JxlDecoderSetBoxBuffer must be set again for each next
|
||||
* box that you want to get, or can be left unset to skip outputting this box.
|
||||
* The output buffer contains the full box data when the next JXL_DEC_BOX
|
||||
* event or JXL_DEC_SUCCESS occurs. JXL_DEC_BOX occurs for all boxes,
|
||||
* including non-metadata boxes such as the signature box or codestream boxes.
|
||||
* To check whether the box is a metadata type for respectively EXIF, XMP or
|
||||
* JUMBF, use JxlDecoderGetBoxType and check for types "Exif", "xml " and
|
||||
* "jumb" respectively.
|
||||
*/
|
||||
JXL_DEC_BOX = 0x4000,
|
||||
} JxlDecoderStatus;
|
||||
|
||||
/** Rewinds decoder to the beginning. The same input must be given again from
|
||||
* the beginning of the file and the decoder will emit events from the beginning
|
||||
* again. When rewinding (as opposed to JxlDecoderReset), the decoder can keep
|
||||
* state about the image, which it can use to skip to a requested frame more
|
||||
* efficiently with JxlDecoderSkipFrames. Settings such as parallel runner or
|
||||
* subscribed events are kept. After rewind, JxlDecoderSubscribeEvents can be
|
||||
* used again, and it is feasible to leave out events that were already handled
|
||||
* before, such as JXL_DEC_BASIC_INFO and JXL_DEC_COLOR_ENCODING, since they
|
||||
* will provide the same information as before.
|
||||
* @param dec decoder object
|
||||
*/
|
||||
JXL_EXPORT void JxlDecoderRewind(JxlDecoder* dec);
|
||||
|
||||
/** Makes the decoder skip the next `amount` frames. It still needs to process
|
||||
* the input, but will not output the frame events. It can be more efficient
|
||||
* when skipping frames, and even more so when using this after
|
||||
* JxlDecoderRewind. If the decoder is already processing a frame (could
|
||||
* have emitted JXL_DEC_FRAME but not yet JXL_DEC_FULL_IMAGE), it starts
|
||||
* skipping from the next frame. If the amount is larger than the amount of
|
||||
* frames remaining in the image, all remaining frames are skipped. Calling this
|
||||
* function multiple times adds the amount to skip to the already existing
|
||||
* amount.
|
||||
* A frame here is defined as a frame that without skipping emits events such as
|
||||
* JXL_DEC_FRAME and JXL_FULL_IMAGE, frames that are internal to the file format
|
||||
* but are not rendered as part of an animation, or are not the final still
|
||||
* frame of a still image, are not counted.
|
||||
* @param dec decoder object
|
||||
* @param amount the amount of frames to skip
|
||||
*/
|
||||
JXL_EXPORT void JxlDecoderSkipFrames(JxlDecoder* dec, size_t amount);
|
||||
|
||||
/**
|
||||
* Get the default pixel format for this decoder.
|
||||
*
|
||||
|
|
@ -319,6 +392,8 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderSubscribeEvents(JxlDecoder* dec,
|
|||
* By default, this option is disabled, and the decoder automatically corrects
|
||||
* the orientation.
|
||||
*
|
||||
* This function must be called at the beginning, before decoding is performed.
|
||||
*
|
||||
* @see JxlBasicInfo for the orientation field, and @see JxlOrientation for the
|
||||
* possible values.
|
||||
*
|
||||
|
|
@ -347,7 +422,15 @@ JxlDecoderSetKeepOrientation(JxlDecoder* dec, JXL_BOOL keep_orientation);
|
|||
* requires more JxlDecoderProcessInput calls to continue.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @return JXL_DEC_SUCCESS when decoding finished and all events handled.
|
||||
* @return JXL_DEC_SUCCESS when decoding finished and all events handled. If you
|
||||
* still have more unprocessed input data anyway, then you can still continue
|
||||
* by using JxlDecoderSetInput and calling JxlDecoderProcessInput again, similar
|
||||
* to handling JXL_DEC_NEED_MORE_INPUT. JXL_DEC_SUCCESS can occur instead of
|
||||
* JXL_DEC_NEED_MORE_INPUT when, for example, the input data ended right at
|
||||
* the boundary of a box of the container format, all essential codestream boxes
|
||||
* were already decoded, but extra metadata boxes are still present in the next
|
||||
* data. JxlDecoderProcessInput cannot return success if all codestream boxes
|
||||
* have not been seen yet.
|
||||
* @return JXL_DEC_ERROR when decoding failed, e.g. invalid codestream.
|
||||
* TODO(lode) document the input data mechanism
|
||||
* @return JXL_DEC_NEED_MORE_INPUT more input data is necessary.
|
||||
|
|
@ -374,7 +457,7 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderProcessInput(JxlDecoder* dec);
|
|||
* @param data pointer to next bytes to read from
|
||||
* @param size amount of bytes available starting from data
|
||||
* @return JXL_DEC_ERROR if input was already set without releasing,
|
||||
* JXL_DEC_SUCCESS otherwise
|
||||
* JXL_DEC_SUCCESS otherwise.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetInput(JxlDecoder* dec,
|
||||
const uint8_t* data,
|
||||
|
|
@ -496,7 +579,7 @@ typedef enum {
|
|||
* check whether the information is available through the return value.
|
||||
* @return JXL_DEC_SUCCESS if the data is available and returned,
|
||||
* JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case
|
||||
* the encuded structured color profile does not exist in the codestream.
|
||||
* the encoded structured color profile does not exist in the codestream.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderGetColorAsEncodedProfile(
|
||||
const JxlDecoder* dec, const JxlPixelFormat* format,
|
||||
|
|
@ -550,6 +633,47 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderGetColorAsICCProfile(
|
|||
const JxlDecoder* dec, const JxlPixelFormat* format,
|
||||
JxlColorProfileTarget target, uint8_t* icc_profile, size_t size);
|
||||
|
||||
/** Sets the color profile to use for JXL_COLOR_PROFILE_TARGET_DATA for the
|
||||
* special case when the decoder has a choice. This only has effect for a JXL
|
||||
* image where uses_original_profile is false, and the original color profile is
|
||||
* encoded as an ICC color profile rather than a JxlColorEncoding with known
|
||||
* enum values. In most other cases (uses uses_original_profile is true, or the
|
||||
* color profile is already given as a JxlColorEncoding), this setting is
|
||||
* ignored and the decoder uses a profile related to the image.
|
||||
* No matter what, the JXL_COLOR_PROFILE_TARGET_DATA must still be queried to
|
||||
* know the actual data format of the decoded pixels after decoding.
|
||||
*
|
||||
* The intended use case of this function is for cases where you are using
|
||||
* a color management system to parse the original ICC color profile
|
||||
* (JXL_COLOR_PROFILE_TARGET_ORIGINAL), from this you know that the ICC
|
||||
* profile represents one of the color profiles supported by JxlColorEncoding
|
||||
* (such as sRGB, PQ or HLG): in that case it is beneficial (but not necessary)
|
||||
* to use JxlDecoderSetPreferredColorProfile to match the parsed profile. The
|
||||
* JXL decoder has no color management system built in, but can convert XYB
|
||||
* color to any of the ones supported by JxlColorEncoding.
|
||||
*
|
||||
* Can only be set after the JXL_DEC_COLOR_ENCODING event occurred and before
|
||||
* any other event occurred, and can affect the result of
|
||||
* JXL_COLOR_PROFILE_TARGET_DATA (but not of JXL_COLOR_PROFILE_TARGET_ORIGINAL),
|
||||
* so should be used after getting JXL_COLOR_PROFILE_TARGET_ORIGINAL but before
|
||||
* getting JXL_COLOR_PROFILE_TARGET_DATA. The color_encoding must be grayscale
|
||||
* if num_color_channels from the basic info is 1, RGB if num_color_channels
|
||||
* from the basic info is 3.
|
||||
*
|
||||
* If JxlDecoderSetPreferredColorProfile is not used, then for images for which
|
||||
* uses_original_profile is false and with ICC color profile, the decoder will
|
||||
* choose linear sRGB for color images, linear grayscale for grayscale images.
|
||||
* This function only sets a preference, since for other images the decoder has
|
||||
* no choice what color profile to use, it is determined by the image.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param color_encoding the default color encoding to set
|
||||
* @return JXL_DEC_SUCCESS if the preference was set successfully, JXL_DEC_ERROR
|
||||
* otherwise.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetPreferredColorProfile(
|
||||
JxlDecoder* dec, const JxlColorEncoding* color_encoding);
|
||||
|
||||
/**
|
||||
* Returns the minimum size in bytes of the preview image output pixel buffer
|
||||
* for the given format. This is the buffer for JxlDecoderSetPreviewOutBuffer.
|
||||
|
|
@ -598,13 +722,12 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderGetFrameHeader(const JxlDecoder* dec,
|
|||
JxlFrameHeader* header);
|
||||
|
||||
/**
|
||||
* Outputs name for the current frame. The buffer
|
||||
* for name must have at least name_length + 1 bytes allocated, gotten from
|
||||
* the associated JxlFrameHeader.
|
||||
* Outputs name for the current frame. The buffer for name must have at least
|
||||
* name_length + 1 bytes allocated, gotten from the associated JxlFrameHeader.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param name buffer to copy the name into
|
||||
* @param size size of the name buffer in bytes, includig zero termination
|
||||
* @param size size of the name buffer in bytes, including zero termination
|
||||
* character, so this must be at least JxlFrameHeader.name_length + 1.
|
||||
* @return JXL_DEC_SUCCESS if the value is available,
|
||||
* JXL_DEC_NEED_MORE_INPUT if not yet available, JXL_DEC_ERROR in case
|
||||
|
|
@ -623,8 +746,11 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderGetFrameName(const JxlDecoder* dec,
|
|||
* @param size output value, buffer size in bytes
|
||||
* @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as
|
||||
* information not available yet.
|
||||
*
|
||||
* DEPRECATED: the DC feature in this form will be removed. You can use
|
||||
* JxlDecoderFlushImage for progressive rendering.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderDCOutBufferSize(
|
||||
JXL_EXPORT JXL_DEPRECATED JxlDecoderStatus JxlDecoderDCOutBufferSize(
|
||||
const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size);
|
||||
|
||||
/**
|
||||
|
|
@ -641,8 +767,11 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderDCOutBufferSize(
|
|||
* @param size size of buffer in bytes
|
||||
* @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as
|
||||
* size too small.
|
||||
*
|
||||
* DEPRECATED: the DC feature in this form will be removed. You can use
|
||||
* JxlDecoderFlushImage for progressive rendering.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetDCOutBuffer(
|
||||
JXL_EXPORT JXL_DEPRECATED JxlDecoderStatus JxlDecoderSetDCOutBuffer(
|
||||
JxlDecoder* dec, const JxlPixelFormat* format, void* buffer, size_t size);
|
||||
|
||||
/**
|
||||
|
|
@ -659,40 +788,6 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderSetDCOutBuffer(
|
|||
JXL_EXPORT JxlDecoderStatus JxlDecoderImageOutBufferSize(
|
||||
const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size);
|
||||
|
||||
/**
|
||||
* Sets output buffer for reconstructed JPEG codestream.
|
||||
*
|
||||
* The data is owned by the caller
|
||||
* and may be used by the decoder until JxlDecoderReleaseJPEGBuffer is called or
|
||||
* the decoder is destroyed or reset so must be kept alive until then.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param data pointer to next bytes to write to
|
||||
* @param size amount of bytes available starting from data
|
||||
* @return JXL_DEC_ERROR if input was already set without releasing,
|
||||
* JXL_DEC_SUCCESS otherwise
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetJPEGBuffer(JxlDecoder* dec,
|
||||
uint8_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Releases buffer which was provided with JxlDecoderSetJPEGBuffer.
|
||||
*
|
||||
* Calling JxlDecoderReleaseJPEGBuffer is required whenever
|
||||
* a buffer is already set and a new buffer needs to be added with
|
||||
* JxlDecoderSetJPEGBuffer, but is not required before JxlDecoderDestroy or
|
||||
* JxlDecoderReset.
|
||||
*
|
||||
* Calling JxlDecoderReleaseJPEGBuffer when no input is set is
|
||||
* not an error and returns 0.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @return the amount of bytes the decoder has not yet written to of the data
|
||||
* set by JxlDecoderSetJPEGBuffer, or 0 if no buffer is set or
|
||||
* JxlDecoderReleaseJPEGBuffer was already called.
|
||||
*/
|
||||
JXL_EXPORT size_t JxlDecoderReleaseJPEGBuffer(JxlDecoder* dec);
|
||||
|
||||
/**
|
||||
* Sets the buffer to write the full resolution image to. This can be set when
|
||||
* the JXL_DEC_FRAME event occurs, must be set when the
|
||||
|
|
@ -716,7 +811,7 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderSetImageOutBuffer(
|
|||
* Callback function type for JxlDecoderSetImageOutCallback. @see
|
||||
* JxlDecoderSetImageOutCallback for usage.
|
||||
*
|
||||
* The callback bay be called simultaneously by different threads when using a
|
||||
* The callback may be called simultaneously by different threads when using a
|
||||
* threaded parallel runner, on different pixels.
|
||||
*
|
||||
* @param opaque optional user data, as given to JxlDecoderSetImageOutCallback.
|
||||
|
|
@ -744,7 +839,7 @@ typedef void (*JxlImageOutCallback)(void* opaque, size_t x, size_t y,
|
|||
* data, 1 pixel high, xsize pixels wide, called a scanline. The xsize here is
|
||||
* not the same as the full image width, the scanline may be a partial section,
|
||||
* and xsize may differ between calls. The user can then process and/or copy the
|
||||
* partial scanline to an image buffer. The callback bay be called
|
||||
* partial scanline to an image buffer. The callback may be called
|
||||
* simultaneously by different threads when using a threaded parallel runner, on
|
||||
* different pixels.
|
||||
*
|
||||
|
|
@ -777,7 +872,192 @@ JXL_EXPORT JxlDecoderStatus
|
|||
JxlDecoderSetImageOutCallback(JxlDecoder* dec, const JxlPixelFormat* format,
|
||||
JxlImageOutCallback callback, void* opaque);
|
||||
|
||||
/* TODO(lode): add way to output extra channels */
|
||||
/**
|
||||
* Returns the minimum size in bytes of an extra channel pixel buffer for the
|
||||
* given format. This is the buffer for JxlDecoderSetExtraChannelBuffer.
|
||||
* Requires the basic image information is available in the decoder.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param format format of the pixels. The num_channels value is ignored and is
|
||||
* always treated to be 1.
|
||||
* @param size output value, buffer size in bytes
|
||||
* @param index which extra channel to get, matching the index used in @see
|
||||
* JxlDecoderGetExtraChannelInfo. Must be smaller than num_extra_channels in the
|
||||
* associated JxlBasicInfo.
|
||||
* @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as
|
||||
* information not available yet or invalid index.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderExtraChannelBufferSize(
|
||||
const JxlDecoder* dec, const JxlPixelFormat* format, size_t* size,
|
||||
uint32_t index);
|
||||
|
||||
/**
|
||||
* Sets the buffer to write an extra channel to. This can be set when
|
||||
* the JXL_DEC_FRAME or JXL_DEC_NEED_IMAGE_OUT_BUFFER event occurs, and applies
|
||||
* only for the current frame. The size of the buffer must be at least as large
|
||||
* as given by JxlDecoderExtraChannelBufferSize. The buffer follows the format
|
||||
* described by JxlPixelFormat, but where num_channels is 1. The buffer is owned
|
||||
* by the caller. The amount of extra channels is given by the
|
||||
* num_extra_channels field in the associated JxlBasicInfo, and the information
|
||||
* of individual extra channels can be queried with @see
|
||||
* JxlDecoderGetExtraChannelInfo. To get multiple extra channels, this function
|
||||
* must be called multiple times, once for each wanted index. Not all images
|
||||
* have extra channels. The alpha channel is an extra channel and can be gotten
|
||||
* as part of the color channels when using an RGBA pixel buffer with
|
||||
* JxlDecoderSetImageOutBuffer, but additionally also can be gotten separately
|
||||
* as extra channel. The color channels themselves cannot be gotten this way.
|
||||
*
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param format format of the pixels. Object owned by user and its contents
|
||||
* are copied internally. The num_channels value is ignored and is always
|
||||
* treated to be 1.
|
||||
* @param buffer buffer type to output the pixel data to
|
||||
* @param size size of buffer in bytes
|
||||
* @param index which extra channel to get, matching the index used in @see
|
||||
* JxlDecoderGetExtraChannelInfo. Must be smaller than num_extra_channels in the
|
||||
* associated JxlBasicInfo.
|
||||
* @return JXL_DEC_SUCCESS on success, JXL_DEC_ERROR on error, such as
|
||||
* size too small or invalid index.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus
|
||||
JxlDecoderSetExtraChannelBuffer(JxlDecoder* dec, const JxlPixelFormat* format,
|
||||
void* buffer, size_t size, uint32_t index);
|
||||
|
||||
/**
|
||||
* Sets output buffer for reconstructed JPEG codestream.
|
||||
*
|
||||
* The data is owned by the caller and may be used by the decoder until
|
||||
* JxlDecoderReleaseJPEGBuffer is called or the decoder is destroyed or reset so
|
||||
* must be kept alive until then.
|
||||
*
|
||||
* If a JPEG buffer was set before and released with
|
||||
* JxlDecoderReleaseJPEGBuffer, bytes that the decoder has already output should
|
||||
* not be included, only the remaining bytes output must be set.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param data pointer to next bytes to write to
|
||||
* @param size amount of bytes available starting from data
|
||||
* @return JXL_DEC_ERROR if output buffer was already set and
|
||||
* JxlDecoderReleaseJPEGBuffer was not called on it, JXL_DEC_SUCCESS otherwise
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetJPEGBuffer(JxlDecoder* dec,
|
||||
uint8_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Releases buffer which was provided with JxlDecoderSetJPEGBuffer.
|
||||
*
|
||||
* Calling JxlDecoderReleaseJPEGBuffer is required whenever
|
||||
* a buffer is already set and a new buffer needs to be added with
|
||||
* JxlDecoderSetJPEGBuffer, but is not required before JxlDecoderDestroy or
|
||||
* JxlDecoderReset.
|
||||
*
|
||||
* Calling JxlDecoderReleaseJPEGBuffer when no buffer is set is
|
||||
* not an error and returns 0.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @return the amount of bytes the decoder has not yet written to of the data
|
||||
* set by JxlDecoderSetJPEGBuffer, or 0 if no buffer is set or
|
||||
* JxlDecoderReleaseJPEGBuffer was already called.
|
||||
*/
|
||||
JXL_EXPORT size_t JxlDecoderReleaseJPEGBuffer(JxlDecoder* dec);
|
||||
|
||||
/**
|
||||
* Sets output buffer for box output codestream.
|
||||
*
|
||||
* The data is owned by the caller and may be used by the decoder until
|
||||
* JxlDecoderReleaseBoxBuffer is called or the decoder is destroyed or reset so
|
||||
* must be kept alive until then.
|
||||
*
|
||||
* If for the current box a box buffer was set before and released with
|
||||
* JxlDecoderReleaseBoxBuffer, bytes that the decoder has already output should
|
||||
* not be included, only the remaining bytes output must be set.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param data pointer to next bytes to write to
|
||||
* @param size amount of bytes available starting from data
|
||||
* @return JXL_DEC_ERROR if output buffer was already set and
|
||||
* JxlDecoderReleaseBoxBuffer was not called on it, JXL_DEC_SUCCESS otherwise
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetBoxBuffer(JxlDecoder* dec,
|
||||
uint8_t* data, size_t size);
|
||||
|
||||
/**
|
||||
* Releases buffer which was provided with JxlDecoderSetBoxBuffer.
|
||||
*
|
||||
* Calling JxlDecoderReleaseBoxBuffer is required whenever
|
||||
* a buffer is already set and a new buffer needs to be added with
|
||||
* JxlDecoderSetBoxBuffer, but is not required before JxlDecoderDestroy or
|
||||
* JxlDecoderReset.
|
||||
*
|
||||
* Calling JxlDecoderReleaseBoxBuffer when no buffer is set is
|
||||
* not an error and returns 0.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @return the amount of bytes the decoder has not yet written to of the data
|
||||
* set by JxlDecoderSetBoxBuffer, or 0 if no buffer is set or
|
||||
* JxlDecoderReleaseBoxBuffer was already called.
|
||||
*/
|
||||
JXL_EXPORT size_t JxlDecoderReleaseBoxBuffer(JxlDecoder* dec);
|
||||
|
||||
/**
|
||||
* Configures whether to get boxes in raw mode or in decompressed mode. In raw
|
||||
* mode, boxes are output as their bytes appear in the container file, which may
|
||||
* be decompressed, or compressed if their type is "brob". In decompressed mode,
|
||||
* "brob" boxes are decompressed with Brotli before outputting them. The size of
|
||||
* the decompressed stream is not known before the decompression has already
|
||||
* finished.
|
||||
*
|
||||
* The default mode is raw. This setting can only be changed before decoding, or
|
||||
* directly after a JXL_DEC_BOX event, and is remembered until the decoder is
|
||||
* reset or destroyed.
|
||||
*
|
||||
* Enabling decompressed mode requires Brotli support from the library.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param decompress JXL_TRUE to transparently decompress, JXL_FALSE to get
|
||||
* boxes in raw mode.
|
||||
* @return JXL_DEC_ERROR if decompressed mode is set and Brotli is not
|
||||
* available, JXL_DEC_SUCCESS otherwise.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderSetDecompressBoxes(JxlDecoder* dec,
|
||||
JXL_BOOL decompress);
|
||||
|
||||
/**
|
||||
* Outputs the type of the current box, after a JXL_DEC_BOX event occured, as 4
|
||||
* characters without null termination character. In case of a compressed "brob"
|
||||
* box, this will return "brob" if the decompressed argument is JXL_FALSE, or
|
||||
* the underlying box type if the decompressed argument is JXL_TRUE.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param type buffer to copy the type into
|
||||
* @param decompressed which box type to get: JXL_TRUE to get the raw box type,
|
||||
* which can be "brob", JXL_FALSE, get the underlying box type.
|
||||
* @return JXL_DEC_SUCCESS if the value is available, JXL_DEC_ERROR if not, for
|
||||
* example the JXL file does not use the container format.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderGetBoxType(JxlDecoder* dec,
|
||||
JxlBoxType* type,
|
||||
JXL_BOOL decompressed);
|
||||
|
||||
/**
|
||||
* Returns the size of a box as it appears in the container file, after the
|
||||
* JXL_DEC_BOX event. For a non-compressed box, this is the size of the
|
||||
* contents, excluding the 4 bytes indicating the box type. For a compressed
|
||||
* "brob" box, this is the size of the compressed box contents plus the
|
||||
* additional 4 byte indicating the underlying box type, but excluding the 4
|
||||
* bytes indicating "brob". This function gives the size of the data that will
|
||||
* be written in the output buffer when getting boxes in the default raw
|
||||
* compressed mode. When JxlDecoderSetDecompressBoxes is enabled, the return
|
||||
* value of function does not change, and the decompressed size is not known
|
||||
* before it has already been decompressed and output.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @param size raw size of the box in bytes
|
||||
* @return JXL_DEC_ERROR if no box size is available, JXL_DEC_SUCCESS otherwise.
|
||||
*/
|
||||
JXL_EXPORT JxlDecoderStatus JxlDecoderGetBoxSizeRaw(const JxlDecoder* dec,
|
||||
uint64_t* size);
|
||||
|
||||
/**
|
||||
* Outputs progressive step towards the decoded image so far when only partial
|
||||
|
|
@ -785,8 +1065,8 @@ JxlDecoderSetImageOutCallback(JxlDecoder* dec, const JxlPixelFormat* format,
|
|||
* JxlDecoderSetImageOutBuffer will contain partial image data.
|
||||
*
|
||||
* Can be called when JxlDecoderProcessInput returns JXL_DEC_NEED_MORE_INPUT,
|
||||
* after the JXL_DEC_FRAME event already occured and before the
|
||||
* JXL_DEC_FULL_IMAGE event occured for a frame.
|
||||
* after the JXL_DEC_FRAME event already occurred and before the
|
||||
* JXL_DEC_FULL_IMAGE event occurred for a frame.
|
||||
*
|
||||
* @param dec decoder object
|
||||
* @return JXL_DEC_SUCCESS if image data was flushed to the output buffer, or
|
||||
|
|
@ -802,3 +1082,5 @@ JXL_EXPORT JxlDecoderStatus JxlDecoderFlushImage(JxlDecoder* dec);
|
|||
#endif
|
||||
|
||||
#endif /* JXL_DECODE_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/// @addtogroup libjxl_decoder
|
||||
/// @{
|
||||
///
|
||||
/// @file decode_cxx.h
|
||||
/// @brief C++ header-only helper for @ref decode.h.
|
||||
///
|
||||
|
|
@ -50,3 +53,5 @@ static inline JxlDecoderPtr JxlDecoderMake(
|
|||
}
|
||||
|
||||
#endif // JXL_DECODE_CXX_H_
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
37
third_party/jpeg-xl/lib/include/jxl/encode.h
vendored
37
third_party/jpeg-xl/lib/include/jxl/encode.h
vendored
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file encode.h
|
||||
/** @addtogroup libjxl_encoder
|
||||
* @{
|
||||
* @file encode.h
|
||||
* @brief Encoding API for JPEG XL.
|
||||
*/
|
||||
|
||||
|
|
@ -142,6 +144,14 @@ JXL_EXPORT JxlEncoderStatus JxlEncoderProcessOutput(JxlEncoder* enc,
|
|||
/**
|
||||
* Sets the buffer to read JPEG encoded bytes from for the next frame to encode.
|
||||
*
|
||||
* If JxlEncoderSetBasicInfo has not yet been called, calling
|
||||
* JxlEncoderAddJPEGFrame will implicitly call it with the parameters of the
|
||||
* added JPEG frame.
|
||||
*
|
||||
* If JxlEncoderSetColorEncoding or JxlEncoderSetICCProfile has not yet been
|
||||
* called, calling JxlEncoderAddJPEGFrame will implicitly call it with the
|
||||
* parameters of the added JPEG frame.
|
||||
*
|
||||
* If the encoder is set to store JPEG reconstruction metadata using @ref
|
||||
* JxlEncoderStoreJPEGMetadata and a single JPEG frame is added, it will be
|
||||
* possible to losslessly reconstruct the JPEG codestream.
|
||||
|
|
@ -157,19 +167,20 @@ JXL_EXPORT JxlEncoderStatus JxlEncoderAddJPEGFrame(
|
|||
|
||||
/**
|
||||
* Sets the buffer to read pixels from for the next image to encode. Must call
|
||||
* JxlEncoderSetDimensions before JxlEncoderAddImageFrame.
|
||||
* JxlEncoderSetBasicInfo before JxlEncoderAddImageFrame.
|
||||
*
|
||||
* Currently only some pixel formats are supported:
|
||||
* - JXL_TYPE_UINT8
|
||||
* - JXL_TYPE_UINT16
|
||||
* - JXL_TYPE_FLOAT16, with nominal range 0..1
|
||||
* - JXL_TYPE_FLOAT, with nominal range 0..1
|
||||
*
|
||||
* The color profile of the pixels depends on the value of uses_original_profile
|
||||
* in the JxlBasicInfo. If true, the pixels are assumed to be encoded in the
|
||||
* original profile that is set with JxlEncoderSetColorEncoding or
|
||||
* JxlEncoderSetICCProfile. If false, the pixels are assumed to be nonlinear
|
||||
* sRGB for integer data types (JXL_TYPE_UINT8 and JXL_TYPE_UINT16), and linear
|
||||
* sRGB for floating point data types (JXL_TYPE_FLOAT).
|
||||
* sRGB for integer data types (JXL_TYPE_UINT8, JXL_TYPE_UINT16), and linear
|
||||
* sRGB for floating point data types (JXL_TYPE_FLOAT16, JXL_TYPE_FLOAT).
|
||||
*
|
||||
* @param options set of encoder options to use when encoding the frame.
|
||||
* @param pixel_format format for pixels. Object owned by the caller and its
|
||||
|
|
@ -225,6 +236,17 @@ JXL_EXPORT JxlEncoderStatus JxlEncoderSetICCProfile(JxlEncoder* enc,
|
|||
const uint8_t* icc_profile,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* Initializes a JxlBasicInfo struct to default values.
|
||||
* For forwards-compatibility, this function has to be called before values
|
||||
* are assigned to the struct fields.
|
||||
* The default values correspond to an 8-bit RGB image, no alpha or any
|
||||
* other extra channels.
|
||||
*
|
||||
* @param info global image metadata. Object owned by the caller.
|
||||
*/
|
||||
JXL_EXPORT void JxlEncoderInitBasicInfo(JxlBasicInfo* info);
|
||||
|
||||
/**
|
||||
* Sets the global metadata of the image encoded by this encoder.
|
||||
*
|
||||
|
|
@ -298,8 +320,9 @@ JxlEncoderOptionsSetDecodingSpeed(JxlEncoderOptions* options, int tier);
|
|||
|
||||
/**
|
||||
* Sets encoder effort/speed level without affecting decoding speed. Valid
|
||||
* values are, from faster to slower speed: 3:falcon 4:cheetah 5:hare 6:wombat
|
||||
* 7:squirrel 8:kitten 9:tortoise Default: squirrel (7).
|
||||
* values are, from faster to slower speed: 1:lightning 2:thunder 3:falcon
|
||||
* 4:cheetah 5:hare 6:wombat 7:squirrel 8:kitten 9:tortoise.
|
||||
* Default: squirrel (7).
|
||||
*
|
||||
* @param options set of encoder options to update with the new mode.
|
||||
* @param effort the effort value to set.
|
||||
|
|
@ -369,3 +392,5 @@ JXL_EXPORT void JxlColorEncodingSetToLinearSRGB(
|
|||
#endif
|
||||
|
||||
#endif /* JXL_ENCODE_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/// @addtogroup libjxl_encoder
|
||||
///@{
|
||||
///
|
||||
/// @file encode_cxx.h
|
||||
/// @brief C++ header-only helper for @ref encode.h.
|
||||
///
|
||||
|
|
@ -50,3 +53,5 @@ static inline JxlEncoderPtr JxlEncoderMake(
|
|||
}
|
||||
|
||||
#endif // JXL_ENCODE_CXX_H_
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file memory_manager.h
|
||||
/** @addtogroup libjxl_common
|
||||
* @{
|
||||
* @file memory_manager.h
|
||||
* @brief Abstraction functions used by JPEG XL to allocate memory.
|
||||
*/
|
||||
|
||||
|
|
@ -65,3 +67,5 @@ typedef struct JxlMemoryManagerStruct {
|
|||
#endif
|
||||
|
||||
#endif /* JXL_MEMORY_MANAGER_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @addtogroup libjxl_common
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @file parallel_runner.h
|
||||
*/
|
||||
|
|
@ -149,3 +152,5 @@ typedef JxlParallelRetCode (*JxlParallelRunner)(
|
|||
#endif
|
||||
|
||||
#endif /* JXL_PARALLEL_RUNNER_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
79
third_party/jpeg-xl/lib/include/jxl/resizable_parallel_runner.h
vendored
Normal file
79
third_party/jpeg-xl/lib/include/jxl/resizable_parallel_runner.h
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/* Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style
|
||||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @addtogroup libjxl_threads
|
||||
* @{
|
||||
* @file resizable_parallel_runner.h
|
||||
* @brief implementation using std::thread of a resizeable ::JxlParallelRunner.
|
||||
*/
|
||||
|
||||
/** Implementation of JxlParallelRunner than can be used to enable
|
||||
* multithreading when using the JPEG XL library. This uses std::thread
|
||||
* internally and related synchronization functions. The number of threads
|
||||
* created can be changed after creation of the thread pool; the threads
|
||||
* (including the main thread) are re-used for every
|
||||
* ResizableParallelRunner::Runner call. Only one concurrent
|
||||
* JxlResizableParallelRunner call per instance is allowed at a time.
|
||||
*
|
||||
* This is a scalable, lower-overhead thread pool runner, especially suitable
|
||||
* for data-parallel computations in the fork-join model, where clients need to
|
||||
* know when all tasks have completed.
|
||||
*
|
||||
* Compared to the implementation in @ref thread_parallel_runner.h, this
|
||||
* implementation is tuned for execution on lower-powered systems, including
|
||||
* for example ARM CPUs with big.LITTLE computation models.
|
||||
*/
|
||||
|
||||
#ifndef JXL_RESIZABLE_PARALLEL_RUNNER_H_
|
||||
#define JXL_RESIZABLE_PARALLEL_RUNNER_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jxl/jxl_threads_export.h"
|
||||
#include "jxl/memory_manager.h"
|
||||
#include "jxl/parallel_runner.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Parallel runner internally using std::thread. Use as JxlParallelRunner.
|
||||
*/
|
||||
JXL_THREADS_EXPORT JxlParallelRetCode JxlResizableParallelRunner(
|
||||
void* runner_opaque, void* jpegxl_opaque, JxlParallelRunInit init,
|
||||
JxlParallelRunFunction func, uint32_t start_range, uint32_t end_range);
|
||||
|
||||
/** Creates the runner for JxlResizableParallelRunner. Use as the opaque
|
||||
* runner. The runner will execute tasks on the calling thread until
|
||||
* @ref JxlResizableParallelRunnerSetThreads is called.
|
||||
*/
|
||||
JXL_THREADS_EXPORT void* JxlResizableParallelRunnerCreate(
|
||||
const JxlMemoryManager* memory_manager);
|
||||
|
||||
/** Changes the number of threads for JxlResizableParallelRunner.
|
||||
*/
|
||||
JXL_THREADS_EXPORT void JxlResizableParallelRunnerSetThreads(
|
||||
void* runner_opaque, size_t num_threads);
|
||||
|
||||
/** Suggests a number of threads to use for an image of given size.
|
||||
*/
|
||||
JXL_THREADS_EXPORT uint32_t
|
||||
JxlResizableParallelRunnerSuggestThreads(uint64_t xsize, uint64_t ysize);
|
||||
|
||||
/** Destroys the runner created by JxlResizableParallelRunnerCreate.
|
||||
*/
|
||||
JXL_THREADS_EXPORT void JxlResizableParallelRunnerDestroy(void* runner_opaque);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JXL_RESIZABLE_PARALLEL_RUNNER_H_ */
|
||||
|
||||
/** @}*/
|
||||
64
third_party/jpeg-xl/lib/include/jxl/resizable_parallel_runner_cxx.h
vendored
Normal file
64
third_party/jpeg-xl/lib/include/jxl/resizable_parallel_runner_cxx.h
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) the JPEG XL Project Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/// @addtogroup libjxl_threads
|
||||
/// @{
|
||||
///
|
||||
/// @file resizable_parallel_runner_cxx.h
|
||||
/// @ingroup libjxl_threads
|
||||
/// @brief C++ header-only helper for @ref resizable_parallel_runner.h.
|
||||
///
|
||||
/// There's no binary library associated with the header since this is a header
|
||||
/// only library.
|
||||
|
||||
#ifndef JXL_RESIZABLE_PARALLEL_RUNNER_CXX_H_
|
||||
#define JXL_RESIZABLE_PARALLEL_RUNNER_CXX_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "jxl/resizable_parallel_runner.h"
|
||||
|
||||
#if !(defined(__cplusplus) || defined(c_plusplus))
|
||||
#error \
|
||||
"This a C++ only header. Use jxl/jxl_resizable_parallel_runner.h from C" \
|
||||
"sources."
|
||||
#endif
|
||||
|
||||
/// Struct to call JxlResizableParallelRunnerDestroy from the
|
||||
/// JxlResizableParallelRunnerPtr unique_ptr.
|
||||
struct JxlResizableParallelRunnerDestroyStruct {
|
||||
/// Calls @ref JxlResizableParallelRunnerDestroy() on the passed runner.
|
||||
void operator()(void* runner) { JxlResizableParallelRunnerDestroy(runner); }
|
||||
};
|
||||
|
||||
/// std::unique_ptr<> type that calls JxlResizableParallelRunnerDestroy() when
|
||||
/// releasing the runner.
|
||||
///
|
||||
/// Use this helper type from C++ sources to ensure the runner is destroyed and
|
||||
/// their internal resources released.
|
||||
typedef std::unique_ptr<void, JxlResizableParallelRunnerDestroyStruct>
|
||||
JxlResizableParallelRunnerPtr;
|
||||
|
||||
/// Creates an instance of JxlResizableParallelRunner into a
|
||||
/// JxlResizableParallelRunnerPtr and initializes it.
|
||||
///
|
||||
/// This function returns a unique_ptr that will call
|
||||
/// JxlResizableParallelRunnerDestroy() when releasing the pointer. See @ref
|
||||
/// JxlResizableParallelRunnerCreate for details on the instance creation.
|
||||
///
|
||||
/// @param memory_manager custom allocator function. It may be NULL. The memory
|
||||
/// manager will be copied internally.
|
||||
/// @return a @c NULL JxlResizableParallelRunnerPtr if the instance can not be
|
||||
/// allocated or initialized
|
||||
/// @return initialized JxlResizableParallelRunnerPtr instance otherwise.
|
||||
static inline JxlResizableParallelRunnerPtr JxlResizableParallelRunnerMake(
|
||||
const JxlMemoryManager* memory_manager) {
|
||||
return JxlResizableParallelRunnerPtr(
|
||||
JxlResizableParallelRunnerCreate(memory_manager));
|
||||
}
|
||||
|
||||
#endif // JXL_RESIZABLE_PARALLEL_RUNNER_CXX_H_
|
||||
|
||||
/// @}
|
||||
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file thread_parallel_runner.h
|
||||
/** @addtogroup libjxl_threads
|
||||
* @{
|
||||
* @file thread_parallel_runner.h
|
||||
* @brief implementation using std::thread of a ::JxlParallelRunner.
|
||||
*/
|
||||
|
||||
|
|
@ -67,3 +69,5 @@ JXL_THREADS_EXPORT size_t JxlThreadParallelRunnerDefaultNumWorkerThreads();
|
|||
#endif
|
||||
|
||||
#endif /* JXL_THREAD_PARALLEL_RUNNER_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/// @addtogroup libjxl_threads
|
||||
/// @{
|
||||
///
|
||||
/// @file thread_parallel_runner_cxx.h
|
||||
/// @brief C++ header-only helper for @ref thread_parallel_runner.h.
|
||||
///
|
||||
|
|
@ -57,3 +60,5 @@ static inline JxlThreadParallelRunnerPtr JxlThreadParallelRunnerMake(
|
|||
}
|
||||
|
||||
#endif // JXL_THREAD_PARALLEL_RUNNER_CXX_H_
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
12
third_party/jpeg-xl/lib/include/jxl/types.h
vendored
12
third_party/jpeg-xl/lib/include/jxl/types.h
vendored
|
|
@ -4,7 +4,9 @@
|
|||
* license that can be found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/** @file types.h
|
||||
/** @addtogroup libjxl_common
|
||||
* @{
|
||||
* @file types.h
|
||||
* @brief Data types for the JPEG XL API, for both encoding and decoding.
|
||||
*/
|
||||
|
||||
|
|
@ -84,7 +86,7 @@ typedef enum {
|
|||
*/
|
||||
typedef struct {
|
||||
/** Amount of channels available in a pixel buffer.
|
||||
* 1: single-channel data, e.g. grayscale
|
||||
* 1: single-channel data, e.g. grayscale or a single extra channel
|
||||
* 2: single-channel + alpha
|
||||
* 3: trichromatic, e.g. RGB
|
||||
* 4: trichromatic + alpha
|
||||
|
|
@ -109,8 +111,14 @@ typedef struct {
|
|||
size_t align;
|
||||
} JxlPixelFormat;
|
||||
|
||||
/** Data type holding the 4-character type name of an ISOBMFF box.
|
||||
*/
|
||||
typedef char JxlBoxType[4];
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* JXL_TYPES_H_ */
|
||||
|
||||
/** @}*/
|
||||
|
|
|
|||
94
third_party/jpeg-xl/lib/jxl.cmake
vendored
94
third_party/jpeg-xl/lib/jxl.cmake
vendored
|
|
@ -43,8 +43,6 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/base/status.cc
|
||||
jxl/base/status.h
|
||||
jxl/base/thread_pool_internal.h
|
||||
jxl/base/time.cc
|
||||
jxl/base/time.h
|
||||
jxl/blending.cc
|
||||
jxl/blending.h
|
||||
jxl/chroma_from_luma.cc
|
||||
|
|
@ -71,6 +69,7 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/dec_ans.cc
|
||||
jxl/dec_ans.h
|
||||
jxl/dec_bit_reader.h
|
||||
jxl/dec_cache.cc
|
||||
jxl/dec_cache.h
|
||||
jxl/dec_context_map.cc
|
||||
jxl/dec_context_map.h
|
||||
|
|
@ -93,6 +92,7 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/dec_patch_dictionary.h
|
||||
jxl/dec_reconstruct.cc
|
||||
jxl/dec_reconstruct.h
|
||||
jxl/dec_render_pipeline.h
|
||||
jxl/dec_transforms-inl.h
|
||||
jxl/dec_upsample.cc
|
||||
jxl/dec_upsample.h
|
||||
|
|
@ -100,6 +100,8 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/dec_xyb.cc
|
||||
jxl/dec_xyb.h
|
||||
jxl/decode.cc
|
||||
jxl/decode_to_jpeg.cc
|
||||
jxl/decode_to_jpeg.h
|
||||
jxl/enc_bit_writer.cc
|
||||
jxl/enc_bit_writer.h
|
||||
jxl/entropy_coder.cc
|
||||
|
|
@ -158,10 +160,11 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/modular/modular_image.cc
|
||||
jxl/modular/modular_image.h
|
||||
jxl/modular/options.h
|
||||
jxl/modular/transform/near-lossless.h
|
||||
jxl/modular/transform/palette.h
|
||||
jxl/modular/transform/rct.cc
|
||||
jxl/modular/transform/rct.h
|
||||
jxl/modular/transform/squeeze.cc
|
||||
jxl/modular/transform/squeeze.h
|
||||
jxl/modular/transform/subtractgreen.h
|
||||
jxl/modular/transform/transform.cc
|
||||
jxl/modular/transform/transform.h
|
||||
jxl/noise.h
|
||||
|
|
@ -177,6 +180,7 @@ set(JPEGXL_INTERNAL_SOURCES_DEC
|
|||
jxl/quantizer.cc
|
||||
jxl/quantizer.h
|
||||
jxl/rational_polynomial-inl.h
|
||||
jxl/sanitizers.h
|
||||
jxl/splines.cc
|
||||
jxl/splines.h
|
||||
jxl/toc.cc
|
||||
|
|
@ -245,6 +249,7 @@ set(JPEGXL_INTERNAL_SOURCES_ENC
|
|||
jxl/enc_icc_codec.h
|
||||
jxl/enc_image_bundle.cc
|
||||
jxl/enc_image_bundle.h
|
||||
jxl/enc_jxl_skcms.h
|
||||
jxl/enc_modular.cc
|
||||
jxl/enc_modular.h
|
||||
jxl/enc_noise.cc
|
||||
|
|
@ -252,6 +257,8 @@ set(JPEGXL_INTERNAL_SOURCES_ENC
|
|||
jxl/enc_params.h
|
||||
jxl/enc_patch_dictionary.cc
|
||||
jxl/enc_patch_dictionary.h
|
||||
jxl/enc_photon_noise.cc
|
||||
jxl/enc_photon_noise.h
|
||||
jxl/enc_quant_weights.cc
|
||||
jxl/enc_quant_weights.h
|
||||
jxl/enc_splines.cc
|
||||
|
|
@ -276,10 +283,20 @@ set(JPEGXL_INTERNAL_SOURCES_ENC
|
|||
jxl/jpeg/enc_jpeg_huffman_decode.cc
|
||||
jxl/jpeg/enc_jpeg_huffman_decode.h
|
||||
jxl/linalg.cc
|
||||
jxl/modular/encoding/enc_debug_tree.cc
|
||||
jxl/modular/encoding/enc_debug_tree.h
|
||||
jxl/modular/encoding/enc_encoding.cc
|
||||
jxl/modular/encoding/enc_encoding.h
|
||||
jxl/modular/encoding/enc_ma.cc
|
||||
jxl/modular/encoding/enc_ma.h
|
||||
jxl/modular/transform/enc_palette.cc
|
||||
jxl/modular/transform/enc_palette.h
|
||||
jxl/modular/transform/enc_rct.cc
|
||||
jxl/modular/transform/enc_rct.h
|
||||
jxl/modular/transform/enc_squeeze.cc
|
||||
jxl/modular/transform/enc_squeeze.h
|
||||
jxl/modular/transform/enc_transform.cc
|
||||
jxl/modular/transform/enc_transform.h
|
||||
jxl/optimize.cc
|
||||
jxl/optimize.h
|
||||
jxl/progressive_split.cc
|
||||
|
|
@ -313,11 +330,20 @@ endfunction()
|
|||
|
||||
if (JPEGXL_ENABLE_SKCMS)
|
||||
list(APPEND JPEGXL_INTERNAL_FLAGS -DJPEGXL_ENABLE_SKCMS=1)
|
||||
list(APPEND JPEGXL_INTERNAL_LIBS skcms)
|
||||
if (JPEGXL_BUNDLE_SKCMS)
|
||||
list(APPEND JPEGXL_INTERNAL_FLAGS -DJPEGXL_BUNDLE_SKCMS=1)
|
||||
# skcms objects are later added to JPEGXL_INTERNAL_OBJECTS
|
||||
else ()
|
||||
list(APPEND JPEGXL_INTERNAL_LIBS skcms)
|
||||
endif ()
|
||||
else ()
|
||||
list(APPEND JPEGXL_INTERNAL_LIBS lcms2)
|
||||
endif ()
|
||||
|
||||
if (NOT JPEGXL_ENABLE_TRANSCODE_JPEG)
|
||||
list(APPEND JPEGXL_INTERNAL_FLAGS -DJPEGXL_ENABLE_TRANSCODE_JPEG=0)
|
||||
endif ()
|
||||
|
||||
set(OBJ_COMPILE_DEFINITIONS
|
||||
JPEGXL_MAJOR_VERSION=${JPEGXL_MAJOR_VERSION}
|
||||
JPEGXL_MINOR_VERSION=${JPEGXL_MINOR_VERSION}
|
||||
|
|
@ -369,23 +395,14 @@ if (JPEGXL_ENABLE_SKCMS)
|
|||
target_include_directories(jxl_enc-obj PRIVATE
|
||||
$<TARGET_PROPERTY:skcms,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_include_directories(jxl_dec-obj PRIVATE
|
||||
$<TARGET_PROPERTY:skcms,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
else ()
|
||||
target_include_directories(jxl_enc-obj PRIVATE
|
||||
$<TARGET_PROPERTY:lcms2,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
target_include_directories(jxl_dec-obj PRIVATE
|
||||
$<TARGET_PROPERTY:lcms2,INCLUDE_DIRECTORIES>
|
||||
)
|
||||
endif ()
|
||||
|
||||
# Headers for exporting/importing public headers
|
||||
include(GenerateExportHeader)
|
||||
# TODO(deymo): Add these visibility properties to the static dependencies of
|
||||
# jxl_{dec,enc}-obj since those are currently compiled with the default
|
||||
# visibility.
|
||||
set_target_properties(jxl_dec-obj PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
VISIBILITY_INLINES_HIDDEN 1
|
||||
|
|
@ -407,8 +424,6 @@ target_include_directories(jxl_enc-obj PUBLIC
|
|||
|
||||
# Private static library. This exposes all the internal functions and is used
|
||||
# for tests.
|
||||
# TODO(lode): this library is missing symbols, more encoder-only code needs to
|
||||
# be moved to JPEGXL_INTERNAL_SOURCES_ENC before this works
|
||||
add_library(jxl_dec-static STATIC
|
||||
$<TARGET_OBJECTS:jxl_dec-obj>
|
||||
)
|
||||
|
|
@ -419,14 +434,20 @@ target_include_directories(jxl_dec-static PUBLIC
|
|||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include")
|
||||
|
||||
# The list of objects in the static and shared libraries.
|
||||
set(JPEGXL_INTERNAL_OBJECTS
|
||||
$<TARGET_OBJECTS:jxl_enc-obj>
|
||||
$<TARGET_OBJECTS:jxl_dec-obj>
|
||||
)
|
||||
if (JPEGXL_ENABLE_SKCMS AND JPEGXL_BUNDLE_SKCMS)
|
||||
list(APPEND JPEGXL_INTERNAL_OBJECTS $<TARGET_OBJECTS:skcms-obj>)
|
||||
endif()
|
||||
|
||||
# Private static library. This exposes all the internal functions and is used
|
||||
# for tests.
|
||||
# TODO(lode): once the source files are correctly split so that it is possible
|
||||
# to do, remove $<TARGET_OBJECTS:jxl_dec-obj> here and depend on jxl_dec-static
|
||||
add_library(jxl-static STATIC
|
||||
$<TARGET_OBJECTS:jxl_enc-obj>
|
||||
$<TARGET_OBJECTS:jxl_dec-obj>
|
||||
)
|
||||
add_library(jxl-static STATIC ${JPEGXL_INTERNAL_OBJECTS})
|
||||
target_link_libraries(jxl-static
|
||||
PUBLIC ${JPEGXL_COVERAGE_FLAGS} ${JPEGXL_INTERNAL_LIBS} hwy)
|
||||
target_include_directories(jxl-static PUBLIC
|
||||
|
|
@ -473,12 +494,10 @@ install(TARGETS jxl-static DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
|||
install(TARGETS jxl_dec-static DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
if (((NOT DEFINED "${TARGET_SUPPORTS_SHARED_LIBS}") OR
|
||||
TARGET_SUPPORTS_SHARED_LIBS) AND NOT JPEGXL_STATIC)
|
||||
TARGET_SUPPORTS_SHARED_LIBS) AND NOT JPEGXL_STATIC AND BUILD_SHARED_LIBS)
|
||||
|
||||
# Public shared library.
|
||||
add_library(jxl SHARED
|
||||
$<TARGET_OBJECTS:jxl_dec-obj>
|
||||
$<TARGET_OBJECTS:jxl_enc-obj>)
|
||||
add_library(jxl SHARED ${JPEGXL_INTERNAL_OBJECTS})
|
||||
strip_static(JPEGXL_INTERNAL_SHARED_LIBS JPEGXL_INTERNAL_LIBS)
|
||||
target_link_libraries(jxl PUBLIC ${JPEGXL_COVERAGE_FLAGS})
|
||||
target_link_libraries(jxl PRIVATE ${JPEGXL_INTERNAL_SHARED_LIBS})
|
||||
|
|
@ -507,6 +526,13 @@ set_target_properties(jxl_dec PROPERTIES
|
|||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")
|
||||
|
||||
# Check whether the linker support excluding libs
|
||||
set(LINKER_EXCLUDE_LIBS_FLAG "-Wl,--exclude-libs=ALL")
|
||||
include(CheckCSourceCompiles)
|
||||
list(APPEND CMAKE_EXE_LINKER_FLAGS ${LINKER_EXCLUDE_LIBS_FLAG})
|
||||
check_c_source_compiles("int main(){return 0;}" LINKER_SUPPORT_EXCLUDE_LIBS)
|
||||
list(REMOVE_ITEM CMAKE_EXE_LINKER_FLAGS ${LINKER_EXCLUDE_LIBS_FLAG})
|
||||
|
||||
# Add a jxl.version file as a version script to tag symbols with the
|
||||
# appropriate version number. This script is also used to limit what's exposed
|
||||
# in the shared library from the static dependencies bundled here.
|
||||
|
|
@ -522,6 +548,13 @@ foreach(target IN ITEMS jxl jxl_dec)
|
|||
set_property(TARGET ${target} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/jxl/jxl.version")
|
||||
endif() # APPLE
|
||||
# This hides the default visibility symbols from static libraries bundled into
|
||||
# the shared library. In particular this prevents exposing symbols from hwy
|
||||
# and skcms in the shared library.
|
||||
if(${LINKER_SUPPORT_EXCLUDE_LIBS})
|
||||
set_property(TARGET ${target} APPEND_STRING PROPERTY
|
||||
LINK_FLAGS " ${LINKER_EXCLUDE_LIBS_FLAG}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Only install libjxl shared library. The libjxl_dec is not installed since it
|
||||
|
|
@ -529,16 +562,19 @@ endforeach()
|
|||
# both.
|
||||
install(TARGETS jxl
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
else()
|
||||
add_library(jxl ALIAS jxl-static)
|
||||
add_library(jxl_dec ALIAS jxl_dec-static)
|
||||
endif() # TARGET_SUPPORTS_SHARED_LIBS AND NOT JPEGXL_STATIC AND
|
||||
# BUILD_SHARED_LIBS
|
||||
|
||||
# Add a pkg-config file for libjxl.
|
||||
set(JPEGXL_LIBRARY_REQUIRES
|
||||
"libhwy libbrotlicommon libbrotlienc libbrotlidec")
|
||||
if(NOT JPEGXL_ENABLE_SKCMS)
|
||||
set(JPEGXL_LIBRARY_REQUIRES "${JPEGXL_LIBRARY_REQUIRES} lcms2")
|
||||
endif()
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/jxl/libjxl.pc.in"
|
||||
"libjxl.pc" @ONLY)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/libjxl.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
|
||||
|
||||
else()
|
||||
add_library(jxl ALIAS jxl-static)
|
||||
add_library(jxl_dec ALIAS jxl_dec-static)
|
||||
endif() # TARGET_SUPPORTS_SHARED_LIBS AND NOT JPEGXL_STATIC
|
||||
|
|
|
|||
|
|
@ -134,10 +134,10 @@ void EnsureUnchanged(const float background, const float foreground,
|
|||
jxl::PassesDecoderState state;
|
||||
JXL_CHECK(
|
||||
jxl::InitializePassesSharedState(frame_header, &state.shared_storage));
|
||||
state.Init();
|
||||
JXL_CHECK(state.Init());
|
||||
state.InitForAC(/*pool=*/nullptr);
|
||||
|
||||
state.filter_weights.Init(lf, frame_dim);
|
||||
JXL_CHECK(state.filter_weights.Init(lf, frame_dim));
|
||||
FillImage(-0.5f, &state.filter_weights.sigma);
|
||||
|
||||
for (size_t idx_image = 0; idx_image < images.size(); ++idx_image) {
|
||||
|
|
@ -152,7 +152,7 @@ void EnsureUnchanged(const float background, const float foreground,
|
|||
// input image.
|
||||
JXL_CHECK(FinalizeFrameDecoding(&out, &state, /*pool=*/nullptr,
|
||||
/*force_fir=*/true,
|
||||
/*skip_blending=*/true));
|
||||
/*skip_blending=*/true, /*move_ec=*/true));
|
||||
|
||||
#if JXL_HIGH_PRECISION
|
||||
VerifyRelativeError(in, *out.color(), 1E-3, 1E-4);
|
||||
|
|
|
|||
10
third_party/jpeg-xl/lib/jxl/ans_common.h
vendored
10
third_party/jpeg-xl/lib/jxl/ans_common.h
vendored
|
|
@ -79,12 +79,12 @@ struct AliasTable {
|
|||
|
||||
// Dividing `value` by `entry_size` determines `i`, the entry which is
|
||||
// responsible for the input. If the remainder is below `cutoff`, then the
|
||||
// mapped symbol is `i`; since `offsets[0]` stores the number of occurences of
|
||||
// `i` "before" the start of this entry, the offset of the input will be
|
||||
// mapped symbol is `i`; since `offsets[0]` stores the number of occurrences
|
||||
// of `i` "before" the start of this entry, the offset of the input will be
|
||||
// `offsets[0] + remainder`. If the remainder is above cutoff, the mapped
|
||||
// symbol is `right_value`; since `offsets[1]` stores the number of occurences
|
||||
// of `right_value` "before" this entry, minus the `cutoff` value, the input
|
||||
// offset is then `remainder + offsets[1]`.
|
||||
// symbol is `right_value`; since `offsets[1]` stores the number of
|
||||
// occurrences of `right_value` "before" this entry, minus the `cutoff` value,
|
||||
// the input offset is then `remainder + offsets[1]`.
|
||||
static JXL_INLINE Symbol Lookup(const Entry* JXL_RESTRICT table, size_t value,
|
||||
size_t log_entry_size,
|
||||
size_t entry_size_minus_1) {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ void VerifyAliasDistribution(const std::vector<int>& distribution,
|
|||
offsets[s.value].push_back(s.offset);
|
||||
}
|
||||
for (uint32_t i = 0; i < distribution.size(); i++) {
|
||||
ASSERT_EQ(distribution[i], offsets[i].size());
|
||||
ASSERT_EQ(static_cast<size_t>(distribution[i]), offsets[i].size());
|
||||
std::sort(offsets[i].begin(), offsets[i].end());
|
||||
for (uint32_t j = 0; j < offsets[i].size(); j++) {
|
||||
ASSERT_EQ(offsets[i][j], j);
|
||||
|
|
|
|||
2
third_party/jpeg-xl/lib/jxl/ans_test.cc
vendored
2
third_party/jpeg-xl/lib/jxl/ans_test.cc
vendored
|
|
@ -111,7 +111,7 @@ void RoundtripRandomUnbalancedStream(int alphabet_size) {
|
|||
constexpr int kNumHistograms = 3;
|
||||
constexpr int kPrecision = 1 << 10;
|
||||
std::mt19937_64 rng;
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (size_t i = 0; i < kReps; i++) {
|
||||
std::vector<int> distributions[kNumHistograms];
|
||||
for (int j = 0; j < kNumHistograms; j++) {
|
||||
distributions[j].resize(kPrecision);
|
||||
|
|
|
|||
14
third_party/jpeg-xl/lib/jxl/aux_out.h
vendored
14
third_party/jpeg-xl/lib/jxl/aux_out.h
vendored
|
|
@ -148,8 +148,7 @@ struct AuxOut {
|
|||
layers[i].Assimilate(victim.layers[i]);
|
||||
}
|
||||
num_blocks += victim.num_blocks;
|
||||
num_dct2_blocks += victim.num_dct2_blocks;
|
||||
num_dct4_blocks += victim.num_dct4_blocks;
|
||||
num_small_blocks += victim.num_small_blocks;
|
||||
num_dct4x8_blocks += victim.num_dct4x8_blocks;
|
||||
num_afv_blocks += victim.num_afv_blocks;
|
||||
num_dct8_blocks += victim.num_dct8_blocks;
|
||||
|
|
@ -158,6 +157,8 @@ struct AuxOut {
|
|||
num_dct16_blocks += victim.num_dct16_blocks;
|
||||
num_dct16x32_blocks += victim.num_dct16x32_blocks;
|
||||
num_dct32_blocks += victim.num_dct32_blocks;
|
||||
num_dct32x64_blocks += victim.num_dct32x64_blocks;
|
||||
num_dct64_blocks += victim.num_dct64_blocks;
|
||||
num_butteraugli_iters += victim.num_butteraugli_iters;
|
||||
for (size_t i = 0; i < dc_pred_usage.size(); ++i) {
|
||||
dc_pred_usage[i] += victim.dc_pred_usage[i];
|
||||
|
|
@ -270,8 +271,7 @@ struct AuxOut {
|
|||
size_t num_blocks = 0;
|
||||
|
||||
// Number of blocks that use larger DCT (set by ac_strategy).
|
||||
size_t num_dct2_blocks = 0;
|
||||
size_t num_dct4_blocks = 0;
|
||||
size_t num_small_blocks = 0;
|
||||
size_t num_dct4x8_blocks = 0;
|
||||
size_t num_afv_blocks = 0;
|
||||
size_t num_dct8_blocks = 0;
|
||||
|
|
@ -280,9 +280,11 @@ struct AuxOut {
|
|||
size_t num_dct16_blocks = 0;
|
||||
size_t num_dct16x32_blocks = 0;
|
||||
size_t num_dct32_blocks = 0;
|
||||
size_t num_dct32x64_blocks = 0;
|
||||
size_t num_dct64_blocks = 0;
|
||||
|
||||
std::array<uint32_t, 8> dc_pred_usage = {0};
|
||||
std::array<uint32_t, 8> dc_pred_usage_xb = {0};
|
||||
std::array<uint32_t, 8> dc_pred_usage = {{0}};
|
||||
std::array<uint32_t, 8> dc_pred_usage_xb = {{0}};
|
||||
|
||||
int num_butteraugli_iters = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ constexpr size_t CacheAligned::kAlignment;
|
|||
constexpr size_t CacheAligned::kAlias;
|
||||
|
||||
void CacheAligned::PrintStats() {
|
||||
printf("Allocations: %zu (max bytes in use: %E)\n",
|
||||
size_t(num_allocations.load(std::memory_order_relaxed)),
|
||||
double(max_bytes_in_use.load(std::memory_order_relaxed)));
|
||||
fprintf(stderr, "Allocations: %zu (max bytes in use: %E)\n",
|
||||
size_t(num_allocations.load(std::memory_order_relaxed)),
|
||||
double(max_bytes_in_use.load(std::memory_order_relaxed)));
|
||||
}
|
||||
|
||||
size_t CacheAligned::NextOffset() {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,16 @@
|
|||
#define JXL_MUST_USE_RESULT
|
||||
#endif
|
||||
|
||||
// Disable certain -fsanitize flags for functions that are expected to include
|
||||
// things like unsigned integer overflow. For example use in the function
|
||||
// declaration JXL_NO_SANITIZE("unsigned-integer-overflow") to silence unsigned
|
||||
// integer overflow ubsan messages.
|
||||
#if JXL_COMPILER_CLANG && JXL_HAVE_ATTRIBUTE(no_sanitize)
|
||||
#define JXL_NO_SANITIZE(X) __attribute__((no_sanitize(X)))
|
||||
#else
|
||||
#define JXL_NO_SANITIZE(X)
|
||||
#endif
|
||||
|
||||
#if JXL_HAVE_ATTRIBUTE(__format__)
|
||||
#define JXL_FORMAT(idx_fmt, idx_arg) \
|
||||
__attribute__((__format__(__printf__, idx_fmt, idx_arg)))
|
||||
|
|
|
|||
|
|
@ -5,14 +5,6 @@
|
|||
|
||||
#include "lib/jxl/base/data_parallel.h"
|
||||
|
||||
#define DATA_PARALLEL_TRACE 0
|
||||
|
||||
#if DATA_PARALLEL_TRACE
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lib/jxl/base/time.h"
|
||||
#endif // DATA_PARALLEL_TRACE
|
||||
|
||||
namespace jxl {
|
||||
|
||||
// static
|
||||
|
|
@ -28,16 +20,4 @@ JxlParallelRetCode ThreadPool::SequentialRunnerStatic(
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if DATA_PARALLEL_TRACE
|
||||
void TraceRunBegin(const char* /*caller*/, double* t0) { *t0 = Now(); }
|
||||
|
||||
void TraceRunEnd(const char* caller, double t0) {
|
||||
const double elapsed = Now() - t0;
|
||||
fprintf(stderr, "%27s: %5.1f ms\n", caller, elapsed * 1E3);
|
||||
}
|
||||
#else
|
||||
void TraceRunBegin(const char* /*caller*/, double* /*t0*/) {}
|
||||
void TraceRunEnd(const char* /*caller*/, double /*t0*/) {}
|
||||
#endif
|
||||
|
||||
} // namespace jxl
|
||||
|
|
|
|||
37
third_party/jpeg-xl/lib/jxl/base/data_parallel.h
vendored
37
third_party/jpeg-xl/lib/jxl/base/data_parallel.h
vendored
|
|
@ -104,58 +104,21 @@ class ThreadPool {
|
|||
void* const runner_opaque_;
|
||||
};
|
||||
|
||||
void TraceRunBegin(const char* caller, double* t0);
|
||||
void TraceRunEnd(const char* caller, double t0);
|
||||
|
||||
// TODO(deymo): Convert the return value to a Status when not using SkipInit.
|
||||
template <class InitFunc, class DataFunc>
|
||||
bool RunOnPool(ThreadPool* pool, const uint32_t begin, const uint32_t end,
|
||||
const InitFunc& init_func, const DataFunc& data_func,
|
||||
const char* caller) {
|
||||
Status ret = true;
|
||||
double t0;
|
||||
TraceRunBegin(caller, &t0);
|
||||
if (pool == nullptr) {
|
||||
ThreadPool default_pool(nullptr, nullptr);
|
||||
ret = default_pool.Run(begin, end, init_func, data_func, caller);
|
||||
} else {
|
||||
ret = pool->Run(begin, end, init_func, data_func, caller);
|
||||
}
|
||||
TraceRunEnd(caller, t0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Accelerates multiple unsigned 32-bit divisions with the same divisor by
|
||||
// precomputing a multiplier. This is useful for splitting a contiguous range of
|
||||
// indices (the task index) into 2D indices. Exhaustively tested on dividends
|
||||
// up to 4M with non-power of two divisors up to 2K.
|
||||
class Divider {
|
||||
public:
|
||||
// "d" is the divisor (what to divide by).
|
||||
explicit Divider(const uint32_t d) : shift_(FloorLog2Nonzero(d)) {
|
||||
// Power of two divisors (including 1) are not supported because it is more
|
||||
// efficient to special-case them at a higher level.
|
||||
JXL_ASSERT((d & (d - 1)) != 0);
|
||||
|
||||
// ceil_log2 = floor_log2 + 1 because we ruled out powers of two above.
|
||||
const uint64_t next_pow2 = 1ULL << (shift_ + 1);
|
||||
|
||||
mul_ = ((next_pow2 - d) << 32) / d + 1;
|
||||
}
|
||||
|
||||
// "n" is the numerator (what is being divided).
|
||||
inline uint32_t operator()(const uint32_t n) const {
|
||||
// Algorithm from "Division by Invariant Integers using Multiplication".
|
||||
// Its "sh1" is hardcoded to 1 because we don't need to handle d=1.
|
||||
const uint32_t hi = (uint64_t(mul_) * n) >> 32;
|
||||
return (hi + ((n - hi) >> 1)) >> shift_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t mul_;
|
||||
const int shift_;
|
||||
};
|
||||
|
||||
} // namespace jxl
|
||||
|
||||
#endif // LIB_JXL_BASE_DATA_PARALLEL_H_
|
||||
|
|
|
|||
93
third_party/jpeg-xl/lib/jxl/base/file_io.h
vendored
93
third_party/jpeg-xl/lib/jxl/base/file_io.h
vendored
|
|
@ -11,7 +11,9 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "lib/jxl/base/compiler_specific.h"
|
||||
#include "lib/jxl/base/padded_bytes.h"
|
||||
|
|
@ -35,10 +37,25 @@ class FileWrapper {
|
|||
FileWrapper& operator=(const FileWrapper& other) = delete;
|
||||
|
||||
explicit FileWrapper(const std::string& pathname, const char* mode)
|
||||
: file_(fopen(pathname.c_str(), mode)) {}
|
||||
: file_(pathname == "-" ? (mode[0] == 'r' ? stdin : stdout)
|
||||
: fopen(pathname.c_str(), mode)),
|
||||
close_on_delete_(pathname != "-") {
|
||||
#ifdef _WIN32
|
||||
struct __stat64 s = {};
|
||||
const int err = _stat64(pathname.c_str(), &s);
|
||||
const bool is_file = (s.st_mode & S_IFREG) != 0;
|
||||
#else
|
||||
struct stat s = {};
|
||||
const int err = stat(pathname.c_str(), &s);
|
||||
const bool is_file = S_ISREG(s.st_mode);
|
||||
#endif
|
||||
if (err == 0 && is_file) {
|
||||
size_ = s.st_size;
|
||||
}
|
||||
}
|
||||
|
||||
~FileWrapper() {
|
||||
if (file_ != nullptr) {
|
||||
if (file_ != nullptr && close_on_delete_) {
|
||||
const int err = fclose(file_);
|
||||
JXL_CHECK(err == 0);
|
||||
}
|
||||
|
|
@ -48,8 +65,12 @@ class FileWrapper {
|
|||
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||
operator FILE*() const { return file_; }
|
||||
|
||||
int64_t size() { return size_; }
|
||||
|
||||
private:
|
||||
FILE* const file_;
|
||||
bool close_on_delete_ = true;
|
||||
int64_t size_ = -1;
|
||||
};
|
||||
|
||||
template <typename ContainerType>
|
||||
|
|
@ -58,34 +79,52 @@ static inline Status ReadFile(const std::string& pathname,
|
|||
FileWrapper f(pathname, "rb");
|
||||
if (f == nullptr) return JXL_FAILURE("Failed to open file for reading");
|
||||
|
||||
// Ensure it is a regular file
|
||||
#ifdef _WIN32
|
||||
struct __stat64 s = {};
|
||||
const int err = _stat64(pathname.c_str(), &s);
|
||||
const bool is_file = (s.st_mode & S_IFREG) != 0;
|
||||
#else
|
||||
struct stat s = {};
|
||||
const int err = stat(pathname.c_str(), &s);
|
||||
const bool is_file = S_ISREG(s.st_mode);
|
||||
#endif
|
||||
if (err != 0) return JXL_FAILURE("Failed to obtain file status");
|
||||
if (!is_file) return JXL_FAILURE("Not a file");
|
||||
|
||||
// Get size of file in bytes
|
||||
const int64_t size = s.st_size;
|
||||
if (size <= 0) return JXL_FAILURE("Empty or invalid file size");
|
||||
bytes->resize(static_cast<size_t>(size));
|
||||
const int64_t size = f.size();
|
||||
if (size < 0) {
|
||||
// Size is unknown, loop reading chunks until EOF.
|
||||
bytes->clear();
|
||||
std::list<std::vector<uint8_t>> chunks;
|
||||
|
||||
size_t pos = 0;
|
||||
while (pos < bytes->size()) {
|
||||
// Needed in case ContainerType is std::string, whose data() is const.
|
||||
char* bytes_writable = reinterpret_cast<char*>(&(*bytes)[0]);
|
||||
const size_t bytes_read =
|
||||
fread(bytes_writable + pos, 1, bytes->size() - pos, f);
|
||||
if (bytes_read == 0) return JXL_FAILURE("Failed to read");
|
||||
pos += bytes_read;
|
||||
size_t total_size = 0;
|
||||
while (true) {
|
||||
std::vector<uint8_t> chunk(16 * 1024);
|
||||
const size_t bytes_read = fread(chunk.data(), 1, chunk.size(), f);
|
||||
if (ferror(f) || bytes_read > chunk.size()) {
|
||||
return JXL_FAILURE("Error reading %s", pathname.c_str());
|
||||
}
|
||||
|
||||
chunk.resize(bytes_read);
|
||||
total_size += bytes_read;
|
||||
if (bytes_read != 0) {
|
||||
chunks.emplace_back(std::move(chunk));
|
||||
}
|
||||
if (feof(f)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bytes->resize(total_size);
|
||||
size_t pos = 0;
|
||||
for (const auto& chunk : chunks) {
|
||||
// Needed in case ContainerType is std::string, whose data() is const.
|
||||
char* bytes_writable = reinterpret_cast<char*>(&(*bytes)[0]);
|
||||
memcpy(bytes_writable + pos, chunk.data(), chunk.size());
|
||||
pos += chunk.size();
|
||||
}
|
||||
} else {
|
||||
// Size is known, read the file directly.
|
||||
bytes->resize(static_cast<size_t>(size));
|
||||
size_t pos = 0;
|
||||
while (pos < bytes->size()) {
|
||||
// Needed in case ContainerType is std::string, whose data() is const.
|
||||
char* bytes_writable = reinterpret_cast<char*>(&(*bytes)[0]);
|
||||
const size_t bytes_read =
|
||||
fread(bytes_writable + pos, 1, bytes->size() - pos, f);
|
||||
if (bytes_read == 0) return JXL_FAILURE("Failed to read");
|
||||
pos += bytes_read;
|
||||
}
|
||||
JXL_ASSERT(pos == bytes->size());
|
||||
}
|
||||
JXL_ASSERT(pos == bytes->size());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
10
third_party/jpeg-xl/lib/jxl/base/status.cc
vendored
10
third_party/jpeg-xl/lib/jxl/base/status.cc
vendored
|
|
@ -11,8 +11,9 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
|
||||
defined(THREAD_SANITIZER)
|
||||
#include "lib/jxl/sanitizers.h"
|
||||
|
||||
#if JXL_ADDRESS_SANITIZER || JXL_MEMORY_SANITIZER || JXL_THREAD_SANITIZER
|
||||
#include "sanitizer/common_interface_defs.h" // __sanitizer_print_stack_trace
|
||||
#endif // defined(*_SANITIZER)
|
||||
|
||||
|
|
@ -27,13 +28,12 @@ bool Debug(const char* format, ...) {
|
|||
}
|
||||
|
||||
bool Abort() {
|
||||
#if defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) || \
|
||||
defined(THREAD_SANITIZER)
|
||||
#if JXL_ADDRESS_SANITIZER || JXL_MEMORY_SANITIZER || JXL_THREAD_SANITIZER
|
||||
// If compiled with any sanitizer print a stack trace. This call doesn't crash
|
||||
// the program, instead the trap below will crash it also allowing gdb to
|
||||
// break there.
|
||||
__sanitizer_print_stack_trace();
|
||||
#endif // defined(*_SANITIZER)
|
||||
#endif // *_SANITIZER)
|
||||
|
||||
#if JXL_COMPILER_MSVC
|
||||
__debugbreak();
|
||||
|
|
|
|||
50
third_party/jpeg-xl/lib/jxl/base/status.h
vendored
50
third_party/jpeg-xl/lib/jxl/base/status.h
vendored
|
|
@ -60,6 +60,12 @@ namespace jxl {
|
|||
#define JXL_DEBUG_V_LEVEL 0
|
||||
#endif // JXL_DEBUG_V_LEVEL
|
||||
|
||||
// Pass -DJXL_DEBUG_ON_ABORT=0 to disable the debug messages on JXL_ASSERT,
|
||||
// JXL_CHECK and JXL_ABORT.
|
||||
#ifndef JXL_DEBUG_ON_ABORT
|
||||
#define JXL_DEBUG_ON_ABORT 1
|
||||
#endif // JXL_DEBUG_ON_ABORT
|
||||
|
||||
// Print a debug message on standard error. You should use the JXL_DEBUG macro
|
||||
// instead of calling Debug directly. This function returns false, so it can be
|
||||
// used as a return value in JXL_FAILURE.
|
||||
|
|
@ -110,19 +116,19 @@ bool Debug(const char* format, ...);
|
|||
JXL_NORETURN bool Abort();
|
||||
|
||||
// Exits the program after printing file/line plus a formatted string.
|
||||
#define JXL_ABORT(format, ...) \
|
||||
(::jxl::Debug(("%s:%d: JXL_ABORT: " format "\n"), __FILE__, __LINE__, \
|
||||
##__VA_ARGS__), \
|
||||
#define JXL_ABORT(format, ...) \
|
||||
((JXL_DEBUG_ON_ABORT) && ::jxl::Debug(("%s:%d: JXL_ABORT: " format "\n"), \
|
||||
__FILE__, __LINE__, ##__VA_ARGS__), \
|
||||
::jxl::Abort())
|
||||
|
||||
// Does not guarantee running the code, use only for debug mode checks.
|
||||
#if JXL_ENABLE_ASSERT
|
||||
#define JXL_ASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(true, "JXL_ASSERT: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
#define JXL_ASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(JXL_DEBUG_ON_ABORT, "JXL_ASSERT: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define JXL_ASSERT(condition) \
|
||||
|
|
@ -132,6 +138,7 @@ JXL_NORETURN bool Abort();
|
|||
|
||||
// Define JXL_IS_DEBUG_BUILD that denotes asan, msan and other debug builds,
|
||||
// but not opt or release.
|
||||
#ifndef JXL_IS_DEBUG_BUILD
|
||||
#if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) || \
|
||||
defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
|
||||
defined(__clang_analyzer__)
|
||||
|
|
@ -139,18 +146,19 @@ JXL_NORETURN bool Abort();
|
|||
#else
|
||||
#define JXL_IS_DEBUG_BUILD 0
|
||||
#endif
|
||||
#endif // JXL_IS_DEBUG_BUILD
|
||||
|
||||
// Same as above, but only runs in debug builds (builds where NDEBUG is not
|
||||
// defined). This is useful for slower asserts that we want to run more rarely
|
||||
// than usual. These will run on asan, msan and other debug builds, but not in
|
||||
// opt or release.
|
||||
#if JXL_IS_DEBUG_BUILD
|
||||
#define JXL_DASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(true, "JXL_DASSERT: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
#define JXL_DASSERT(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(JXL_DEBUG_ON_ABORT, "JXL_DASSERT: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define JXL_DASSERT(condition) \
|
||||
|
|
@ -160,12 +168,12 @@ JXL_NORETURN bool Abort();
|
|||
|
||||
// Always runs the condition, so can be used for non-debug calls.
|
||||
#if JXL_ENABLE_CHECK
|
||||
#define JXL_CHECK(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(true, "JXL_CHECK: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
#define JXL_CHECK(condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JXL_DEBUG(JXL_DEBUG_ON_ABORT, "JXL_CHECK: %s", #condition); \
|
||||
::jxl::Abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define JXL_CHECK(condition) \
|
||||
|
|
|
|||
51
third_party/jpeg-xl/lib/jxl/bit_reader_test.cc
vendored
51
third_party/jpeg-xl/lib/jxl/bit_reader_test.cc
vendored
|
|
@ -31,12 +31,12 @@ TEST(BitReaderTest, ExtendsWithZeroes) {
|
|||
BitReader br(Span<const uint8_t>(data.data(), n_bytes));
|
||||
// Read all the bits
|
||||
for (size_t i = 0; i < n_bytes * kBitsPerByte; i++) {
|
||||
ASSERT_EQ(br.ReadBits(1), 1) << "n_bytes=" << n_bytes << " i=" << i;
|
||||
ASSERT_EQ(br.ReadBits(1), 1u) << "n_bytes=" << n_bytes << " i=" << i;
|
||||
}
|
||||
|
||||
// PEEK more than the declared size - all will be zero. Cannot consume.
|
||||
for (size_t i = 0; i < BitReader::kMaxBitsPerCall; i++) {
|
||||
ASSERT_EQ(br.PeekBits(i), 0)
|
||||
ASSERT_EQ(br.PeekBits(i), 0u)
|
||||
<< "size=" << size << "n_bytes=" << n_bytes << " i=" << i;
|
||||
}
|
||||
|
||||
|
|
@ -116,20 +116,21 @@ TEST(BitReaderTest, TestSkip) {
|
|||
BitReader reader2(writer.GetSpan());
|
||||
// Verify initial 1-bits
|
||||
for (int i = 0; i < task; ++i) {
|
||||
EXPECT_EQ(1, reader1.ReadBits(1));
|
||||
EXPECT_EQ(1, reader2.ReadBits(1));
|
||||
EXPECT_EQ(1u, reader1.ReadBits(1));
|
||||
EXPECT_EQ(1u, reader2.ReadBits(1));
|
||||
}
|
||||
|
||||
// SkipBits or manually read "skip" bits
|
||||
reader1.SkipBits(skip);
|
||||
for (size_t i = 0; i < skip; ++i) {
|
||||
EXPECT_EQ(0, reader2.ReadBits(1)) << " skip=" << skip << " i=" << i;
|
||||
EXPECT_EQ(0u, reader2.ReadBits(1))
|
||||
<< " skip=" << skip << " i=" << i;
|
||||
}
|
||||
EXPECT_EQ(reader1.TotalBitsConsumed(), reader2.TotalBitsConsumed());
|
||||
|
||||
// Ensure both readers see the terminator bits.
|
||||
EXPECT_EQ(5, reader1.ReadBits(3));
|
||||
EXPECT_EQ(5, reader2.ReadBits(3));
|
||||
EXPECT_EQ(5u, reader1.ReadBits(3));
|
||||
EXPECT_EQ(5u, reader2.ReadBits(3));
|
||||
|
||||
EXPECT_TRUE(reader1.Close());
|
||||
EXPECT_TRUE(reader2.Close());
|
||||
|
|
@ -158,8 +159,8 @@ TEST(BitReaderTest, TestOrder) {
|
|||
writer.ZeroPadToByte();
|
||||
ReclaimAndCharge(&writer, &allotment, 0, nullptr);
|
||||
BitReader reader(writer.GetSpan());
|
||||
EXPECT_EQ(0x1F, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xFC, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x1Fu, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xFCu, reader.ReadFixedBits<8>());
|
||||
EXPECT_TRUE(reader.Close());
|
||||
}
|
||||
|
||||
|
|
@ -173,8 +174,8 @@ TEST(BitReaderTest, TestOrder) {
|
|||
writer.ZeroPadToByte();
|
||||
ReclaimAndCharge(&writer, &allotment, 0, nullptr);
|
||||
BitReader reader(writer.GetSpan());
|
||||
EXPECT_EQ(0xF8, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x3F, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xF8u, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x3Fu, reader.ReadFixedBits<8>());
|
||||
EXPECT_TRUE(reader.Close());
|
||||
}
|
||||
|
||||
|
|
@ -187,8 +188,8 @@ TEST(BitReaderTest, TestOrder) {
|
|||
writer.ZeroPadToByte();
|
||||
ReclaimAndCharge(&writer, &allotment, 0, nullptr);
|
||||
BitReader reader(writer.GetSpan());
|
||||
EXPECT_EQ(0x3F, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xF8, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x3Fu, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xF8u, reader.ReadFixedBits<8>());
|
||||
EXPECT_TRUE(reader.Close());
|
||||
}
|
||||
|
||||
|
|
@ -204,8 +205,8 @@ TEST(BitReaderTest, TestOrder) {
|
|||
writer.ZeroPadToByte();
|
||||
ReclaimAndCharge(&writer, &allotment, 0, nullptr);
|
||||
BitReader reader(writer.GetSpan());
|
||||
EXPECT_EQ(0xBD, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x8D, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0xBDu, reader.ReadFixedBits<8>());
|
||||
EXPECT_EQ(0x8Du, reader.ReadFixedBits<8>());
|
||||
EXPECT_TRUE(reader.Close());
|
||||
}
|
||||
}
|
||||
|
|
@ -215,21 +216,21 @@ TEST(BitReaderTest, TotalCountersTest) {
|
|||
BitReader reader(Span<const uint8_t>(buf, sizeof(buf)));
|
||||
|
||||
EXPECT_EQ(sizeof(buf), reader.TotalBytes());
|
||||
EXPECT_EQ(0, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(0u, reader.TotalBitsConsumed());
|
||||
reader.ReadFixedBits<1>();
|
||||
EXPECT_EQ(1, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(1u, reader.TotalBitsConsumed());
|
||||
|
||||
reader.ReadFixedBits<10>();
|
||||
EXPECT_EQ(11, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(11u, reader.TotalBitsConsumed());
|
||||
|
||||
reader.ReadFixedBits<4>();
|
||||
EXPECT_EQ(15, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(15u, reader.TotalBitsConsumed());
|
||||
|
||||
reader.ReadFixedBits<1>();
|
||||
EXPECT_EQ(16, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(16u, reader.TotalBitsConsumed());
|
||||
|
||||
reader.ReadFixedBits<16>();
|
||||
EXPECT_EQ(32, reader.TotalBitsConsumed());
|
||||
EXPECT_EQ(32u, reader.TotalBitsConsumed());
|
||||
|
||||
EXPECT_TRUE(reader.Close());
|
||||
}
|
||||
|
|
@ -240,18 +241,18 @@ TEST(BitReaderTest, MoveTest) {
|
|||
{
|
||||
BitReader reader1(Span<const uint8_t>(buf, sizeof(buf)));
|
||||
|
||||
EXPECT_EQ(0, reader1.TotalBitsConsumed());
|
||||
EXPECT_EQ(0u, reader1.TotalBitsConsumed());
|
||||
reader1.ReadFixedBits<16>();
|
||||
EXPECT_EQ(16, reader1.TotalBitsConsumed());
|
||||
EXPECT_EQ(16u, reader1.TotalBitsConsumed());
|
||||
|
||||
reader2 = std::move(reader1);
|
||||
// From this point reader1 is invalid, but can continue to access reader2
|
||||
// and we don't need to call Close() on reader1.
|
||||
}
|
||||
|
||||
EXPECT_EQ(16, reader2.TotalBitsConsumed());
|
||||
EXPECT_EQ(16u, reader2.TotalBitsConsumed());
|
||||
EXPECT_EQ(3U, reader2.ReadFixedBits<8>());
|
||||
EXPECT_EQ(24, reader2.TotalBitsConsumed());
|
||||
EXPECT_EQ(24u, reader2.TotalBitsConsumed());
|
||||
|
||||
EXPECT_TRUE(reader2.Close());
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue