Bug 1884859 - Update libjxl to f06a34c77b1bd11bafbe82989241e68c756ccca2 r=saschanaz

Differential Revision: https://phabricator.services.mozilla.com/D204327
This commit is contained in:
Updatebot 2024-03-14 20:57:48 +00:00
Родитель a58d54f79b
Коммит 85a91db376
290 изменённых файлов: 3324 добавлений и 3017 удалений

Просмотреть файл

@ -40,7 +40,6 @@ SOURCES += [
"/third_party/jpeg-xl/lib/jxl/decode.cc",
"/third_party/jpeg-xl/lib/jxl/entropy_coder.cc",
"/third_party/jpeg-xl/lib/jxl/epf.cc",
"/third_party/jpeg-xl/lib/jxl/fast_dct.cc",
"/third_party/jpeg-xl/lib/jxl/fields.cc",
"/third_party/jpeg-xl/lib/jxl/frame_header.cc",
"/third_party/jpeg-xl/lib/jxl/headers.cc",

Просмотреть файл

@ -10,9 +10,9 @@ origin:
url: https://github.com/libjxl/libjxl
release: ab47708dcf002fae0164555b370aa36487df0f5d (2024-02-19T19:38:30Z).
release: f06a34c77b1bd11bafbe82989241e68c756ccca2 (2024-03-11T15:14:53Z).
revision: ab47708dcf002fae0164555b370aa36487df0f5d
revision: f06a34c77b1bd11bafbe82989241e68c756ccca2
license: Apache-2.0

33
third_party/jpeg-xl/.clang-tidy поставляемый
Просмотреть файл

@ -25,16 +25,31 @@ Checks: >-
modernize-*,
performance-*,
readability-*,
-bugprone-narrowing-conversions,
-bugprone-branch-clone,
-bugprone-easily-swappable-parameters,
-bugprone-implicit-widening-of-multiplication-result,
-bugprone-infinite-loop,
-bugprone-unused-local-non-trivial-variable,
-modernize-avoid-c-arrays,
-modernize-deprecated-headers,
-modernize-return-braced-init-list,
-modernize-use-auto,
-modernize-use-default-member-init,
-modernize-use-trailing-return-type,
-modernize-use-using,
-performance-enum-size,
-readability-avoid-nested-conditional-operator,
-readability-else-after-return,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-magic-numbers,
-readability-redundant-access-specifiers,
-readability-simplify-boolean-expr,
-readability-static-accessed-through-instance,
-readability-suspicious-call-argument,
-readability-uppercase-literal-suffix,
-readability-use-anyofallof,
WarningsAsErrors: >-
@ -57,11 +72,13 @@ WarningsAsErrors: >-
HeaderFilterRegex: '^.*/(lib|tools)/.*\.h$'
CheckOptions:
- key: readability-braces-around-statements.ShortStatementLines
value: '2'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '2'
- key: readability-implicit-bool-conversion.AllowPointerConditions
value: '1'
- key: readability-implicit-bool-conversion.AllowIntegerConditions
value: '1'
- key: readability-braces-around-statements.ShortStatementLines
value: '2'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '2'
- key: readability-implicit-bool-conversion.AllowPointerConditions
value: '1'
- key: readability-implicit-bool-conversion.AllowIntegerConditions
value: '1'
- key: bugprone-signed-char-misuse.CharTypdefsToIgnore
value: 'int8_t'

18
third_party/jpeg-xl/CHANGELOG.md поставляемый
Просмотреть файл

@ -8,12 +8,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased
### Added
- decoder API: added `JxlDecoderGetBoxSizeContents` for getting the size of the
content of a box without the headers.
### Removed
### Changed / clarified
### Fixed
## [0.10.0] - 2024-02-21
### Added
- decoder API: added `JxlDecoderGetBoxSizeContents` for getting the size of the
content of a box without the headers.
- encoder API: implemented new api functions for streaming encoding.
### Changed / clarified
- decoder/encoder API: return failure when surface allocation fail
- encoder API / cjxl: updated modular effort levels to faster settings; the
effort range is now 1-10, with 11 available in advanced mode.
## [0.9.2] - 2024-02-07
### Fixed

2
third_party/jpeg-xl/CMakeLists.txt поставляемый
Просмотреть файл

@ -167,7 +167,7 @@ set(JPEGXL_ENABLE_WASM_TRHEADS true CACHE BOOL
set(JPEGXL_FORCE_SYSTEM_BROTLI false CACHE BOOL
"Force using system installed brotli instead of third_party/brotli source.")
set(JPEGXL_FORCE_SYSTEM_GTEST false CACHE BOOL
"Force using system installed googletest (gtest/gmock) instead of third_party/googletest source.")
"Force using system installed googletest (gtest) instead of third_party/googletest source.")
set(JPEGXL_FORCE_SYSTEM_LCMS2 false CACHE BOOL
"Force using system installed lcms2 instead of third_party/lcms source.")
set(JPEGXL_FORCE_SYSTEM_HWY false CACHE BOOL

5
third_party/jpeg-xl/MODULE.bazel поставляемый
Просмотреть файл

@ -1,4 +1,7 @@
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "giflib", version = "5.2.1")
bazel_dep(name = "googletest", version = "1.14.0")
bazel_dep(name = "openexr", version = "3.2.1")
bazel_dep(name = "libjpeg_turbo", version = "2.1.91")
bazel_dep(name = "libpng", version = "1.6.40")
bazel_dep(name = "libwebp", version = "1.3.2")
bazel_dep(name = "openexr", version = "3.2.1")

9
third_party/jpeg-xl/README.md поставляемый
Просмотреть файл

@ -73,11 +73,14 @@ To decode a JPEG XL file run:
djxl input.jxl output.png
```
When possible `cjxl`/`djxl` are able to read/write the following
image formats: .exr, .gif, .jpeg/.jpg, .pfm, .pgm/.ppm, .pgx, .png.
When possible, `cjxl`/`djxl` are able to read/write the following image formats:
OpenEXR (`.exr`), GIF (`.gif`), JPEG (`.jpg`/`.jpeg`), NetPBM (`.pam`/`.pgm`/`.ppm`),
Portable FloatMap (`.pfm`), PGX Test Format (`.pgx`), Portable Network Graphics (`.png`),
Animated PNG (`.png`/`.apng`), and JPEG XL itself (`.jxl`).
Specifically for JPEG files, the default `cjxl` behavior is to apply lossless
recompression and the default `djxl` behavior is to reconstruct the original
JPEG file (when the extension of the output file is .jpg).
JPEG file (when the extension of the output file is `.jpg`).
### Benchmarking

182
third_party/jpeg-xl/WORKSPACE поставляемый
Просмотреть файл

@ -30,185 +30,3 @@ cc_library(
""",
path = "third_party/skcms",
)
new_git_repository(
name = "libjpeg_turbo",
build_file_content = """
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
SUBSTITUTIONS = {
"@BUILD@" : "20230208",
"@CMAKE_PROJECT_NAME@" : "libjpeg-turbo",
"@COPYRIGHT_YEAR@" : "2023",
"@INLINE@" : "__inline__",
"@JPEG_LIB_VERSION@" : "62",
"@LIBJPEG_TURBO_VERSION_NUMBER@" : "2001091",
"@SIZE_T@" : "8",
"@THREAD_LOCAL@" : "__thread",
"@VERSION@" : "2.1.91",
}
YES_DEFINES = [
"C_ARITH_CODING_SUPPORTED", "D_ARITH_CODING_SUPPORTED",
"HAVE_BUILTIN_CTZL", "MEM_SRCDST_SUPPORTED"
]
NO_DEFINES = [
"WITH_SIMD", "RIGHT_SHIFT_IS_UNSIGNED", "HAVE_INTRIN_H"
]
SUBSTITUTIONS.update({
"#cmakedefine " + key : "#define " + key for key in YES_DEFINES
})
SUBSTITUTIONS.update({
"#cmakedefine " + key : "// #define " + key for key in NO_DEFINES
})
[
expand_template(
name = "expand_" + src,
template = src + ".in",
out = src,
substitutions = SUBSTITUTIONS,
visibility = ["//visibility:public"],
) for src in ["jconfig.h", "jconfigint.h", "jversion.h"]
]
JPEG16_SOURCES = [
"jccolor.c",
"jcdiffct.c",
"jclossls.c",
"jcmainct.c",
"jcprepct.c",
"jcsample.c",
"jdcolor.c",
"jddiffct.c",
"jdlossls.c",
"jdmainct.c",
"jdmerge.c",
"jdpostct.c",
"jdsample.c",
"jquant1.c",
"jquant2.c",
"jutils.c",
]
JPEG12_SOURCES = JPEG16_SOURCES + [
"jccoefct.c",
"jcdctmgr.c",
"jdcoefct.c",
"jddctmgr.c",
"jfdctfst.c",
"jfdctint.c",
"jidctflt.c",
"jidctfst.c",
"jidctint.c",
"jidctred.c",
]
JPEG_SOURCES = JPEG12_SOURCES + [
"jaricom.c",
"jcapimin.c",
"jcapistd.c",
"jcarith.c",
"jchuff.c",
"jcicc.c",
"jcinit.c",
"jclhuff.c",
"jcmarker.c",
"jcmaster.c",
"jcomapi.c",
"jcparam.c",
"jcphuff.c",
"jdapimin.c",
"jdapistd.c",
"jdarith.c",
"jdatadst.c",
"jdatasrc.c",
"jdhuff.c",
"jdicc.c",
"jdinput.c",
"jdlhuff.c",
"jdmarker.c",
"jdmaster.c",
"jdphuff.c",
"jdtrans.c",
"jerror.c",
"jfdctflt.c",
"jmemmgr.c",
"jmemnobs.c",
]
JPEG_HEADERS = [
"jccolext.c",
"jchuff.h",
"jcmaster.h",
"jconfig.h",
"jconfigint.h",
"jdcoefct.h",
"jdcol565.c",
"jdcolext.c",
"jdct.h",
"jdhuff.h",
"jdmainct.h",
"jdmaster.h",
"jdmerge.h",
"jdmrg565.c",
"jdmrgext.c",
"jdsample.h",
"jerror.h",
"jinclude.h",
"jlossls.h",
"jmemsys.h",
"jmorecfg.h",
"jpeg_nbits_table.h",
"jpegapicomp.h",
"jpegint.h",
"jpeglib.h",
"jsamplecomp.h",
"jsimd.h",
"jsimddct.h",
"jstdhuff.c",
"jversion.h",
]
cc_library(
name = "jpeg16",
srcs = JPEG16_SOURCES,
hdrs = JPEG_HEADERS,
local_defines = ["BITS_IN_JSAMPLE=16"],
visibility = ["//visibility:public"],
)
cc_library(
name = "jpeg12",
srcs = JPEG12_SOURCES,
hdrs = JPEG_HEADERS,
local_defines = ["BITS_IN_JSAMPLE=12"],
visibility = ["//visibility:public"],
)
cc_library(
name = "jpeg",
srcs = JPEG_SOURCES,
hdrs = JPEG_HEADERS,
deps = [":jpeg16", ":jpeg12"],
includes = ["."],
visibility = ["//visibility:public"],
)
exports_files([
"jmorecfg.h",
"jpeglib.h",
])
""",
remote = "https://github.com/libjpeg-turbo/libjpeg-turbo.git",
tag = "2.1.91",
)
http_archive(
name = "gif",
build_file_content = """
cc_library(
name = "gif",
srcs = [
"dgif_lib.c", "egif_lib.c", "gifalloc.c", "gif_err.c", "gif_font.c",
"gif_hash.c", "openbsd-reallocarray.c", "gif_hash.h",
"gif_lib_private.h"
],
hdrs = ["gif_lib.h"],
includes = ["."],
visibility = ["//visibility:public"],
)
""",
sha256 = "31da5562f44c5f15d63340a09a4fd62b48c45620cd302f77a6d9acf0077879bd",
strip_prefix = "giflib-5.2.1",
url = "https://netcologne.dl.sourceforge.net/project/giflib/giflib-5.2.1.tar.gz",
)

6
third_party/jpeg-xl/bash_test.sh поставляемый
Просмотреть файл

@ -106,12 +106,6 @@ test_printf_size_t() {
ret=1
fi
if grep -n -E 'gmock\.h' \
$(git ls-files | grep -E '(\.c|\.cc|\.cpp|\.h)$' | grep -v -F /testing.h); then
echo "Don't include gmock directly, instead include 'testing.h'. " >&2
ret=1
fi
local f
for f in $(git ls-files | grep -E "\.cc$" | xargs grep 'PRI[udx]S' |
cut -f 1 -d : | uniq); do

75
third_party/jpeg-xl/ci.sh поставляемый
Просмотреть файл

@ -16,6 +16,8 @@ MYDIR=$(dirname $(realpath "$0"))
### Environment parameters:
TEST_STACK_LIMIT="${TEST_STACK_LIMIT:-256}"
BENCHMARK_NUM_THREADS="${BENCHMARK_NUM_THREADS:-0}"
BUILD_CONFIG=${BUILD_CONFIG:-}
CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE:-RelWithDebInfo}
CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH:-}
CMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER:-}
@ -79,6 +81,12 @@ if [[ "${ENABLE_WASM_SIMD}" -eq "2" ]]; then
CMAKE_C_FLAGS="${CMAKE_C_FLAGS} -DHWY_WANT_WASM2"
fi
if [[ -z "${BUILD_CONFIG}" ]]; then
TOOLS_DIR="${BUILD_DIR}/tools"
else
TOOLS_DIR="${BUILD_DIR}/tools/${BUILD_CONFIG}"
fi
if [[ ! -z "${HWY_BASELINE_TARGETS}" ]]; then
CMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS} -DHWY_BASELINE_TARGETS=${HWY_BASELINE_TARGETS}"
fi
@ -128,17 +136,17 @@ if [[ "${BUILD_TARGET%%-*}" != "arm" ]]; then
)
fi
CLANG_TIDY_BIN=$(which clang-tidy-6.0 clang-tidy-7 clang-tidy-8 clang-tidy | head -n 1)
CLANG_TIDY_BIN=$(which clang-tidy-6.0 clang-tidy-7 clang-tidy-8 clang-tidy 2>/dev/null | head -n 1)
# Default to "cat" if "colordiff" is not installed or if stdout is not a tty.
if [[ -t 1 ]]; then
COLORDIFF_BIN=$(which colordiff cat | head -n 1)
COLORDIFF_BIN=$(which colordiff cat 2>/dev/null | head -n 1)
else
COLORDIFF_BIN="cat"
fi
FIND_BIN=$(which gfind find | head -n 1)
FIND_BIN=$(which gfind find 2>/dev/null | head -n 1)
# "false" will disable wine64 when not installed. This won't allow
# cross-compiling.
WINE_BIN=$(which wine64 false | head -n 1)
WINE_BIN=$(which wine64 false 2>/dev/null | head -n 1)
CLANG_VERSION="${CLANG_VERSION:-}"
# Detect the clang version suffix and store it in CLANG_VERSION. For example,
@ -411,7 +419,7 @@ cmake_build_and_test() {
if [[ "${PACK_TEST:-}" == "1" ]]; then
(cd "${BUILD_DIR}"
${FIND_BIN} -name '*.cmake' -a '!' -path '*CMakeFiles*'
# gtest / gmock / gtest_main shared libs
# gtest / gtest_main shared libs
${FIND_BIN} lib/ -name 'libg*.so*'
${FIND_BIN} -type d -name tests -a '!' -path '*CMakeFiles*'
) | tar -C "${BUILD_DIR}" -cf "${BUILD_DIR}/tests.tar.xz" -T - \
@ -791,9 +799,13 @@ cmd_ossfuzz_ninja() {
cmd_fast_benchmark() {
local small_corpus_tar="${BENCHMARK_CORPORA}/jyrki-full.tar"
local small_corpus_url="https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/jyrki-full.tar"
mkdir -p "${BENCHMARK_CORPORA}"
curl --show-error -o "${small_corpus_tar}" -z "${small_corpus_tar}" \
"https://storage.googleapis.com/artifacts.jpegxl.appspot.com/corpora/jyrki-full.tar"
if [ -f "${small_corpus_tar}" ]; then
curl --show-error -o "${small_corpus_tar}" -z "${small_corpus_tar}" "${small_corpus_url}"
else
curl --show-error -o "${small_corpus_tar}" "${small_corpus_url}"
fi
local tmpdir=$(mktemp -d)
CLEANUP_FILES+=("${tmpdir}")
@ -831,7 +843,7 @@ cmd_benchmark() {
png_filename="${filename%.ppm}.png"
png_filename=$(echo "${png_filename}" | tr '/' '_')
sem --bg --id "${sem_id}" -j"${nprocs}" -- \
"${BUILD_DIR}/tools/decode_and_encode" \
"${TOOLS_DIR}/decode_and_encode" \
"${tmpdir}/${filename}" "${mode}" "${tmpdir}/${png_filename}"
images+=( "${png_filename}" )
done < <(cd "${tmpdir}"; ${FIND_BIN} . -name '*.ppm' -type f)
@ -844,6 +856,8 @@ cmd_benchmark() {
get_mem_available() {
if [[ "${OS}" == "Darwin" ]]; then
echo $(vm_stat | grep -F 'Pages free:' | awk '{print $3 * 4}')
elif [[ "${OS}" == MINGW* ]]; then
echo $(vmstat | tail -n 1 | awk '{print $4 * 4}')
else
echo $(grep -F MemAvailable: /proc/meminfo | awk '{print $2}')
fi
@ -856,15 +870,24 @@ run_benchmark() {
local output_dir="${BUILD_DIR}/benchmark_results"
mkdir -p "${output_dir}"
# The memory available at the beginning of the benchmark run in kB. The number
# of threads depends on the available memory, and the passed memory per
# thread. We also add a 2 GiB of constant memory.
local mem_available="$(get_mem_available)"
# Check that we actually have a MemAvailable value.
[[ -n "${mem_available}" ]]
local num_threads=$(( (${mem_available} - 1048576) / ${mem_per_thread} ))
if [[ ${num_threads} -le 0 ]]; then
num_threads=1
if [[ "${OS}" == MINGW* ]]; then
src_img_dir=`cygpath -w "${src_img_dir}"`
fi
local num_threads=1
if [[ ${BENCHMARK_NUM_THREADS} -gt 0 ]]; then
num_threads=${BENCHMARK_NUM_THREADS}
else
# The memory available at the beginning of the benchmark run in kB. The number
# of threads depends on the available memory, and the passed memory per
# thread. We also add a 2 GiB of constant memory.
local mem_available="$(get_mem_available)"
# Check that we actually have a MemAvailable value.
[[ -n "${mem_available}" ]]
num_threads=$(( (${mem_available} - 1048576) / ${mem_per_thread} ))
if [[ ${num_threads} -le 0 ]]; then
num_threads=1
fi
fi
local benchmark_args=(
@ -873,20 +896,20 @@ run_benchmark() {
--output_dir "${output_dir}"
--show_progress
--num_threads="${num_threads}"
--decode_reps=11
--encode_reps=11
)
if [[ "${STORE_IMAGES}" == "1" ]]; then
benchmark_args+=(--save_decompressed --save_compressed)
fi
(
[[ "${TEST_STACK_LIMIT}" == "none" ]] || ulimit -s "${TEST_STACK_LIMIT}"
"${BUILD_DIR}/tools/benchmark_xl" "${benchmark_args[@]}" | \
"${TOOLS_DIR}/benchmark_xl" "${benchmark_args[@]}" | \
tee "${output_dir}/results.txt"
# Check error code for benckmark_xl command. This will exit if not.
return ${PIPESTATUS[0]}
)
}
# Helper function to wait for the CPU temperature to cool down on ARM.
@ -1027,7 +1050,7 @@ cmd_arm_benchmark() {
local src_img
for src_img in "${jpg_images[@]}" "${images[@]}"; do
local src_img_hash=$(sha1sum "${src_img}" | cut -f 1 -d ' ')
local enc_binaries=("${BUILD_DIR}/tools/cjxl")
local enc_binaries=("${TOOLS_DIR}/cjxl")
local src_ext="${src_img##*.}"
for enc_binary in "${enc_binaries[@]}"; do
local enc_binary_base=$(basename "${enc_binary}")
@ -1076,7 +1099,7 @@ cmd_arm_benchmark() {
local dec_output
wait_for_temp
dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
dec_output=$("${TOOLS_DIR}/djxl" "${enc_file}" \
--num_reps=5 --num_threads="${num_threads}" 2>&1 | tee /dev/stderr |
grep -E "M[BP]/s \[")
local img_size=$(echo "${dec_output}" | cut -f 1 -d ',')
@ -1092,7 +1115,7 @@ cmd_arm_benchmark() {
if [[ "${src_ext}" == "jpg" ]]; then
wait_for_temp
local dec_file="${BUILD_DIR}/arm_benchmark/${enc_file_hash}.jpg"
dec_output=$("${BUILD_DIR}/tools/djxl" "${enc_file}" \
dec_output=$("${TOOLS_DIR}/djxl" "${enc_file}" \
"${dec_file}" --num_reps=5 --num_threads="${num_threads}" 2>&1 | \
tee /dev/stderr | grep -E "M[BP]/s \[")
local jpeg_dec_mps_speed=$(_speed_from_output "${dec_output}")
@ -1122,12 +1145,12 @@ cmd_fuzz() {
local fuzzer_crash_dir=$(realpath "${BUILD_DIR}/fuzzer_crash")
mkdir -p "${corpus_dir}" "${fuzzer_crash_dir}"
# Generate step.
"${BUILD_DIR}/tools/fuzzer_corpus" "${corpus_dir}"
"${TOOLS_DIR}/fuzzer_corpus" "${corpus_dir}"
# Run step:
local nprocs=$(nproc --all || echo 1)
(
cd "${BUILD_DIR}"
"tools/djxl_fuzzer" "${fuzzer_crash_dir}" "${corpus_dir}" \
cd "${TOOLS_DIR}"
djxl_fuzzer "${fuzzer_crash_dir}" "${corpus_dir}" \
-max_total_time="${FUZZER_MAX_TIME}" -jobs=${nprocs} \
-artifact_prefix="${fuzzer_crash_dir}/"
)

1
third_party/jpeg-xl/debian/control поставляемый
Просмотреть файл

@ -11,7 +11,6 @@ Build-Depends:
libgdk-pixbuf-2.0-dev | libgdk-pixbuf2.0-dev,
libgif-dev,
libgimp2.0-dev,
libgmock-dev,
libgoogle-perftools-dev,
libgtest-dev,
libhwy-dev (>= 1.0.0),

Просмотреть файл

@ -1,2 +1,3 @@
usr/lib/*/gdk-pixbuf-*/*/loaders/*
usr/share/mime/packages/image-jxl.xml
usr/share/thumbnailers/jxl.thumbnailer

Просмотреть файл

@ -11,6 +11,7 @@
#include <jxl/decode_cxx.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <vector>
@ -55,8 +56,9 @@ bool DecodeJpegXlExif(const uint8_t* jxl, size_t size,
return true;
}
JxlBoxType type;
if (JXL_DEC_SUCCESS !=
JxlDecoderGetBoxType(dec.get(), type, support_decompression)) {
status = JxlDecoderGetBoxType(dec.get(), type,
TO_JXL_BOOL(support_decompression));
if (JXL_DEC_SUCCESS != status) {
fprintf(stderr, "Error, failed to get box type\n");
return false;
}

Просмотреть файл

@ -7,11 +7,6 @@
// available at once). The example outputs the pixels and color information to a
// floating point image and an ICC profile on disk.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#include <jxl/codestream_header.h>
#include <jxl/decode.h>
#include <jxl/decode_cxx.h>
@ -102,13 +97,13 @@ bool DecodeJpegXlOneShot(const uint8_t* jxl, size_t size,
return false;
}
if (buffer_size != *xsize * *ysize * 16) {
fprintf(stderr, "Invalid out buffer size %" PRIu64 " %" PRIu64 "\n",
static_cast<uint64_t>(buffer_size),
static_cast<uint64_t>(*xsize * *ysize * 16));
fprintf(stderr, "Invalid out buffer size %d %d\n",
static_cast<int>(buffer_size),
static_cast<int>(*xsize * *ysize * 16));
return false;
}
pixels->resize(*xsize * *ysize * 4);
void* pixels_buffer = (void*)pixels->data();
void* pixels_buffer = static_cast<void*>(pixels->data());
size_t pixels_buffer_size = pixels->size() * sizeof(float);
if (JXL_DEC_SUCCESS != JxlDecoderSetImageOutBuffer(dec.get(), &format,
pixels_buffer,
@ -147,8 +142,8 @@ bool WritePFM(const char* filename, const float* pixels, size_t xsize,
uint8_t little_endian[4];
memcpy(little_endian, &endian_test, 4);
fprintf(file, "PF\n%d %d\n%s\n", (int)xsize, (int)ysize,
little_endian[0] ? "-1.0" : "1.0");
fprintf(file, "PF\n%d %d\n%s\n", static_cast<int>(xsize),
static_cast<int>(ysize), little_endian[0] ? "-1.0" : "1.0");
for (int y = ysize - 1; y >= 0; y--) {
for (size_t x = 0; x < xsize; x++) {
for (size_t c = 0; c < 3; c++) {
@ -233,7 +228,8 @@ int main(int argc, char* argv[]) {
std::vector<float> pixels;
std::vector<uint8_t> icc_profile;
size_t xsize = 0, ysize = 0;
size_t xsize = 0;
size_t ysize = 0;
if (!DecodeJpegXlOneShot(jxl.data(), jxl.size(), &pixels, &xsize, &ysize,
&icc_profile)) {
fprintf(stderr, "Error while decoding the jxl file\n");

Просмотреть файл

@ -6,10 +6,6 @@
// This C++ example decodes a JPEG XL image progressively (input bytes are
// passed in chunks). The example outputs the intermediate steps to PAM files.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif
#include <inttypes.h>
#include <jxl/decode.h>
#include <jxl/decode_cxx.h>
@ -29,10 +25,9 @@ bool WritePAM(const char* filename, const uint8_t* buffer, size_t w, size_t h) {
return false;
}
fprintf(fp,
"P7\nWIDTH %" PRIu64 "\nHEIGHT %" PRIu64
"\nDEPTH 4\nMAXVAL 255\nTUPLTYPE "
"P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\nTUPLTYPE "
"RGB_ALPHA\nENDHDR\n",
static_cast<uint64_t>(w), static_cast<uint64_t>(h));
static_cast<int>(w), static_cast<int>(h));
size_t num_bytes = w * h * 4;
if (fwrite(buffer, 1, num_bytes, fp) != num_bytes) {
fclose(fp);
@ -51,7 +46,8 @@ bool DecodeJpegXlProgressive(const uint8_t* jxl, size_t size,
const char* filename, size_t chunksize) {
std::vector<uint8_t> pixels;
std::vector<uint8_t> icc_profile;
size_t xsize = 0, ysize = 0;
size_t xsize = 0;
size_t ysize = 0;
// Multi-threaded parallel runner.
auto runner = JxlResizableParallelRunnerMake(nullptr);

Просмотреть файл

@ -39,8 +39,9 @@ bool ReadPFM(const char* filename, std::vector<float>* pixels, uint32_t* xsize,
return false;
}
uint32_t endian_test = 1;
uint8_t little_endian[4];
memcpy(little_endian, &endian_test, 4);
uint8_t little_endian_check[4];
memcpy(little_endian_check, &endian_test, 4);
bool little_endian = (little_endian_check[0] == 1);
if (fseek(file, 0, SEEK_END) != 0) {
fclose(file);
@ -63,7 +64,7 @@ bool ReadPFM(const char* filename, std::vector<float>* pixels, uint32_t* xsize,
data.resize(size);
size_t readsize = fread(data.data(), 1, size, file);
if ((long)readsize != size) {
if (static_cast<long>(readsize) != size) {
fclose(file);
return false;
}
@ -116,12 +117,13 @@ bool ReadPFM(const char* filename, std::vector<float>* pixels, uint32_t* xsize,
fprintf(stderr,
"%s doesn't seem to be a Portable FloatMap file (pixel data bytes "
"are %d, but expected %d * %d * 3 * 4 + %d (%d).\n",
filename, (int)data.size(), (int)*ysize, (int)*xsize, (int)offset,
(int)(*ysize * *xsize * 3 * 4 + offset));
filename, static_cast<int>(data.size()), static_cast<int>(*ysize),
static_cast<int>(*xsize), static_cast<int>(offset),
static_cast<int>(*ysize * *xsize * 3 * 4 + offset));
return false;
}
if (!!little_endian[0] != input_little_endian) {
if (little_endian != input_little_endian) {
fprintf(stderr,
"%s has a different endianness than we do, conversion is not "
"supported.\n",
@ -132,7 +134,7 @@ bool ReadPFM(const char* filename, std::vector<float>* pixels, uint32_t* xsize,
pixels->resize(*ysize * *xsize * 3);
for (int y = *ysize - 1; y >= 0; y--) {
for (int x = 0; x < (int)*xsize; x++) {
for (int x = 0; x < static_cast<int>(*xsize); x++) {
for (int c = 0; c < 3; c++) {
memcpy(pixels->data() + (y * *xsize + x) * 3 + c, data.data() + offset,
sizeof(float));
@ -180,8 +182,8 @@ bool EncodeJxlOneshot(const std::vector<float>& pixels, const uint32_t xsize,
}
JxlColorEncoding color_encoding = {};
JxlColorEncodingSetToSRGB(&color_encoding,
/*is_gray=*/pixel_format.num_channels < 3);
JXL_BOOL is_gray = TO_JXL_BOOL(pixel_format.num_channels < 3);
JxlColorEncodingSetToSRGB(&color_encoding, is_gray);
if (JXL_ENC_SUCCESS !=
JxlEncoderSetColorEncoding(enc.get(), &color_encoding)) {
fprintf(stderr, "JxlEncoderSetColorEncoding failed\n");
@ -193,7 +195,7 @@ bool EncodeJxlOneshot(const std::vector<float>& pixels, const uint32_t xsize,
if (JXL_ENC_SUCCESS !=
JxlEncoderAddImageFrame(frame_settings, &pixel_format,
(void*)pixels.data(),
static_cast<const void*>(pixels.data()),
sizeof(float) * pixels.size())) {
fprintf(stderr, "JxlEncoderAddImageFrame failed\n");
return false;

1
third_party/jpeg-xl/flake.nix поставляемый
Просмотреть файл

@ -19,7 +19,6 @@
cmake
pkg-config
gtest
gmock
doxygen
graphviz
python3

11
third_party/jpeg-xl/lib/BUILD поставляемый
Просмотреть файл

@ -23,8 +23,8 @@ load(
"libjxl_enc_sources",
"libjxl_extras_for_tools_sources",
"libjxl_extras_sources",
#'libjxl_gbench_sources',
"libjxl_jpegli_lib_version",
# "libjxl_gbench_sources",
# "libjxl_jpegli_lib_version",
"libjxl_jpegli_libjpeg_helper_files",
"libjxl_jpegli_sources",
"libjxl_jpegli_testlib_files",
@ -51,13 +51,14 @@ load(
"libjxl_deps_png",
"libjxl_deps_runfiles",
"libjxl_deps_skcms",
"libjxl_deps_testdata",
# "libjxl_deps_testdata",
# "libjxl_deps_webp",
"libjxl_root_package",
"libjxl_test_shards",
"libjxl_test_timeouts",
)
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
load("@bazel_skylib//rules:copy_file.bzl", "copy_file")
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
DEFAULT_VISIBILITY = ["//:__subpackages__"]
@ -66,7 +67,7 @@ DEFAULT_COMPATIBILITY = []
INCLUDES_DIR = "include"
package(
default_visibility = ["//:__subpackages__"],
default_visibility = DEFAULT_VISIBILITY,
)
licenses(["notice"])

Просмотреть файл

@ -12,7 +12,7 @@ namespace extras {
namespace {
void AlphaBlend(PackedFrame* frame, float background[3]) {
void AlphaBlend(PackedFrame* frame, const float background[3]) {
if (!frame) return;
const PackedImage& im = frame->color;
JxlPixelFormat format = im.format;
@ -20,7 +20,8 @@ void AlphaBlend(PackedFrame* frame, float background[3]) {
return;
}
--format.num_channels;
PackedImage blended(im.xsize, im.ysize, format);
JXL_ASSIGN_OR_DIE(PackedImage blended,
PackedImage::Create(im.xsize, im.ysize, format));
// TODO(szabadka) SIMDify this and make it work for float16.
for (size_t y = 0; y < im.ysize; ++y) {
for (size_t x = 0; x < im.xsize; ++x) {
@ -48,7 +49,7 @@ void AlphaBlend(PackedFrame* frame, float background[3]) {
} // namespace
void AlphaBlend(PackedPixelFile* ppf, float background[3]) {
void AlphaBlend(PackedPixelFile* ppf, const float background[3]) {
if (!ppf || ppf->info.alpha_bits == 0) {
return;
}

Просмотреть файл

@ -11,7 +11,7 @@
namespace jxl {
namespace extras {
void AlphaBlend(PackedPixelFile* ppf, float background[3]);
void AlphaBlend(PackedPixelFile* ppf, const float background[3]);
} // namespace extras
} // namespace jxl

2
third_party/jpeg-xl/lib/extras/codec.h поставляемый
Просмотреть файл

@ -43,7 +43,7 @@ JXL_INLINE Status SetFromBytes(const Span<const uint8_t> bytes, CodecInOut* io,
orig_codec);
}
Status Encode(const extras::PackedPixelFile& ppf, const extras::Codec codec,
Status Encode(const extras::PackedPixelFile& ppf, extras::Codec codec,
std::vector<uint8_t>* bytes, ThreadPool* pool);
Status Encode(const extras::PackedPixelFile& ppf, const std::string& pathname,

36
third_party/jpeg-xl/lib/extras/codec_test.cc поставляемый
Просмотреть файл

@ -40,12 +40,6 @@ using test::ThreadPoolForTests;
namespace extras {
namespace {
using ::testing::AllOf;
using ::testing::Contains;
using ::testing::Field;
using ::testing::IsEmpty;
using ::testing::SizeIs;
std::string ExtensionFromCodec(Codec codec, const bool is_gray,
const bool has_alpha,
const size_t bits_per_sample) {
@ -78,8 +72,8 @@ void VerifySameImage(const PackedImage& im0, size_t bits_per_sample0,
};
double factor0 = get_factor(im0.format, bits_per_sample0);
double factor1 = get_factor(im1.format, bits_per_sample1);
auto pixels0 = static_cast<const uint8_t*>(im0.pixels());
auto pixels1 = static_cast<const uint8_t*>(im1.pixels());
const auto* pixels0 = static_cast<const uint8_t*>(im0.pixels());
const auto* pixels1 = static_cast<const uint8_t*>(im1.pixels());
auto rgba0 =
test::ConvertToRGBA32(pixels0, im0.xsize, im0.ysize, im0.format, factor0);
auto rgba1 =
@ -227,19 +221,23 @@ void CreateTestImage(const TestImageParams& params, PackedPixelFile* ppf) {
ppf->info.exponent_bits_per_sample = params.bits_per_sample == 32 ? 8 : 0;
ppf->info.num_color_channels = params.is_gray ? 1 : 3;
ppf->info.alpha_bits = params.add_alpha ? params.bits_per_sample : 0;
ppf->info.alpha_premultiplied = (params.codec == Codec::kEXR);
ppf->info.alpha_premultiplied = TO_JXL_BOOL(params.codec == Codec::kEXR);
JxlColorEncoding color_encoding = CreateTestColorEncoding(params.is_gray);
ppf->icc = GenerateICC(color_encoding);
ppf->color_encoding = color_encoding;
PackedFrame frame(params.xsize, params.ysize, params.PixelFormat());
JXL_ASSIGN_OR_DIE(
PackedFrame frame,
PackedFrame::Create(params.xsize, params.ysize, params.PixelFormat()));
FillPackedImage(params.bits_per_sample, &frame.color);
if (params.add_extra_channels) {
for (size_t i = 0; i < 7; ++i) {
JxlPixelFormat ec_format = params.PixelFormat();
ec_format.num_channels = 1;
PackedImage ec(params.xsize, params.ysize, ec_format);
JXL_ASSIGN_OR_DIE(
PackedImage ec,
PackedImage::Create(params.xsize, params.ysize, ec_format));
FillPackedImage(params.bits_per_sample, &ec);
frame.extra_channels.emplace_back(std::move(ec));
PackedExtraChannel pec;
@ -432,15 +430,17 @@ TEST(CodecTest, EncodeToPNG) {
ASSERT_TRUE(extras::DecodeBytes(Bytes(original_png), ColorHints(), &ppf));
const JxlPixelFormat& format = ppf.frames.front().color.format;
ASSERT_THAT(
png_encoder->AcceptedFormats(),
Contains(AllOf(Field(&JxlPixelFormat::num_channels, format.num_channels),
Field(&JxlPixelFormat::data_type, format.data_type),
Field(&JxlPixelFormat::endianness, format.endianness))));
const auto& format_matcher = [&format](const JxlPixelFormat& candidate) {
return (candidate.num_channels == format.num_channels) &&
(candidate.data_type == format.data_type) &&
(candidate.endianness == format.endianness);
};
const auto formats = png_encoder->AcceptedFormats();
ASSERT_TRUE(std::any_of(formats.begin(), formats.end(), format_matcher));
EncodedImage encoded_png;
ASSERT_TRUE(png_encoder->Encode(ppf, &encoded_png, pool));
EXPECT_THAT(encoded_png.icc, IsEmpty());
ASSERT_THAT(encoded_png.bitstreams, SizeIs(1));
EXPECT_TRUE(encoded_png.icc.empty());
ASSERT_EQ(encoded_png.bitstreams.size(), 1);
PackedPixelFile decoded_ppf;
ASSERT_TRUE(extras::DecodeBytes(Bytes(encoded_png.bitstreams.front()),

114
third_party/jpeg-xl/lib/extras/dec/apng.cc поставляемый
Просмотреть файл

@ -71,9 +71,7 @@ const png_byte kIgnoredPngChunks[] = {
};
// Returns floating-point value from the PNG encoding (times 10^5).
static double F64FromU32(const uint32_t x) {
return static_cast<int32_t>(x) * 1E-5;
}
double F64FromU32(const uint32_t x) { return static_cast<int32_t>(x) * 1E-5; }
Status DecodeSRGB(const unsigned char* payload, const size_t payload_size,
JxlColorEncoding* color_encoding) {
@ -402,7 +400,8 @@ class BlobsReaderPNG {
}
if (pos + 2 >= encoded_end) return false; // Truncated base16 2;
uint32_t nibble0, nibble1;
uint32_t nibble0;
uint32_t nibble1;
JXL_RETURN_IF_ERROR(DecodeNibble(pos[0], &nibble0));
JXL_RETURN_IF_ERROR(DecodeNibble(pos[1], &nibble1));
bytes->push_back(static_cast<uint8_t>((nibble0 << 4) + nibble1));
@ -432,9 +431,22 @@ constexpr uint32_t kId_cHRM = 0x4D524863;
constexpr uint32_t kId_eXIf = 0x66495865;
struct APNGFrame {
std::vector<uint8_t> pixels;
APNGFrame() : pixels(nullptr, free) {}
std::unique_ptr<void, decltype(free)*> pixels;
size_t pixels_size = 0;
std::vector<uint8_t*> rows;
unsigned int w, h, delay_num, delay_den;
Status Resize(size_t new_size) {
if (new_size > pixels_size) {
pixels.reset(malloc(new_size));
if (!pixels.get()) {
// TODO(szabadka): use specialized OOM error code
return JXL_FAILURE("Failed to allocate memory for image buffer");
}
pixels_size = new_size;
}
return true;
}
};
struct Reader {
@ -447,7 +459,7 @@ struct Reader {
next += to_copy;
return (len == to_copy);
}
bool Eof() { return next == last; }
bool Eof() const { return next == last; }
};
const unsigned long cMaxPNGSize = 1000000UL;
@ -463,10 +475,11 @@ void info_fn(png_structp png_ptr, png_infop info_ptr) {
void row_fn(png_structp png_ptr, png_bytep new_row, png_uint_32 row_num,
int pass) {
APNGFrame* frame = (APNGFrame*)png_get_progressive_ptr(png_ptr);
APNGFrame* frame =
reinterpret_cast<APNGFrame*>(png_get_progressive_ptr(png_ptr));
JXL_CHECK(frame);
JXL_CHECK(row_num < frame->rows.size());
JXL_CHECK(frame->rows[row_num] < frame->pixels.data() + frame->pixels.size());
JXL_CHECK(frame->rows[row_num] < frame->rows[0] + frame->pixels_size);
png_progressive_combine_row(png_ptr, frame->rows[row_num], new_row);
}
@ -494,12 +507,13 @@ int processing_start(png_structp& png_ptr, png_infop& info_ptr, void* frame_ptr,
unsigned char header[8] = {137, 80, 78, 71, 13, 10, 26, 10};
// Cleanup prior decoder, if any.
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
// Just in case. Not all versions on libpng wipe-out the pointers.
png_ptr = nullptr;
info_ptr = nullptr;
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_ptr =
png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
info_ptr = png_create_info_struct(png_ptr);
if (!png_ptr || !info_ptr) return 1;
@ -508,18 +522,17 @@ int processing_start(png_structp& png_ptr, png_infop& info_ptr, void* frame_ptr,
}
png_set_keep_unknown_chunks(png_ptr, 1, kIgnoredPngChunks,
(int)sizeof(kIgnoredPngChunks) / 5);
static_cast<int>(sizeof(kIgnoredPngChunks) / 5));
png_set_crc_action(png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
png_set_progressive_read_fn(png_ptr, frame_ptr, info_fn, row_fn, NULL);
png_set_progressive_read_fn(png_ptr, frame_ptr, info_fn, row_fn, nullptr);
png_process_data(png_ptr, info_ptr, header, 8);
png_process_data(png_ptr, info_ptr, chunkIHDR.data(), chunkIHDR.size());
if (hasInfo) {
for (unsigned int i = 0; i < chunksInfo.size(); i++) {
png_process_data(png_ptr, info_ptr, chunksInfo[i].data(),
chunksInfo[i].size());
for (auto& chunk : chunksInfo) {
png_process_data(png_ptr, info_ptr, chunk.data(), chunk.size());
}
}
return 0;
@ -575,8 +588,6 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
const SizeConstraints* constraints) {
#if JPEGXL_ENABLE_APNG
Reader r;
unsigned int id, j, w, h, w0, h0, x0, y0;
unsigned int delay_num, delay_den, dop, bop, rowbytes, imagesize;
unsigned char sig[8];
png_structp png_ptr = nullptr;
png_infop info_ptr = nullptr;
@ -588,7 +599,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
bool seenFctl = false;
APNGFrame frameRaw = {};
uint32_t num_channels;
JxlPixelFormat format;
JxlPixelFormat format = {};
unsigned int bytes_per_pixel = 0;
struct FrameInfo {
@ -604,7 +615,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
// Make sure png memory is released in any case.
auto scope_guard = MakeScopeGuard([&]() {
png_destroy_read_struct(&png_ptr, &info_ptr, 0);
png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
// Just in case. Not all versions on libpng wipe-out the pointers.
png_ptr = nullptr;
info_ptr = nullptr;
@ -616,7 +627,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
if (!r.Read(sig, 8) || memcmp(sig, png_signature, 8) != 0) {
return false;
}
id = read_chunk(&r, &chunkIHDR);
unsigned int id = read_chunk(&r, &chunkIHDR);
ppf->info.exponent_bits_per_sample = 0;
ppf->info.alpha_exponent_bits = 0;
@ -625,18 +636,22 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
ppf->frames.clear();
bool have_color = false;
bool have_cicp = false, have_iccp = false, have_srgb = false;
bool have_cicp = false;
bool have_iccp = false;
bool have_srgb = false;
bool errorstate = true;
if (id == kId_IHDR && chunkIHDR.size() == 25) {
x0 = 0;
y0 = 0;
delay_num = 1;
delay_den = 10;
dop = 0;
bop = 0;
unsigned int x0 = 0;
unsigned int y0 = 0;
unsigned int delay_num = 1;
unsigned int delay_den = 10;
unsigned int dop = 0;
unsigned int bop = 0;
w0 = w = png_get_uint_32(chunkIHDR.data() + 8);
h0 = h = png_get_uint_32(chunkIHDR.data() + 12);
unsigned int w = png_get_uint_32(chunkIHDR.data() + 8);
unsigned int h = png_get_uint_32(chunkIHDR.data() + 12);
unsigned int w0 = w;
unsigned int h0 = h;
if (w > cMaxPNGSize || h > cMaxPNGSize) {
return false;
}
@ -648,8 +663,8 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
ppf->color_encoding.transfer_function = JXL_TRANSFER_FUNCTION_SRGB;
ppf->color_encoding.rendering_intent = JXL_RENDERING_INTENT_RELATIVE;
if (!processing_start(png_ptr, info_ptr, (void*)&frameRaw, hasInfo,
chunkIHDR, chunksInfo)) {
if (!processing_start(png_ptr, info_ptr, static_cast<void*>(&frameRaw),
hasInfo, chunkIHDR, chunksInfo)) {
while (!r.Eof()) {
id = read_chunk(&r, &chunk);
if (!id) break;
@ -657,7 +672,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
if (id == kId_acTL && !hasInfo && !isAnimated) {
isAnimated = true;
ppf->info.have_animation = true;
ppf->info.have_animation = JXL_TRUE;
ppf->info.animation.tps_numerator = 1000;
ppf->info.animation.tps_denominator = 1;
} else if (id == kId_IEND ||
@ -666,8 +681,10 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
if (!processing_finish(png_ptr, info_ptr, &ppf->metadata)) {
// Allocates the frame buffer.
uint32_t duration = delay_num * 1000 / delay_den;
frames.push_back(FrameInfo{PackedImage(w0, h0, format), duration,
x0, w0, y0, h0, dop, bop});
JXL_ASSIGN_OR_RETURN(PackedImage image,
PackedImage::Create(w0, h0, format));
frames.push_back(FrameInfo{std::move(image), duration, x0, w0, y0,
h0, dop, bop});
auto& frame = frames.back().data;
for (size_t y = 0; y < h0; ++y) {
memcpy(static_cast<uint8_t*>(frame.pixels()) + frame.stride * y,
@ -707,7 +724,8 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
if (hasInfo) {
memcpy(chunkIHDR.data() + 8, chunk.data() + 12, 8);
if (processing_start(png_ptr, info_ptr, (void*)&frameRaw, hasInfo,
if (processing_start(png_ptr, info_ptr,
static_cast<void*>(&frameRaw), hasInfo,
chunkIHDR, chunksInfo)) {
break;
}
@ -724,7 +742,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
int colortype = png_get_color_type(png_ptr, info_ptr);
int png_bit_depth = png_get_bit_depth(png_ptr, info_ptr);
ppf->info.bits_per_sample = png_bit_depth;
png_color_8p sigbits = NULL;
png_color_8p sigbits = nullptr;
png_get_sBIT(png_ptr, info_ptr, &sigbits);
if (colortype & 1) {
// palette will actually be 8-bit regardless of the index bitdepth
@ -784,12 +802,18 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
}
bytes_per_pixel =
num_channels * (format.data_type == JXL_TYPE_UINT16 ? 2 : 1);
rowbytes = w * bytes_per_pixel;
imagesize = h * rowbytes;
frameRaw.pixels.resize(imagesize);
size_t rowbytes = w * bytes_per_pixel;
if (h > std::numeric_limits<size_t>::max() / rowbytes) {
return JXL_FAILURE("Image too big.");
}
size_t imagesize = h * rowbytes;
JXL_RETURN_IF_ERROR(frameRaw.Resize(imagesize));
frameRaw.rows.resize(h);
for (j = 0; j < h; j++)
frameRaw.rows[j] = frameRaw.pixels.data() + j * rowbytes;
for (size_t j = 0; j < h; j++) {
frameRaw.rows[j] =
reinterpret_cast<uint8_t*>(frameRaw.pixels.get()) +
j * rowbytes;
}
if (processing_data(png_ptr, info_ptr, chunk.data(), chunk.size())) {
break;
@ -925,7 +949,8 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
py0 + pys >= y0 + ysize && use_for_next_frame) {
// If the new frame is contained within the old frame, we can pad the
// new frame with zeros and not blend.
PackedImage new_data(pxs, pys, frame.data.format);
JXL_ASSIGN_OR_RETURN(PackedImage new_data,
PackedImage::Create(pxs, pys, frame.data.format));
memset(new_data.pixels(), 0, new_data.pixels_size);
for (size_t y = 0; y < ysize; y++) {
size_t bytes_per_pixel =
@ -947,7 +972,8 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
ppf->frames.emplace_back(std::move(new_data));
} else {
// If all else fails, insert a placeholder blank frame with kReplace.
PackedImage blank(pxs, pys, frame.data.format);
JXL_ASSIGN_OR_RETURN(PackedImage blank,
PackedImage::Create(pxs, pys, frame.data.format));
memset(blank.pixels(), 0, blank.pixels_size);
ppf->frames.emplace_back(std::move(blank));
auto& pframe = ppf->frames.back();
@ -987,7 +1013,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
has_nontrivial_background && frame.dispose_op == DISPOSE_OP_BACKGROUND;
}
if (ppf->frames.empty()) return JXL_FAILURE("No frames decoded");
ppf->frames.back().frame_info.is_last = true;
ppf->frames.back().frame_info.is_last = JXL_TRUE;
return true;
#else

Просмотреть файл

@ -9,6 +9,8 @@
#include <cmath>
#include "lib/jxl/base/common.h"
namespace jxl {
namespace {
@ -19,49 +21,46 @@ struct EnumName {
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},
};
constexpr auto kJxlColorSpaceNames =
to_array<EnumName<JxlColorSpace>>({{"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},
};
constexpr auto kJxlWhitePointNames =
to_array<EnumName<JxlWhitePoint>>({{"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},
};
constexpr auto kJxlPrimariesNames =
to_array<EnumName<JxlPrimaries>>({{"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},
};
constexpr auto kJxlTransferFunctionNames =
to_array<EnumName<JxlTransferFunction>>(
{{"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},
};
constexpr auto kJxlRenderingIntentNames =
to_array<EnumName<JxlRenderingIntent>>(
{{"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) {
for (size_t i = 0; i < enum_len; i++) {
template <typename T, size_t N>
Status ParseEnum(const std::string& token,
const std::array<EnumName<T>, N>& enum_values, T* value) {
for (size_t i = 0; i < enum_values.size(); i++) {
if (enum_values[i].name == token) {
*value = enum_values[i].value;
return true;
@ -69,9 +68,6 @@ Status ParseEnum(const std::string& token, const EnumName<T>* enum_values,
}
return false;
}
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
#define PARSE_ENUM(type, token, value) \
ParseEnum<type>(token, k##type##Names, ARRAY_SIZE(k##type##Names), value)
class Tokenizer {
public:
@ -122,7 +118,7 @@ Status ParseColorSpace(Tokenizer* tokenizer, JxlColorEncoding* c) {
std::string str;
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
JxlColorSpace cs;
if (PARSE_ENUM(JxlColorSpace, str, &cs)) {
if (ParseEnum(str, kJxlColorSpaceNames, &cs)) {
c->color_space = cs;
return true;
}
@ -139,7 +135,7 @@ Status ParseWhitePoint(Tokenizer* tokenizer, JxlColorEncoding* c) {
std::string str;
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
if (PARSE_ENUM(JxlWhitePoint, str, &c->white_point)) return true;
if (ParseEnum(str, kJxlWhitePointNames, &c->white_point)) return true;
Tokenizer xy_tokenizer(&str, ';');
c->white_point = JXL_WHITE_POINT_CUSTOM;
@ -157,7 +153,7 @@ Status ParsePrimaries(Tokenizer* tokenizer, JxlColorEncoding* c) {
std::string str;
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
if (PARSE_ENUM(JxlPrimaries, str, &c->primaries)) return true;
if (ParseEnum(str, kJxlPrimariesNames, &c->primaries)) return true;
Tokenizer xy_tokenizer(&str, ';');
JXL_RETURN_IF_ERROR(ParseDouble(&xy_tokenizer, c->primaries_red_xy + 0));
@ -174,7 +170,8 @@ Status ParsePrimaries(Tokenizer* tokenizer, JxlColorEncoding* c) {
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;
if (ParseEnum(str, kJxlRenderingIntentNames, &c->rendering_intent))
return true;
return JXL_FAILURE("Invalid RenderingIntent %s\n", str.c_str());
}
@ -189,7 +186,7 @@ Status ParseTransferFunction(Tokenizer* tokenizer, JxlColorEncoding* c) {
std::string str;
JXL_RETURN_IF_ERROR(tokenizer->Next(&str));
if (PARSE_ENUM(JxlTransferFunction, str, &c->transfer_function)) {
if (ParseEnum(str, kJxlTransferFunctionNames, &c->transfer_function)) {
return true;
}

Просмотреть файл

@ -35,7 +35,8 @@ std::string GetExtension(const std::string& path) {
} // namespace
Codec CodecFromPath(std::string path, size_t* JXL_RESTRICT bits_per_sample,
Codec CodecFromPath(const std::string& path,
size_t* JXL_RESTRICT bits_per_sample,
std::string* extension) {
std::string ext = GetExtension(path);
if (extension) {
@ -98,7 +99,7 @@ Status DecodeBytes(const Span<const uint8_t> bytes,
*ppf = extras::PackedPixelFile();
// Default values when not set by decoders.
ppf->info.uses_original_profile = true;
ppf->info.uses_original_profile = JXL_TRUE;
ppf->info.orientation = JXL_ORIENT_IDENTITY;
const auto choose_codec = [&]() -> Codec {
@ -116,6 +117,7 @@ Status DecodeBytes(const Span<const uint8_t> bytes,
dparams.accepted_formats.push_back(
{num_channels, JXL_TYPE_FLOAT, JXL_LITTLE_ENDIAN, /*align=*/0});
}
dparams.output_bitdepth.type = JXL_BIT_DEPTH_FROM_CODESTREAM;
size_t decoded_bytes;
if (DecodeImageJXL(bytes.data(), bytes.size(), dparams, &decoded_bytes,
ppf) &&

2
third_party/jpeg-xl/lib/extras/dec/decode.h поставляемый
Просмотреть файл

@ -40,7 +40,7 @@ bool CanDecode(Codec codec);
// If and only if extension is ".pfm", *bits_per_sample is updated to 32 so
// that Encode() would encode to PFM instead of PPM.
Codec CodecFromPath(std::string path,
Codec CodecFromPath(const std::string& path,
size_t* JXL_RESTRICT bits_per_sample = nullptr,
std::string* extension = nullptr);

9
third_party/jpeg-xl/lib/extras/dec/exr.cc поставляемый
Просмотреть файл

@ -121,7 +121,12 @@ Status DecodeImageEXR(Span<const uint8_t> bytes, const ColorHints& color_hints,
};
ppf->frames.clear();
// Allocates the frame buffer.
ppf->frames.emplace_back(image_size.x, image_size.y, format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(image_size.x, image_size.y, format));
ppf->frames.emplace_back(std::move(frame));
}
const auto& frame = ppf->frames.back();
const int row_size = input.dataWindow().size().x + 1;
@ -188,7 +193,7 @@ Status DecodeImageEXR(Span<const uint8_t> bytes, const ColorHints& color_hints,
if (has_alpha) {
ppf->info.alpha_bits = kExrAlphaBits;
ppf->info.alpha_exponent_bits = ppf->info.exponent_bits_per_sample;
ppf->info.alpha_premultiplied = true;
ppf->info.alpha_premultiplied = JXL_TRUE;
}
ppf->info.intensity_target = intensity_target;
return true;

28
third_party/jpeg-xl/lib/extras/dec/gif.cc поставляемый
Просмотреть файл

@ -50,8 +50,10 @@ void ensure_have_alpha(PackedFrame* frame) {
/*endianness=*/JXL_NATIVE_ENDIAN,
/*align=*/0,
};
frame->extra_channels.emplace_back(frame->color.xsize, frame->color.ysize,
alpha_format);
JXL_ASSIGN_OR_DIE(PackedImage image,
PackedImage::Create(frame->color.xsize, frame->color.ysize,
alpha_format));
frame->extra_channels.emplace_back(std::move(image));
// We need to set opaque-by-default.
std::fill_n(static_cast<uint8_t*>(frame->extra_channels[0].pixels()),
frame->color.xsize * frame->color.ysize, 255u);
@ -136,7 +138,7 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, const ColorHints& color_hints,
}
if (gif->ImageCount > 1) {
ppf->info.have_animation = true;
ppf->info.have_animation = JXL_TRUE;
// Delays in GIF are specified in 100ths of a second.
ppf->info.animation.tps_numerator = 100;
ppf->info.animation.tps_denominator = 1;
@ -186,7 +188,9 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, const ColorHints& color_hints,
}
const PackedRgba background_rgba{background_color.Red, background_color.Green,
background_color.Blue, 0};
PackedFrame canvas(gif->SWidth, gif->SHeight, canvas_format);
JXL_ASSIGN_OR_RETURN(
PackedFrame canvas,
PackedFrame::Create(gif->SWidth, gif->SHeight, canvas_format));
std::fill_n(static_cast<PackedRgba*>(canvas.color.pixels()),
canvas.color.xsize * canvas.color.ysize, background_rgba);
Rect canvas_rect{0, 0, canvas.color.xsize, canvas.color.ysize};
@ -230,8 +234,14 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, const ColorHints& color_hints,
}
// Allocates the frame buffer.
ppf->frames.emplace_back(total_rect.xsize(), total_rect.ysize(),
packed_frame_format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(total_rect.xsize(), total_rect.ysize(),
packed_frame_format));
ppf->frames.emplace_back(std::move(frame));
}
PackedFrame* frame = &ppf->frames.back();
// We cannot tell right from the start whether there will be a
@ -301,8 +311,10 @@ Status DecodeImageGIF(Span<const uint8_t> bytes, const ColorHints& color_hints,
}
// Update the canvas by creating a copy first.
PackedImage new_canvas_image(canvas.color.xsize, canvas.color.ysize,
canvas.color.format);
JXL_ASSIGN_OR_RETURN(
PackedImage new_canvas_image,
PackedImage::Create(canvas.color.xsize, canvas.color.ysize,
canvas.color.format));
memcpy(new_canvas_image.pixels(), canvas.color.pixels(),
new_canvas_image.pixels_size);
for (size_t y = 0, byte_index = 0; y < image_rect.ysize(); ++y) {

13
third_party/jpeg-xl/lib/extras/dec/jpegli.cc поставляемый
Просмотреть файл

@ -27,7 +27,7 @@ constexpr unsigned char kExifSignature[6] = {0x45, 0x78, 0x69,
constexpr int kExifMarker = JPEG_APP0 + 1;
constexpr int kICCMarker = JPEG_APP0 + 2;
static inline bool IsJPG(const std::vector<uint8_t>& bytes) {
inline bool IsJPG(const std::vector<uint8_t>& bytes) {
if (bytes.size() < 2) return false;
if (bytes[0] != 0xFF || bytes[1] != 0xD8) return false;
return true;
@ -218,7 +218,7 @@ Status DecodeJpeg(const std::vector<uint8_t>& compressed,
} else {
return failure("unsupported data type");
}
ppf->info.uses_original_profile = true;
ppf->info.uses_original_profile = JXL_TRUE;
// No alpha in JPG
ppf->info.alpha_bits = 0;
@ -232,7 +232,7 @@ Status DecodeJpeg(const std::vector<uint8_t>& compressed,
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = dparams.num_colors;
cinfo.two_pass_quantize = static_cast<boolean>(dparams.two_pass_quant);
cinfo.dither_mode = (J_DITHER_MODE)dparams.dither_mode;
cinfo.dither_mode = static_cast<J_DITHER_MODE>(dparams.dither_mode);
}
jpegli_start_decompress(&cinfo);
@ -246,7 +246,12 @@ Status DecodeJpeg(const std::vector<uint8_t>& compressed,
};
ppf->frames.clear();
// Allocates the frame buffer.
ppf->frames.emplace_back(cinfo.image_width, cinfo.image_height, format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(cinfo.image_width, cinfo.image_height, format));
ppf->frames.emplace_back(std::move(frame));
}
const auto& frame = ppf->frames.back();
JXL_ASSERT(sizeof(JSAMPLE) * cinfo.out_color_components *
cinfo.image_width <=

22
third_party/jpeg-xl/lib/extras/dec/jpg.cc поставляемый
Просмотреть файл

@ -34,7 +34,7 @@ constexpr unsigned char kExifSignature[6] = {0x45, 0x78, 0x69,
0x66, 0x00, 0x00};
constexpr int kExifMarker = JPEG_APP0 + 1;
static inline bool IsJPG(const Span<const uint8_t> bytes) {
inline bool IsJPG(const Span<const uint8_t> bytes) {
if (bytes.size() < 2) return false;
if (bytes[0] != 0xFF || bytes[1] != 0xD8) return false;
return true;
@ -270,7 +270,7 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes,
ppf->info.bits_per_sample = BITS_IN_JSAMPLE;
JXL_ASSERT(BITS_IN_JSAMPLE == 8 || BITS_IN_JSAMPLE == 16);
ppf->info.exponent_bits_per_sample = 0;
ppf->info.uses_original_profile = true;
ppf->info.uses_original_profile = JXL_TRUE;
// No alpha in JPG
ppf->info.alpha_bits = 0;
@ -283,7 +283,7 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes,
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = dparams->num_colors;
cinfo.two_pass_quantize = static_cast<boolean>(dparams->two_pass_quant);
cinfo.dither_mode = (J_DITHER_MODE)dparams->dither_mode;
cinfo.dither_mode = static_cast<J_DITHER_MODE>(dparams->dither_mode);
}
jpeg_start_decompress(&cinfo);
@ -299,19 +299,25 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes,
};
ppf->frames.clear();
// Allocates the frame buffer.
ppf->frames.emplace_back(cinfo.image_width, cinfo.image_height, format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(cinfo.image_width, cinfo.image_height, format));
ppf->frames.emplace_back(std::move(frame));
}
const auto& frame = ppf->frames.back();
JXL_ASSERT(sizeof(JSAMPLE) * cinfo.out_color_components *
cinfo.image_width <=
frame.color.stride);
if (cinfo.quantize_colors) {
jxl::msan::UnpoisonMemory(cinfo.colormap, cinfo.out_color_components *
sizeof(cinfo.colormap[0]));
JSAMPLE** colormap = cinfo.colormap;
jxl::msan::UnpoisonMemory(reinterpret_cast<void*>(colormap),
cinfo.out_color_components * sizeof(JSAMPLE*));
for (int c = 0; c < cinfo.out_color_components; ++c) {
jxl::msan::UnpoisonMemory(
cinfo.colormap[c],
cinfo.actual_number_of_colors * sizeof(cinfo.colormap[c][0]));
reinterpret_cast<void*>(colormap[c]),
cinfo.actual_number_of_colors * sizeof(JSAMPLE));
}
}
for (size_t y = 0; y < cinfo.image_height; ++y) {

56
third_party/jpeg-xl/lib/extras/dec/jxl.cc поставляемый
Просмотреть файл

@ -16,20 +16,23 @@
#include "lib/extras/dec/color_description.h"
#include "lib/jxl/base/exif.h"
#include "lib/jxl/base/printf_macros.h"
#include "lib/jxl/base/status.h"
namespace jxl {
namespace extras {
namespace {
struct BoxProcessor {
BoxProcessor(JxlDecoder* dec) : dec_(dec) { Reset(); }
explicit BoxProcessor(JxlDecoder* dec) : dec_(dec) { Reset(); }
void InitializeOutput(std::vector<uint8_t>* out) {
JXL_ASSERT(out != nullptr);
box_data_ = out;
AddMoreOutput();
}
bool AddMoreOutput() {
JXL_ASSERT(box_data_ != nullptr);
Flush();
static const size_t kBoxOutputChunkSize = 1 << 16;
box_data_->resize(box_data_->size() + kBoxOutputChunkSize);
@ -126,7 +129,7 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
return false;
}
JxlPixelFormat format;
JxlPixelFormat format = {}; // Initialize to calm down clang-tidy.
std::vector<JxlPixelFormat> accepted_formats = dparams.accepted_formats;
JxlColorEncoding color_encoding;
@ -177,18 +180,18 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
return false;
}
if (jpeg_bytes == nullptr) {
if (JXL_DEC_SUCCESS !=
JxlDecoderSetRenderSpotcolors(dec, dparams.render_spotcolors)) {
if (JXL_DEC_SUCCESS != JxlDecoderSetRenderSpotcolors(
dec, TO_JXL_BOOL(dparams.render_spotcolors))) {
fprintf(stderr, "JxlDecoderSetRenderSpotColors failed\n");
return false;
}
if (JXL_DEC_SUCCESS !=
JxlDecoderSetKeepOrientation(dec, dparams.keep_orientation)) {
if (JXL_DEC_SUCCESS != JxlDecoderSetKeepOrientation(
dec, TO_JXL_BOOL(dparams.keep_orientation))) {
fprintf(stderr, "JxlDecoderSetKeepOrientation failed\n");
return false;
}
if (JXL_DEC_SUCCESS !=
JxlDecoderSetUnpremultiplyAlpha(dec, dparams.unpremultiply_alpha)) {
if (JXL_DEC_SUCCESS != JxlDecoderSetUnpremultiplyAlpha(
dec, TO_JXL_BOOL(dparams.unpremultiply_alpha))) {
fprintf(stderr, "JxlDecoderSetUnpremultiplyAlpha failed\n");
return false;
}
@ -267,6 +270,7 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
return false;
}
} else if (status == JXL_DEC_JPEG_NEED_MORE_OUTPUT) {
JXL_ASSERT(jpeg_bytes != nullptr); // Help clang-tidy.
// Decoded a chunk to JPEG.
size_t used_jpeg_output =
jpeg_data_chunk.size() - JxlDecoderReleaseJPEGBuffer(dec);
@ -309,7 +313,7 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
} else {
if (dparams.unpremultiply_alpha) {
// Mark in the basic info that alpha was unpremultiplied.
ppf->info.alpha_premultiplied = false;
ppf->info.alpha_premultiplied = JXL_FALSE;
}
}
bool alpha_found = false;
@ -327,7 +331,8 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
}
std::string name(eci.name_length + 1, 0);
if (JXL_DEC_SUCCESS !=
JxlDecoderGetExtraChannelName(dec, i, &name[0], name.size())) {
JxlDecoderGetExtraChannelName(
dec, i, const_cast<char*>(name.data()), name.size())) {
fprintf(stderr, "JxlDecoderGetExtraChannelName failed\n");
return false;
}
@ -387,14 +392,21 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
}
}
} else if (status == JXL_DEC_FRAME) {
jxl::extras::PackedFrame frame(ppf->info.xsize, ppf->info.ysize, format);
auto frame_or = jxl::extras::PackedFrame::Create(ppf->info.xsize,
ppf->info.ysize, format);
if (!frame_or.status()) {
fprintf(stderr, "Failed to create image frame.");
return false;
}
jxl::extras::PackedFrame frame = std::move(frame_or).value();
if (JXL_DEC_SUCCESS != JxlDecoderGetFrameHeader(dec, &frame.frame_info)) {
fprintf(stderr, "JxlDecoderGetFrameHeader failed\n");
return false;
}
frame.name.resize(frame.frame_info.name_length + 1, 0);
if (JXL_DEC_SUCCESS !=
JxlDecoderGetFrameName(dec, &frame.name[0], frame.name.size())) {
JxlDecoderGetFrameName(dec, const_cast<char*>(frame.name.data()),
frame.name.size())) {
fprintf(stderr, "JxlDecoderGetFrameName failed\n");
return false;
}
@ -425,9 +437,16 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
fprintf(stderr, "JxlDecoderPreviewOutBufferSize failed\n");
return false;
}
auto preview_image_or = jxl::extras::PackedImage::Create(
ppf->info.preview.xsize, ppf->info.preview.ysize, format);
if (!preview_image_or.status()) {
fprintf(stderr, "Failed to create preview image\n");
return false;
}
jxl::extras::PackedImage preview_image =
std::move(preview_image_or).value();
ppf->preview_frame = std::unique_ptr<jxl::extras::PackedFrame>(
new jxl::extras::PackedFrame(ppf->info.preview.xsize,
ppf->info.preview.ysize, format));
new jxl::extras::PackedFrame(std::move(preview_image)));
if (buffer_size != ppf->preview_frame->color.pixels_size) {
fprintf(stderr, "Invalid out buffer size %" PRIuS " %" PRIuS "\n",
buffer_size, ppf->preview_frame->color.pixels_size);
@ -494,8 +513,13 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
JxlPixelFormat ec_format = format;
ec_format.num_channels = 1;
for (auto& eci : ppf->extra_channels_info) {
frame.extra_channels.emplace_back(jxl::extras::PackedImage(
ppf->info.xsize, ppf->info.ysize, ec_format));
auto image = jxl::extras::PackedImage::Create(
ppf->info.xsize, ppf->info.ysize, ec_format);
if (!image.status()) {
fprintf(stderr, "Failed to create extra channel image\n");
return false;
}
frame.extra_channels.emplace_back(std::move(image).value());
auto& ec = frame.extra_channels.back();
size_t buffer_size;
if (JXL_DEC_SUCCESS != JxlDecoderExtraChannelBufferSize(

11
third_party/jpeg-xl/lib/extras/dec/pgx.cc поставляемый
Просмотреть файл

@ -150,7 +150,7 @@ Status DecodeImagePGX(const Span<const uint8_t> bytes,
const SizeConstraints* constraints) {
Parser parser(bytes);
HeaderPGX header = {};
const uint8_t* pos;
const uint8_t* pos = nullptr;
if (!parser.ParseHeader(&header, &pos)) return false;
JXL_RETURN_IF_ERROR(
VerifyDimensions(constraints, header.xsize, header.ysize));
@ -165,7 +165,7 @@ Status DecodeImagePGX(const Span<const uint8_t> bytes,
// Original data is uint, so exponent_bits_per_sample = 0.
ppf->info.bits_per_sample = header.bits_per_sample;
ppf->info.exponent_bits_per_sample = 0;
ppf->info.uses_original_profile = true;
ppf->info.uses_original_profile = JXL_TRUE;
// No alpha in PGX
ppf->info.alpha_bits = 0;
@ -188,7 +188,12 @@ Status DecodeImagePGX(const Span<const uint8_t> bytes,
};
ppf->frames.clear();
// Allocates the frame buffer.
ppf->frames.emplace_back(header.xsize, header.ysize, format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(header.xsize, header.ysize, format));
ppf->frames.emplace_back(std::move(frame));
}
const auto& frame = ppf->frames.back();
size_t pgx_remaining_size = bytes.data() + bytes.size() - pos;
if (pgx_remaining_size < frame.color.pixels_size) {

31
third_party/jpeg-xl/lib/extras/dec/pnm.cc поставляемый
Просмотреть файл

@ -9,6 +9,7 @@
#include <string.h>
#include <cmath>
#include <cstdint>
#include <mutex>
#include "jxl/encode.h"
@ -55,8 +56,10 @@ class Parser {
case 'f':
header->is_gray = true;
return ParseHeaderPFM(header, pos);
default:
return false;
}
return false;
}
// Exposed for testing
@ -160,11 +163,12 @@ class Parser {
Status MatchString(const char* keyword, bool skipws = true) {
const uint8_t* ppos = pos_;
while (*keyword) {
const uint8_t* kw = reinterpret_cast<const uint8_t*>(keyword);
while (*kw) {
if (ppos >= end_) return JXL_FAILURE("PAM: unexpected end of input");
if (*keyword != *ppos) return false;
if (*kw != *ppos) return false;
ppos++;
keyword++;
kw++;
}
pos_ = ppos;
if (skipws) {
@ -387,8 +391,8 @@ StatusOr<ChunkedPNMDecoder> ChunkedPNMDecoder::Init(const char* path) {
const size_t num_channels = dec.header_.is_gray ? 1 : 3;
const size_t bytes_per_pixel = num_channels * bytes_per_channel;
size_t row_size = dec.header_.xsize * bytes_per_pixel;
if (header.ysize * row_size + dec.data_start_ < size) {
return JXL_FAILURE("Invalid ppm");
if (size < header.ysize * row_size + dec.data_start_) {
return JXL_FAILURE("PNM file too small");
}
return dec;
}
@ -495,10 +499,18 @@ Status DecodeImagePNM(const Span<const uint8_t> bytes,
};
const JxlPixelFormat ec_format{1, format.data_type, format.endianness, 0};
ppf->frames.clear();
ppf->frames.emplace_back(header.xsize, header.ysize, format);
{
JXL_ASSIGN_OR_RETURN(
PackedFrame frame,
PackedFrame::Create(header.xsize, header.ysize, format));
ppf->frames.emplace_back(std::move(frame));
}
auto* frame = &ppf->frames.back();
for (size_t i = 0; i < header.ec_types.size(); ++i) {
frame->extra_channels.emplace_back(header.xsize, header.ysize, ec_format);
JXL_ASSIGN_OR_RETURN(
PackedImage ec,
PackedImage::Create(header.xsize, header.ysize, ec_format));
frame->extra_channels.emplace_back(std::move(ec));
}
size_t pnm_remaining_size = bytes.data() + bytes.size() - pos;
if (pnm_remaining_size < frame->color.pixels_size) {
@ -533,6 +545,9 @@ Status DecodeImagePNM(const Span<const uint8_t> bytes,
}
}
}
if (ppf->info.exponent_bits_per_sample == 0) {
ppf->input_bitdepth.type = JXL_BIT_DEPTH_FROM_CODESTREAM;
}
return true;
}

19
third_party/jpeg-xl/lib/extras/enc/apng.cc поставляемый
Просмотреть файл

@ -86,7 +86,7 @@ class APNGEncoder : public Encoder {
std::vector<uint8_t>* bytes) const;
};
static void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length) {
void PngWrite(png_structp png_ptr, png_bytep data, png_size_t length) {
std::vector<uint8_t>* bytes =
static_cast<std::vector<uint8_t>*>(png_get_io_ptr(png_ptr));
bytes->insert(bytes->end(), data, data + length);
@ -137,7 +137,7 @@ class BlobsWriterPNG {
std::vector<std::string>* strings) {
// Encoding: base16 with newline after 72 chars.
const size_t base16_size =
2 * bytes.size() + DivCeil(bytes.size(), size_t(36)) + 1;
2 * bytes.size() + DivCeil(bytes.size(), static_cast<size_t>(36)) + 1;
std::string base16;
base16.reserve(base16_size);
for (size_t i = 0; i < bytes.size(); ++i) {
@ -155,7 +155,7 @@ class BlobsWriterPNG {
snprintf(header, sizeof(header), "\n%s\n%8" PRIuS, type.c_str(),
bytes.size());
strings->push_back(std::string(key));
strings->emplace_back(key);
strings->push_back(std::string(header) + base16);
return true;
}
@ -303,7 +303,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
out[i] = static_cast<uint8_t>(in[i] * mul + 0.5);
}
} else {
memcpy(&out[0], in, out_size);
memcpy(out.data(), in, out_size);
}
} else if (format.data_type == JXL_TYPE_UINT16) {
if (ppf.info.bits_per_sample < 16 ||
@ -317,20 +317,21 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
StoreBE16(static_cast<uint32_t>(val * mul + 0.5), p_out);
}
} else {
memcpy(&out[0], in, out_size);
memcpy(out.data(), in, out_size);
}
}
png_structp png_ptr;
png_infop info_ptr;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr,
nullptr);
if (!png_ptr) return JXL_FAILURE("Could not init png encoder");
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) return JXL_FAILURE("Could not init png info struct");
png_set_write_fn(png_ptr, bytes, PngWrite, NULL);
png_set_write_fn(png_ptr, bytes, PngWrite, nullptr);
png_set_flush(png_ptr, 0);
int width = xsize;
@ -406,7 +407,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
png_write_flush(png_ptr);
const size_t pos = bytes->size();
png_write_image(png_ptr, &rows[0]);
png_write_image(png_ptr, rows.data());
png_write_flush(png_ptr);
if (count > 0) {
std::vector<uint8_t> fdata(4);
@ -430,7 +431,7 @@ Status APNGEncoder::EncodePackedPixelFileToAPNG(
count++;
if (count == ppf.frames.size() || !ppf.info.have_animation) {
png_write_end(png_ptr, NULL);
png_write_end(png_ptr, nullptr);
}
png_destroy_write_struct(&png_ptr, &info_ptr);

Просмотреть файл

@ -54,7 +54,7 @@ Status Encoder::VerifyBitDepth(JxlDataType data_type, uint32_t bits_per_sample,
(bits_per_sample > 16 || exponent_bits > 5))) {
return JXL_FAILURE(
"Incompatible data_type %d and bit depth %u with exponent bits %u",
(int)data_type, bits_per_sample, exponent_bits);
static_cast<int>(data_type), bits_per_sample, exponent_bits);
}
return true;
}

2
third_party/jpeg-xl/lib/extras/enc/encode.h поставляемый
Просмотреть файл

@ -56,7 +56,7 @@ class Encoder {
// Any existing data in encoded_image is discarded.
virtual Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
ThreadPool* pool = nullptr) const = 0;
ThreadPool* pool) const = 0;
void SetOption(std::string name, std::string value) {
options_[std::move(name)] = std::move(value);

4
third_party/jpeg-xl/lib/extras/enc/exr.cc поставляемый
Просмотреть файл

@ -84,7 +84,7 @@ Status EncodeImageEXR(const PackedImage& image, const JxlBasicInfo& info,
const size_t xsize = info.xsize;
const size_t ysize = info.ysize;
const bool has_alpha = info.alpha_bits > 0;
const bool alpha_is_premultiplied = info.alpha_premultiplied;
const bool alpha_is_premultiplied = FROM_JXL_BOOL(info.alpha_premultiplied);
if (info.num_color_channels != 3 ||
c_enc.color_space != JXL_COLOR_SPACE_RGB ||
@ -177,7 +177,7 @@ class EXREncoder : public Encoder {
return formats;
}
Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
ThreadPool* pool = nullptr) const override {
ThreadPool* pool) const override {
JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
encoded_image->icc.clear();
encoded_image->bitstreams.clear();

75
third_party/jpeg-xl/lib/extras/enc/jpegli.cc поставляемый
Просмотреть файл

@ -54,6 +54,10 @@ Status VerifyInput(const PackedPixelFile& ppf) {
if (ppf.frames.size() != 1) {
return JXL_FAILURE("JPEG input must have exactly one frame.");
}
if (info.num_color_channels != 1 && info.num_color_channels != 3) {
return JXL_FAILURE("Invalid number of color channels %d",
info.num_color_channels);
}
const PackedImage& image = ppf.frames[0].color;
JXL_RETURN_IF_ERROR(Encoder::VerifyImageSize(image, info));
if (image.format.data_type == JXL_TYPE_FLOAT16) {
@ -123,12 +127,12 @@ Status WriteAppData(j_compress_ptr cinfo,
return true;
}
static constexpr int kICCMarker = 0xe2;
constexpr int kICCMarker = 0xe2;
constexpr unsigned char kICCSignature[12] = {
0x49, 0x43, 0x43, 0x5F, 0x50, 0x52, 0x4F, 0x46, 0x49, 0x4C, 0x45, 0x00};
static constexpr uint8_t kUnknownTf = 2;
static constexpr unsigned char kCICPTagSignature[4] = {0x63, 0x69, 0x63, 0x70};
static constexpr size_t kCICPTagSize = 12;
constexpr uint8_t kUnknownTf = 2;
constexpr unsigned char kCICPTagSignature[4] = {0x63, 0x69, 0x63, 0x70};
constexpr size_t kCICPTagSize = 12;
bool FindCICPTag(const uint8_t* icc_data, size_t len, bool is_first_chunk,
size_t* cicp_offset, size_t* cicp_length, uint8_t* cicp_tag,
@ -249,32 +253,48 @@ JpegliEndianness ConvertEndianness(JxlEndianness endianness) {
}
}
void ToFloatRow(const uint8_t* row_in, JxlPixelFormat format, size_t len,
float* row_out) {
void ToFloatRow(const uint8_t* row_in, JxlPixelFormat format, size_t xsize,
size_t c_out, float* row_out) {
bool is_little_endian =
(format.endianness == JXL_LITTLE_ENDIAN ||
(format.endianness == JXL_NATIVE_ENDIAN && IsLittleEndian()));
static constexpr double kMul8 = 1.0 / 255.0;
static constexpr double kMul16 = 1.0 / 65535.0;
const size_t c_in = format.num_channels;
if (format.data_type == JXL_TYPE_UINT8) {
for (size_t x = 0; x < len; ++x) {
row_out[x] = row_in[x] * kMul8;
for (size_t x = 0; x < xsize; ++x) {
for (size_t c = 0; c < c_out; ++c) {
const size_t ix = c_in * x + c;
row_out[c_out * x + c] = row_in[ix] * kMul8;
}
}
} else if (format.data_type == JXL_TYPE_UINT16 && is_little_endian) {
for (size_t x = 0; x < len; ++x) {
row_out[x] = LoadLE16(&row_in[2 * x]) * kMul16;
for (size_t x = 0; x < xsize; ++x) {
for (size_t c = 0; c < c_out; ++c) {
const size_t ix = c_in * x + c;
row_out[c_out * x + c] = LoadLE16(&row_in[2 * ix]) * kMul16;
}
}
} else if (format.data_type == JXL_TYPE_UINT16 && !is_little_endian) {
for (size_t x = 0; x < len; ++x) {
row_out[x] = LoadBE16(&row_in[2 * x]) * kMul16;
for (size_t x = 0; x < xsize; ++x) {
for (size_t c = 0; c < c_out; ++c) {
const size_t ix = c_in * x + c;
row_out[c_out * x + c] = LoadBE16(&row_in[2 * ix]) * kMul16;
}
}
} else if (format.data_type == JXL_TYPE_FLOAT && is_little_endian) {
for (size_t x = 0; x < len; ++x) {
row_out[x] = LoadLEFloat(&row_in[4 * x]);
for (size_t x = 0; x < xsize; ++x) {
for (size_t c = 0; c < c_out; ++c) {
const size_t ix = c_in * x + c;
row_out[c_out * x + c] = LoadLEFloat(&row_in[4 * ix]);
}
}
} else if (format.data_type == JXL_TYPE_FLOAT && !is_little_endian) {
for (size_t x = 0; x < len; ++x) {
row_out[x] = LoadBEFloat(&row_in[4 * x]);
for (size_t x = 0; x < xsize; ++x) {
for (size_t c = 0; c < c_out; ++c) {
const size_t ix = c_in * x + c;
row_out[c_out * x + c] = LoadBEFloat(&row_in[4 * ix]);
}
}
}
}
@ -353,9 +373,6 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
ColorSpaceTransform c_transform(*JxlGetDefaultCms());
ColorEncoding xyb_encoding;
if (jpeg_settings.xyb) {
if (ppf.info.num_color_channels != 3) {
return JXL_FAILURE("Only RGB input is supported in XYB mode.");
}
if (HasICCProfile(jpeg_settings.app_data)) {
return JXL_FAILURE("APP data ICC profile is not supported in XYB mode.");
}
@ -402,6 +419,8 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
cinfo.input_components == 1 ? JCS_GRAYSCALE : JCS_RGB;
if (jpeg_settings.xyb) {
jpegli_set_xyb_mode(&cinfo);
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
} else if (jpeg_settings.use_std_quant_tables) {
jpegli_use_standard_quant_tables(&cinfo);
}
@ -437,7 +456,7 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
}
}
jpegli_enable_adaptive_quantization(
&cinfo, jpeg_settings.use_adaptive_quantization);
&cinfo, TO_JXL_BOOL(jpeg_settings.use_adaptive_quantization));
if (jpeg_settings.psnr_target > 0.0) {
jpegli_set_psnr(&cinfo, jpeg_settings.psnr_target,
jpeg_settings.search_tolerance,
@ -449,11 +468,11 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
jpegli_set_distance(&cinfo, jpeg_settings.distance, TRUE);
}
jpegli_set_progressive_level(&cinfo, jpeg_settings.progressive_level);
cinfo.optimize_coding = jpeg_settings.optimize_coding;
cinfo.optimize_coding = TO_JXL_BOOL(jpeg_settings.optimize_coding);
if (!jpeg_settings.app_data.empty()) {
// Make sure jpegli_start_compress() does not write any APP markers.
cinfo.write_JFIF_header = false;
cinfo.write_Adobe_marker = false;
cinfo.write_JFIF_header = JXL_FALSE;
cinfo.write_Adobe_marker = JXL_FALSE;
}
const PackedImage& image = ppf.frames[0].color;
if (jpeg_settings.xyb) {
@ -477,10 +496,10 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
float* dst_buf = c_transform.BufDst(0);
for (size_t y = 0; y < image.ysize; ++y) {
// convert to float
ToFloatRow(&pixels[y * image.stride], image.format, 3 * image.xsize,
src_buf);
ToFloatRow(&pixels[y * image.stride], image.format, image.xsize,
info.num_color_channels, src_buf);
// convert to linear srgb
if (!c_transform.Run(0, src_buf, dst_buf)) {
if (!c_transform.Run(0, src_buf, dst_buf, image.xsize)) {
return false;
}
// deinterleave channels
@ -509,9 +528,9 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
}
} else {
row_bytes.resize(image.stride);
if (cinfo.num_components == (int)image.format.num_channels) {
if (cinfo.num_components == static_cast<int>(image.format.num_channels)) {
for (size_t y = 0; y < info.ysize; ++y) {
memcpy(&row_bytes[0], pixels + y * image.stride, image.stride);
memcpy(row_bytes.data(), pixels + y * image.stride, image.stride);
JSAMPROW row[] = {row_bytes.data()};
jpegli_write_scanlines(&cinfo, row, 1);
}

79
third_party/jpeg-xl/lib/extras/enc/jpg.cc поставляемый
Просмотреть файл

@ -23,6 +23,7 @@
#include <vector>
#include "lib/extras/exif.h"
#include "lib/jxl/base/common.h"
#include "lib/jxl/base/status.h"
#include "lib/jxl/sanitizers.h"
#if JPEGXL_ENABLE_SJPEG
@ -50,23 +51,21 @@ enum class JpegEncoder {
kSJpeg,
};
#define ARRAY_SIZE(X) (sizeof(X) / sizeof((X)[0]))
// Popular jpeg scan scripts
// The fields of the individual scans are:
// comps_in_scan, component_index[], Ss, Se, Ah, Al
static constexpr jpeg_scan_info kScanScript1[] = {
constexpr auto kScanScript1 = to_array<jpeg_scan_info>({
{1, {0}, 0, 0, 0, 0}, //
{1, {1}, 0, 0, 0, 0}, //
{1, {2}, 0, 0, 0, 0}, //
{1, {0}, 1, 8, 0, 0}, //
{1, {0}, 9, 63, 0, 0}, //
{1, {1}, 1, 63, 0, 0}, //
{1, {2}, 1, 63, 0, 0}, //
};
static constexpr size_t kNumScans1 = ARRAY_SIZE(kScanScript1);
{1, {2}, 1, 63, 0, 0} //
});
constexpr size_t kNumScans1 = kScanScript1.size();
static constexpr jpeg_scan_info kScanScript2[] = {
constexpr auto kScanScript2 = to_array<jpeg_scan_info>({
{1, {0}, 0, 0, 0, 0}, //
{1, {1}, 0, 0, 0, 0}, //
{1, {2}, 0, 0, 0, 0}, //
@ -74,11 +73,11 @@ static constexpr jpeg_scan_info kScanScript2[] = {
{1, {0}, 3, 63, 0, 1}, //
{1, {0}, 1, 63, 1, 0}, //
{1, {1}, 1, 63, 0, 0}, //
{1, {2}, 1, 63, 0, 0}, //
};
static constexpr size_t kNumScans2 = ARRAY_SIZE(kScanScript2);
{1, {2}, 1, 63, 0, 0} //
});
constexpr size_t kNumScans2 = kScanScript2.size();
static constexpr jpeg_scan_info kScanScript3[] = {
constexpr auto kScanScript3 = to_array<jpeg_scan_info>({
{1, {0}, 0, 0, 0, 0}, //
{1, {1}, 0, 0, 0, 0}, //
{1, {2}, 0, 0, 0, 0}, //
@ -86,11 +85,11 @@ static constexpr jpeg_scan_info kScanScript3[] = {
{1, {0}, 1, 63, 2, 1}, //
{1, {0}, 1, 63, 1, 0}, //
{1, {1}, 1, 63, 0, 0}, //
{1, {2}, 1, 63, 0, 0}, //
};
static constexpr size_t kNumScans3 = ARRAY_SIZE(kScanScript3);
{1, {2}, 1, 63, 0, 0} //
});
constexpr size_t kNumScans3 = kScanScript3.size();
static constexpr jpeg_scan_info kScanScript4[] = {
constexpr auto kScanScript4 = to_array<jpeg_scan_info>({
{3, {0, 1, 2}, 0, 0, 0, 1}, //
{1, {0}, 1, 5, 0, 2}, //
{1, {2}, 1, 63, 0, 1}, //
@ -100,11 +99,11 @@ static constexpr jpeg_scan_info kScanScript4[] = {
{3, {0, 1, 2}, 0, 0, 1, 0}, //
{1, {2}, 1, 63, 1, 0}, //
{1, {1}, 1, 63, 1, 0}, //
{1, {0}, 1, 63, 1, 0}, //
};
static constexpr size_t kNumScans4 = ARRAY_SIZE(kScanScript4);
{1, {0}, 1, 63, 1, 0} //
});
constexpr size_t kNumScans4 = kScanScript4.size();
static constexpr jpeg_scan_info kScanScript5[] = {
constexpr auto kScanScript5 = to_array<jpeg_scan_info>({
{3, {0, 1, 2}, 0, 0, 0, 1}, //
{1, {0}, 1, 5, 0, 2}, //
{1, {1}, 1, 5, 0, 2}, //
@ -118,12 +117,12 @@ static constexpr jpeg_scan_info kScanScript5[] = {
{3, {0, 1, 2}, 0, 0, 1, 0}, //
{1, {0}, 1, 63, 1, 0}, //
{1, {1}, 1, 63, 1, 0}, //
{1, {2}, 1, 63, 1, 0}, //
};
static constexpr size_t kNumScans5 = ARRAY_SIZE(kScanScript5);
{1, {2}, 1, 63, 1, 0} //
});
constexpr size_t kNumScans5 = kScanScript5.size();
// default progressive mode of jpegli
static constexpr jpeg_scan_info kScanScript6[] = {
constexpr auto kScanScript6 = to_array<jpeg_scan_info>({
{3, {0, 1, 2}, 0, 0, 0, 0}, //
{1, {0}, 1, 2, 0, 0}, //
{1, {1}, 1, 2, 0, 0}, //
@ -137,8 +136,8 @@ static constexpr jpeg_scan_info kScanScript6[] = {
{1, {0}, 3, 63, 1, 0}, //
{1, {1}, 3, 63, 1, 0}, //
{1, {2}, 3, 63, 1, 0}, //
};
static constexpr size_t kNumScans6 = ARRAY_SIZE(kScanScript6);
});
constexpr size_t kNumScans6 = kScanScript6.size();
// Adapt RGB scan info to grayscale jpegs.
void FilterScanComponents(const jpeg_compress_struct* cinfo,
@ -163,12 +162,12 @@ Status SetJpegProgression(int progressive_id,
jpeg_simple_progression(cinfo);
return true;
}
constexpr const jpeg_scan_info* kScanScripts[] = {kScanScript1, kScanScript2,
kScanScript3, kScanScript4,
kScanScript5, kScanScript6};
constexpr size_t kNumScans[] = {kNumScans1, kNumScans2, kNumScans3,
kNumScans4, kNumScans5, kNumScans6};
if (progressive_id > static_cast<int>(ARRAY_SIZE(kNumScans))) {
const jpeg_scan_info* kScanScripts[] = {
kScanScript1.data(), kScanScript2.data(), kScanScript3.data(),
kScanScript4.data(), kScanScript5.data(), kScanScript6.data()};
constexpr auto kNumScans = to_array<size_t>(
{kNumScans1, kNumScans2, kNumScans3, kNumScans4, kNumScans5, kNumScans6});
if (progressive_id > static_cast<int>(kNumScans.size())) {
return JXL_FAILURE("Unknown jpeg scan script id %d", progressive_id);
}
const jpeg_scan_info* scan_script = kScanScripts[progressive_id - 1];
@ -178,7 +177,7 @@ Status SetJpegProgression(int progressive_id,
jpeg_scan_info scan_info = scan_script[i];
FilterScanComponents(cinfo, &scan_info);
if (scan_info.comps_in_scan > 0) {
scan_infos->emplace_back(std::move(scan_info));
scan_infos->emplace_back(scan_info);
}
}
cinfo->scan_info = scan_infos->data();
@ -217,8 +216,8 @@ void WriteExif(jpeg_compress_struct* const cinfo,
for (const unsigned char c : kExifSignature) {
jpeg_write_m_byte(cinfo, c);
}
for (size_t i = 0; i < exif.size(); ++i) {
jpeg_write_m_byte(cinfo, exif[i]);
for (uint8_t c : exif) {
jpeg_write_m_byte(cinfo, c);
}
}
@ -310,10 +309,10 @@ Status EncodeWithLibJpeg(const PackedImage& image, const JxlBasicInfo& info,
std::vector<uint8_t> row_bytes(image.stride);
const uint8_t* pixels = reinterpret_cast<const uint8_t*>(image.pixels());
if (cinfo.num_components == (int)image.format.num_channels &&
if (cinfo.num_components == static_cast<int>(image.format.num_channels) &&
image.format.data_type == JXL_TYPE_UINT8) {
for (size_t y = 0; y < info.ysize; ++y) {
memcpy(&row_bytes[0], pixels + y * image.stride, image.stride);
memcpy(row_bytes.data(), pixels + y * image.stride, image.stride);
JSAMPROW row[] = {row_bytes.data()};
jpeg_write_scanlines(&cinfo, row, 1);
}
@ -401,7 +400,7 @@ struct MySearchHook : public sjpeg::SearchHook {
}
bool Update(float result) override {
value = result;
if (fabs(value - target) < tolerance * target) {
if (std::fabs(value - target) < tolerance * target) {
return true;
}
if (value > target) {
@ -420,9 +419,9 @@ struct MySearchHook : public sjpeg::SearchHook {
} else {
q = (qmin + qmax) / 2.;
}
return (pass > 0 && fabs(q - last_q) < q_precision);
return (pass > 0 && std::fabs(q - last_q) < q_precision);
}
~MySearchHook() override {}
~MySearchHook() override = default;
};
#endif
@ -539,7 +538,7 @@ class JPEGEncoder : public Encoder {
return formats;
}
Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
ThreadPool* pool = nullptr) const override {
ThreadPool* pool) const override {
JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
JpegEncoder jpeg_encoder = JpegEncoder::kLibJpeg;
JpegParams params;

33
third_party/jpeg-xl/lib/extras/enc/jxl.cc поставляемый
Просмотреть файл

@ -7,6 +7,7 @@
#include <jxl/encode.h>
#include <jxl/encode_cxx.h>
#include <jxl/types.h>
#include "lib/jxl/base/exif.h"
@ -132,7 +133,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
return false;
}
auto settings = JxlEncoderFrameSettingsCreate(enc, nullptr);
auto* settings = JxlEncoderFrameSettingsCreate(enc, nullptr);
size_t option_idx = 0;
if (!SetFrameOptions(params.options, 0, &option_idx, settings)) {
return false;
@ -150,10 +151,11 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
JxlEncoderCollectStats(settings, params.stats);
}
bool has_jpeg_bytes = (jpeg_bytes != nullptr);
bool use_boxes = !ppf.metadata.exif.empty() || !ppf.metadata.xmp.empty() ||
!ppf.metadata.jumbf.empty() || !ppf.metadata.iptc.empty();
bool use_container = params.use_container || use_boxes ||
(jpeg_bytes && params.jpeg_store_metadata);
(has_jpeg_bytes && params.jpeg_store_metadata);
if (JXL_ENC_SUCCESS !=
JxlEncoderUseContainer(enc, static_cast<int>(use_container))) {
@ -161,7 +163,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
return false;
}
if (jpeg_bytes) {
if (has_jpeg_bytes) {
if (params.jpeg_store_metadata &&
JXL_ENC_SUCCESS != JxlEncoderStoreJPEGMetadata(enc, JXL_TRUE)) {
fprintf(stderr, "Storing JPEG metadata failed.\n");
@ -220,8 +222,8 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
basic_info.num_extra_channels =
std::max<uint32_t>(num_alpha_channels, ppf.info.num_extra_channels);
basic_info.num_color_channels = ppf.info.num_color_channels;
const bool lossless = params.distance == 0;
basic_info.uses_original_profile = lossless;
const bool lossless = (params.distance == 0);
basic_info.uses_original_profile = TO_JXL_BOOL(lossless);
if (params.override_bitdepth != 0) {
basic_info.bits_per_sample = params.override_bitdepth;
basic_info.exponent_bits_per_sample =
@ -243,7 +245,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
return false;
}
if (JXL_ENC_SUCCESS !=
JxlEncoderSetFrameBitDepth(settings, &params.input_bitdepth)) {
JxlEncoderSetFrameBitDepth(settings, &ppf.input_bitdepth)) {
fprintf(stderr, "JxlEncoderSetFrameBitDepth() failed.\n");
return false;
}
@ -294,14 +296,15 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
{"jumb", ppf.metadata.jumbf},
{"xml ", ppf.metadata.iptc},
};
for (size_t i = 0; i < sizeof boxes / sizeof *boxes; ++i) {
const BoxInfo& box = boxes[i];
if (!box.bytes.empty() &&
JXL_ENC_SUCCESS != JxlEncoderAddBox(enc, box.type, box.bytes.data(),
box.bytes.size(),
params.compress_boxes)) {
fprintf(stderr, "JxlEncoderAddBox() failed (%s).\n", box.type);
return false;
for (auto box : boxes) {
if (!box.bytes.empty()) {
if (JXL_ENC_SUCCESS !=
JxlEncoderAddBox(enc, box.type, box.bytes.data(),
box.bytes.size(),
TO_JXL_BOOL(params.compress_boxes))) {
fprintf(stderr, "JxlEncoderAddBox() failed (%s).\n", box.type);
return false;
}
}
}
JxlEncoderCloseBoxes(enc);
@ -346,7 +349,7 @@ bool EncodeImageJXL(const JXLCompressParams& params, const PackedPixelFile& ppf,
}
const bool last_frame = fi + 1 == ppf.chunked_frames.size();
if (JXL_ENC_SUCCESS !=
JxlEncoderAddChunkedFrame(settings, last_frame,
JxlEncoderAddChunkedFrame(settings, TO_JXL_BOOL(last_frame),
chunked_frame.GetInputSource())) {
fprintf(stderr, "JxlEncoderAddChunkedFrame() failed.\n");
return false;

6
third_party/jpeg-xl/lib/extras/enc/jxl.h поставляемый
Просмотреть файл

@ -57,8 +57,6 @@ struct JXLCompressParams {
size_t override_bitdepth = 0;
int32_t codestream_level = -1;
int32_t premultiply = -1;
// Override input buffer interpretation.
JxlBitDepth input_bitdepth = {JXL_BIT_DEPTH_FROM_PIXEL_FORMAT, 0, 0};
// If runner_opaque is set, the decoder uses this parallel runner.
JxlParallelRunner runner = JxlThreadParallelRunner;
void* runner_opaque = nullptr;
@ -69,10 +67,10 @@ struct JXLCompressParams {
bool allow_expert_options = false;
void AddOption(JxlEncoderFrameSettingId id, int64_t val) {
options.emplace_back(JXLOption(id, val, 0));
options.emplace_back(id, val, 0);
}
void AddFloatOption(JxlEncoderFrameSettingId id, float val) {
options.emplace_back(JXLOption(id, val, 0));
options.emplace_back(id, val, 0);
}
bool HasOutputProcessor() const {
return (output_processor.get_buffer != nullptr &&

35
third_party/jpeg-xl/lib/extras/enc/npy.cc поставляемый
Просмотреть файл

@ -7,11 +7,13 @@
#include <jxl/types.h>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
#include "lib/extras/packed_image.h"
#include "lib/jxl/base/common.h"
namespace jxl {
namespace extras {
@ -52,14 +54,17 @@ class JSONDict : public JSONField {
static_assert(std::is_convertible<T*, JSONField*>::value,
"T must be a JSONField");
T* ret = new T();
values_.emplace_back(
key, std::unique_ptr<JSONField>(static_cast<JSONField*>(ret)));
JSONField* field = static_cast<JSONField*>(ret);
auto handle = std::unique_ptr<JSONField>(field);
values_.emplace_back(key, std::move(handle));
return ret;
}
template <typename T>
void Add(const std::string& key, const T& value) {
values_.emplace_back(key, std::unique_ptr<JSONField>(new JSONValue(value)));
JSONField* field = static_cast<JSONField*>(new JSONValue(value));
auto handle = std::unique_ptr<JSONField>(field);
values_.emplace_back(key, std::move(handle));
}
void Write(std::ostream& o, uint32_t indent) const override {
@ -71,11 +76,11 @@ class JSONDict : public JSONField {
o << ",";
}
is_first = false;
o << std::endl << indent_str << " \"" << key_value.first << "\": ";
o << "\n" << indent_str << " \"" << key_value.first << "\": ";
key_value.second->Write(o, indent + 2);
}
if (!values_.empty()) {
o << std::endl << indent_str;
o << "\n" << indent_str;
}
o << "}";
}
@ -112,11 +117,11 @@ class JSONArray : public JSONField {
o << ",";
}
is_first = false;
o << std::endl << indent_str << " ";
o << "\n" << indent_str << " ";
value->Write(o, indent + 2);
}
if (!values_.empty()) {
o << std::endl << indent_str;
o << "\n" << indent_str;
}
o << "]";
}
@ -160,13 +165,13 @@ void GenerateMetadata(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
}
{
auto ectype = meta.AddEmpty<JSONArray>("extra_channel_type");
auto bps = meta.AddEmpty<JSONArray>("bits_per_sample");
auto ebps = meta.AddEmpty<JSONArray>("exp_bits_per_sample");
auto* ectype = meta.AddEmpty<JSONArray>("extra_channel_type");
auto* bps = meta.AddEmpty<JSONArray>("bits_per_sample");
auto* ebps = meta.AddEmpty<JSONArray>("exp_bits_per_sample");
bps->Add(ppf.info.bits_per_sample);
ebps->Add(ppf.info.exponent_bits_per_sample);
for (size_t i = 0; i < ppf.extra_channels_info.size(); i++) {
switch (ppf.extra_channels_info[i].ec_info.type) {
for (const auto& eci : ppf.extra_channels_info) {
switch (eci.ec_info.type) {
case JXL_CHANNEL_ALPHA: {
ectype->Add(std::string("Alpha"));
break;
@ -200,8 +205,8 @@ void GenerateMetadata(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
break;
}
}
bps->Add(ppf.extra_channels_info[i].ec_info.bits_per_sample);
ebps->Add(ppf.extra_channels_info[i].ec_info.exponent_bits_per_sample);
bps->Add(eci.ec_info.bits_per_sample);
ebps->Add(eci.ec_info.exponent_bits_per_sample);
}
}
@ -282,7 +287,7 @@ bool WriteNPYArray(const PackedPixelFile& ppf, std::vector<uint8_t>* out) {
class NumPyEncoder : public Encoder {
public:
Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
ThreadPool* pool = nullptr) const override {
ThreadPool* pool) const override {
JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
GenerateMetadata(ppf, &encoded_image->metadata);
encoded_image->bitstreams.emplace_back();

4
third_party/jpeg-xl/lib/extras/enc/pgx.cc поставляемый
Просмотреть файл

@ -60,7 +60,7 @@ Status EncodeImagePGX(const PackedFrame& frame, const JxlBasicInfo& info,
std::vector<uint8_t> pixels(num_samples * bytes_per_sample);
if (format.data_type == JXL_TYPE_UINT8) {
memcpy(&pixels[0], in, num_samples * bytes_per_sample);
memcpy(pixels.data(), in, num_samples * bytes_per_sample);
} else if (format.data_type == JXL_TYPE_UINT16) {
if (format.endianness != JXL_BIG_ENDIAN) {
const uint8_t* p_in = in;
@ -69,7 +69,7 @@ Status EncodeImagePGX(const PackedFrame& frame, const JxlBasicInfo& info,
StoreBE16(LoadLE16(p_in), p_out);
}
} else {
memcpy(&pixels[0], in, num_samples * bytes_per_sample);
memcpy(pixels.data(), in, num_samples * bytes_per_sample);
}
} else {
return JXL_FAILURE("Unsupported pixel data type");

2
third_party/jpeg-xl/lib/extras/enc/pnm.cc поставляемый
Просмотреть файл

@ -31,7 +31,7 @@ constexpr size_t kMaxHeaderSize = 200;
class BasePNMEncoder : public Encoder {
public:
Status Encode(const PackedPixelFile& ppf, EncodedImage* encoded_image,
ThreadPool* pool = nullptr) const override {
ThreadPool* pool) const override {
JXL_RETURN_IF_ERROR(VerifyBasicInfo(ppf.info));
if (!ppf.metadata.exif.empty() || !ppf.metadata.iptc.empty() ||
!ppf.metadata.jumbf.empty() || !ppf.metadata.xmp.empty()) {

18
third_party/jpeg-xl/lib/extras/jpegli_test.cc поставляемый
Просмотреть файл

@ -85,7 +85,7 @@ Status EncodeWithLibjpeg(const PackedPixelFile& ppf, int quality,
std::unique_ptr<Encoder> encoder = GetJPEGEncoder();
encoder->SetOption("q", std::to_string(quality));
EncodedImage encoded;
JXL_RETURN_IF_ERROR(encoder->Encode(ppf, &encoded));
JXL_RETURN_IF_ERROR(encoder->Encode(ppf, &encoded, nullptr));
JXL_RETURN_IF_ERROR(!encoded.bitstreams.empty());
*compressed = std::move(encoded.bitstreams[0]);
return true;
@ -156,8 +156,8 @@ TEST(JpegliTest, JpegliXYBEncodeTest) {
PackedPixelFile ppf_out;
ASSERT_TRUE(DecodeWithLibjpeg(compressed, &ppf_out));
EXPECT_THAT(BitsPerPixel(ppf_in, compressed), IsSlightlyBelow(1.45f));
EXPECT_THAT(ButteraugliDistance(ppf_in, ppf_out), IsSlightlyBelow(1.32f));
EXPECT_SLIGHTLY_BELOW(BitsPerPixel(ppf_in, compressed), 1.45f);
EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(ppf_in, ppf_out), 1.32f);
}
TEST(JpegliTest, JpegliDecodeTestLargeSmoothArea) {
@ -205,8 +205,8 @@ TEST(JpegliTest, JpegliYUVEncodeTest) {
PackedPixelFile ppf_out;
ASSERT_TRUE(DecodeWithLibjpeg(compressed, &ppf_out));
EXPECT_THAT(BitsPerPixel(ppf_in, compressed), IsSlightlyBelow(1.7f));
EXPECT_THAT(ButteraugliDistance(ppf_in, ppf_out), IsSlightlyBelow(1.32f));
EXPECT_SLIGHTLY_BELOW(BitsPerPixel(ppf_in, compressed), 1.7f);
EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(ppf_in, ppf_out), 1.32f);
}
TEST(JpegliTest, JpegliYUVChromaSubsamplingEncodeTest) {
@ -247,8 +247,8 @@ TEST(JpegliTest, JpegliYUVEncodeTestNoAq) {
PackedPixelFile ppf_out;
ASSERT_TRUE(DecodeWithLibjpeg(compressed, &ppf_out));
EXPECT_THAT(BitsPerPixel(ppf_in, compressed), IsSlightlyBelow(1.85f));
EXPECT_THAT(ButteraugliDistance(ppf_in, ppf_out), IsSlightlyBelow(1.25f));
EXPECT_SLIGHTLY_BELOW(BitsPerPixel(ppf_in, compressed), 1.85f);
EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(ppf_in, ppf_out), 1.25f);
}
TEST(JpegliTest, JpegliHDRRoundtripTest) {
@ -267,8 +267,8 @@ TEST(JpegliTest, JpegliHDRRoundtripTest) {
JpegDecompressParams dparams;
dparams.output_data_type = JXL_TYPE_UINT16;
ASSERT_TRUE(DecodeJpeg(compressed, dparams, nullptr, &ppf_out));
EXPECT_THAT(BitsPerPixel(ppf_in, compressed), IsSlightlyBelow(2.95f));
EXPECT_THAT(ButteraugliDistance(ppf_in, ppf_out), IsSlightlyBelow(1.05f));
EXPECT_SLIGHTLY_BELOW(BitsPerPixel(ppf_in, compressed), 2.95f);
EXPECT_SLIGHTLY_BELOW(ButteraugliDistance(ppf_in, ppf_out), 1.05f);
}
TEST(JpegliTest, JpegliSetAppData) {

2
third_party/jpeg-xl/lib/extras/mmap.cc поставляемый
Просмотреть файл

@ -55,7 +55,7 @@ struct MemoryMappedFileImpl {
} // namespace jxl
#elif __WIN32__
#elif defined(_WIN32)
#include <string.h>
#include <windows.h>

39
third_party/jpeg-xl/lib/extras/packed_image.h поставляемый
Просмотреть файл

@ -37,11 +37,18 @@ namespace extras {
// Class representing an interleaved image with a bunch of channels.
class PackedImage {
public:
PackedImage(size_t xsize, size_t ysize, const JxlPixelFormat& format)
: PackedImage(xsize, ysize, format, CalcStride(format, xsize)) {}
static StatusOr<PackedImage> Create(size_t xsize, size_t ysize,
const JxlPixelFormat& format) {
PackedImage image(xsize, ysize, format, CalcStride(format, xsize));
if (!image.pixels()) {
// TODO(szabadka): use specialized OOM error code
return JXL_FAILURE("Failed to allocate memory for image");
}
return image;
}
PackedImage Copy() const {
PackedImage copy(xsize, ysize, format);
PackedImage copy(xsize, ysize, format, CalcStride(format, xsize));
memcpy(reinterpret_cast<uint8_t*>(copy.pixels()),
reinterpret_cast<const uint8_t*>(pixels()), pixels_size);
return copy;
@ -108,7 +115,7 @@ class PackedImage {
}
}
void SetPixelValue(size_t y, size_t x, size_t c, float val) {
void SetPixelValue(size_t y, size_t x, size_t c, float val) const {
uint8_t* data = pixels(y, x, c);
switch (format.data_type) {
case JXL_TYPE_UINT8:
@ -169,17 +176,25 @@ class PackedImage {
// as all other frames in the same image.
class PackedFrame {
public:
template <typename... Args>
explicit PackedFrame(Args&&... args) : color(std::forward<Args>(args)...) {}
explicit PackedFrame(PackedImage&& image) : color(std::move(image)) {}
PackedFrame Copy() const {
PackedFrame copy(color.xsize, color.ysize, color.format);
static StatusOr<PackedFrame> Create(size_t xsize, size_t ysize,
const JxlPixelFormat& format) {
JXL_ASSIGN_OR_RETURN(PackedImage image,
PackedImage::Create(xsize, ysize, format));
PackedFrame frame(std::move(image));
return frame;
}
StatusOr<PackedFrame> Copy() const {
JXL_ASSIGN_OR_RETURN(
PackedFrame copy,
PackedFrame::Create(color.xsize, color.ysize, color.format));
copy.frame_info = frame_info;
copy.name = name;
copy.color = color.Copy();
for (size_t i = 0; i < extra_channels.size(); ++i) {
PackedImage ec = extra_channels[i].Copy();
copy.extra_channels.emplace_back(std::move(ec));
for (const auto& ec : extra_channels) {
copy.extra_channels.emplace_back(ec.Copy());
}
return copy;
}
@ -262,6 +277,8 @@ class PackedPixelFile {
// The icc profile of the original image.
std::vector<uint8_t> orig_icc;
JxlBitDepth input_bitdepth = {JXL_BIT_DEPTH_FROM_PIXEL_FORMAT, 0, 0};
std::unique_ptr<PackedFrame> preview_frame;
std::vector<PackedFrame> frames;
mutable std::vector<ChunkedPackedFrame> chunked_frames;

Просмотреть файл

@ -22,15 +22,15 @@ namespace jxl {
namespace extras {
Status ConvertPackedFrameToImageBundle(const JxlBasicInfo& info,
const JxlBitDepth& input_bitdepth,
const PackedFrame& frame,
const CodecInOut& io, ThreadPool* pool,
ImageBundle* bundle) {
JXL_ASSERT(frame.color.pixels() != nullptr);
const bool float_in = frame.color.format.data_type == JXL_TYPE_FLOAT16 ||
frame.color.format.data_type == JXL_TYPE_FLOAT;
size_t frame_bits_per_sample =
float_in ? PackedImage::BitsPerChannel(frame.color.format.data_type)
: info.bits_per_sample;
input_bitdepth.type == JXL_BIT_DEPTH_FROM_PIXEL_FORMAT
? PackedImage::BitsPerChannel(frame.color.format.data_type)
: info.bits_per_sample;
JXL_ASSERT(frame_bits_per_sample != 0);
// It is ok for the frame.color.format.num_channels to not match the
// number of channels on the image.
@ -98,17 +98,17 @@ Status ConvertPackedPixelFileToCodecInOut(const PackedPixelFile& ppf,
ppf.info.exponent_bits_per_sample == 0 && ppf.info.bits_per_sample <= 12;
io->metadata.m.SetAlphaBits(ppf.info.alpha_bits,
ppf.info.alpha_premultiplied);
FROM_JXL_BOOL(ppf.info.alpha_premultiplied));
ExtraChannelInfo* alpha = io->metadata.m.Find(ExtraChannel::kAlpha);
if (alpha) alpha->bit_depth = io->metadata.m.bit_depth;
io->metadata.m.xyb_encoded = !ppf.info.uses_original_profile;
io->metadata.m.xyb_encoded = !FROM_JXL_BOOL(ppf.info.uses_original_profile);
JXL_ASSERT(ppf.info.orientation > 0 && ppf.info.orientation <= 8);
io->metadata.m.orientation = ppf.info.orientation;
// Convert animation metadata
JXL_ASSERT(ppf.frames.size() == 1 || ppf.info.have_animation);
io->metadata.m.have_animation = ppf.info.have_animation;
io->metadata.m.have_animation = FROM_JXL_BOOL(ppf.info.have_animation);
io->metadata.m.animation.tps_numerator = ppf.info.animation.tps_numerator;
io->metadata.m.animation.tps_denominator = ppf.info.animation.tps_denominator;
io->metadata.m.animation.num_loops = ppf.info.animation.num_loops;
@ -171,15 +171,16 @@ Status ConvertPackedPixelFileToCodecInOut(const PackedPixelFile& ppf,
JXL_RETURN_IF_ERROR(
io->metadata.m.preview_size.Set(preview_xsize, preview_ysize));
JXL_RETURN_IF_ERROR(ConvertPackedFrameToImageBundle(
ppf.info, *ppf.preview_frame, *io, pool, &io->preview_frame));
ppf.info, ppf.input_bitdepth, *ppf.preview_frame, *io, pool,
&io->preview_frame));
}
// Convert the pixels
io->frames.clear();
for (const auto& frame : ppf.frames) {
ImageBundle bundle(&io->metadata.m);
JXL_RETURN_IF_ERROR(
ConvertPackedFrameToImageBundle(ppf.info, frame, *io, pool, &bundle));
JXL_RETURN_IF_ERROR(ConvertPackedFrameToImageBundle(
ppf.info, ppf.input_bitdepth, frame, *io, pool, &bundle));
io->frames.push_back(std::move(bundle));
}
@ -211,7 +212,8 @@ PackedPixelFile ConvertImage3FToPackedPixelFile(const Image3F& image,
: 0;
ppf.color_encoding = c_enc.ToExternal();
ppf.frames.clear();
PackedFrame frame(image.xsize(), image.ysize(), format);
JXL_ASSIGN_OR_DIE(PackedFrame frame,
PackedFrame::Create(image.xsize(), image.ysize(), format));
const ImageF* channels[3];
for (int c = 0; c < 3; ++c) {
channels[c] = &image.Plane(c);
@ -243,7 +245,8 @@ Status ConvertCodecInOutToPackedPixelFile(const CodecInOut& io,
ppf->info.alpha_bits = alpha_channel->bit_depth.bits_per_sample;
ppf->info.alpha_exponent_bits =
alpha_channel->bit_depth.exponent_bits_per_sample;
ppf->info.alpha_premultiplied = alpha_channel->alpha_associated;
ppf->info.alpha_premultiplied =
TO_JXL_BOOL(alpha_channel->alpha_associated);
}
// Convert the image metadata
@ -258,9 +261,9 @@ Status ConvertCodecInOutToPackedPixelFile(const CodecInOut& io,
ppf->info.linear_below = io.metadata.m.tone_mapping.linear_below;
ppf->info.min_nits = io.metadata.m.tone_mapping.min_nits;
ppf->info.relative_to_max_display =
io.metadata.m.tone_mapping.relative_to_max_display;
TO_JXL_BOOL(io.metadata.m.tone_mapping.relative_to_max_display);
ppf->info.uses_original_profile = !io.metadata.m.xyb_encoded;
ppf->info.uses_original_profile = TO_JXL_BOOL(!io.metadata.m.xyb_encoded);
JXL_ASSERT(0 < io.metadata.m.orientation && io.metadata.m.orientation <= 8);
ppf->info.orientation =
static_cast<JxlOrientation>(io.metadata.m.orientation);
@ -268,7 +271,7 @@ Status ConvertCodecInOutToPackedPixelFile(const CodecInOut& io,
// Convert animation metadata
JXL_ASSERT(io.frames.size() == 1 || io.metadata.m.have_animation);
ppf->info.have_animation = io.metadata.m.have_animation;
ppf->info.have_animation = TO_JXL_BOOL(io.metadata.m.have_animation);
ppf->info.animation.tps_numerator = io.metadata.m.animation.tps_numerator;
ppf->info.animation.tps_denominator = io.metadata.m.animation.tps_denominator;
ppf->info.animation.num_loops = io.metadata.m.animation.num_loops;
@ -293,15 +296,17 @@ Status ConvertCodecInOutToPackedPixelFile(const CodecInOut& io,
JXL_ASSERT(frame.metadata()->bit_depth.bits_per_sample != 0);
// It is ok for the frame.color().kNumPlanes to not match the
// number of channels on the image.
const uint32_t alpha_channels = has_alpha ? 1 : 0;
const uint32_t num_channels =
frame.metadata()->color_encoding.Channels() + has_alpha;
frame.metadata()->color_encoding.Channels() + alpha_channels;
JxlPixelFormat format{/*num_channels=*/num_channels,
/*data_type=*/pixel_format.data_type,
/*endianness=*/pixel_format.endianness,
/*align=*/pixel_format.align};
PackedFrame packed_frame(frame.oriented_xsize(), frame.oriented_ysize(),
format);
JXL_ASSIGN_OR_RETURN(PackedFrame packed_frame,
PackedFrame::Create(frame.oriented_xsize(),
frame.oriented_ysize(), format));
const size_t bits_per_sample =
float_out ? packed_frame.color.BitsPerChannel(pixel_format.data_type)
: ppf->info.bits_per_sample;

Просмотреть файл

@ -19,7 +19,7 @@ HWY_BEFORE_NAMESPACE();
namespace jxl {
namespace HWY_NAMESPACE {
static constexpr float rec2020_luminances[3] = {0.2627f, 0.6780f, 0.0593f};
static constexpr Vector3 rec2020_luminances{0.2627f, 0.6780f, 0.0593f};
Status ToneMapFrame(const std::pair<float, float> display_nits,
ImageBundle* const ib, ThreadPool* const pool) {

Просмотреть файл

@ -6,6 +6,7 @@
#include "benchmark/benchmark.h"
#include "lib/extras/codec.h"
#include "lib/extras/tone_mapping.h"
#include "lib/jxl/image.h"
namespace jxl {

Просмотреть файл

@ -126,7 +126,7 @@ typedef enum {
typedef enum {
/** Sets encoder effort/speed level without affecting decoding speed. Valid
* 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.
* 4:cheetah 5:hare 6:wombat 7:squirrel 8:kitten 9:tortoise 10:glacier.
* Default: squirrel (7).
*/
JXL_ENC_FRAME_SETTING_EFFORT = 0,
@ -1530,7 +1530,7 @@ JXL_EXPORT void JxlColorEncodingSetToLinearSRGB(
/**
* Enables usage of expert options.
*
* At the moment, the only expert option is setting an effort value of 10,
* At the moment, the only expert option is setting an effort value of 11,
* which gives the best compression for pixel-lossless modes but is very slow.
*
* @param enc encoder object.

2
third_party/jpeg-xl/lib/include/jxl/types.h поставляемый
Просмотреть файл

@ -33,6 +33,8 @@ extern "C" {
#define JXL_FALSE 0
/** Converts of bool-like value to either ::JXL_TRUE or ::JXL_FALSE. */
#define TO_JXL_BOOL(C) (!!(C) ? JXL_TRUE : JXL_FALSE)
/** Converts JXL_BOOL to C++ bool. */
#define FROM_JXL_BOOL(C) (static_cast<bool>(C))
/** Data type for the sample values per channel per pixel.
*/

1
third_party/jpeg-xl/lib/jpegli.cmake поставляемый
Просмотреть файл

@ -88,7 +88,6 @@ foreach (TESTFILE IN LISTS JPEGXL_INTERNAL_JPEGLI_TESTS)
target_link_libraries(${TESTNAME}
hwy
jpegli-static
gmock
GTest::GTest
GTest::Main
${JPEG_LIBRARIES}

Просмотреть файл

@ -5,6 +5,7 @@
#include "lib/jpegli/adaptive_quantization.h"
#include <jxl/types.h>
#include <stddef.h>
#include <stdlib.h>
@ -46,7 +47,7 @@ using hwy::HWY_NAMESPACE::Sqrt;
using hwy::HWY_NAMESPACE::Sub;
using hwy::HWY_NAMESPACE::ZeroIfNegative;
static constexpr float kInputScaling = 1.0f / 255.0f;
constexpr float kInputScaling = 1.0f / 255.0f;
// Primary template: default to actual division.
template <typename T, class V>
@ -65,7 +66,7 @@ struct FastDivision<float, V> {
}
V operator()(const V n, const V d) const {
#if 1 // Faster on SKX
#if JXL_TRUE // Faster on SKX
return Div(n, d);
#else
return n * ReciprocalNR(d);
@ -191,12 +192,12 @@ V ComputeMask(const D d, const V out_val) {
}
// mul and mul2 represent a scaling difference between jxl and butteraugli.
static const float kSGmul = 226.0480446705883f;
static const float kSGmul2 = 1.0f / 73.377132366608819f;
static const float kLog2 = 0.693147181f;
const float kSGmul = 226.0480446705883f;
const float kSGmul2 = 1.0f / 73.377132366608819f;
const float kLog2 = 0.693147181f;
// Includes correction factor for std::log -> log2.
static const float kSGRetMul = kSGmul2 * 18.6580932135f * kLog2;
static const float kSGVOffset = 7.14672470003f;
const float kSGRetMul = kSGmul2 * 18.6580932135f * kLog2;
const float kSGVOffset = 7.14672470003f;
template <bool invert, typename D, typename V>
V RatioOfDerivativesOfCubicRootToSimpleGamma(const D d, V v) {
@ -226,7 +227,7 @@ V RatioOfDerivativesOfCubicRootToSimpleGamma(const D d, V v) {
}
template <bool invert = false>
static float RatioOfDerivativesOfCubicRootToSimpleGamma(float v) {
float RatioOfDerivativesOfCubicRootToSimpleGamma(float v) {
using DScalar = HWY_CAPPED(float, 1);
auto vscalar = Load(DScalar(), &v);
return GetLane(
@ -503,7 +504,7 @@ HWY_EXPORT(PerBlockModulations);
namespace {
static constexpr int kPreErosionBorder = 1;
constexpr int kPreErosionBorder = 1;
} // namespace

7
third_party/jpeg-xl/lib/jpegli/bitstream.cc поставляемый
Просмотреть файл

@ -90,8 +90,8 @@ bool EncodeDQT(j_compress_ptr cinfo, bool write_all_tables) {
JPEGLI_ERROR("Missing quant table %d", i);
}
int precision = 0;
for (size_t k = 0; k < DCTSIZE2; ++k) {
if (quant_table->quantval[k] > 255) {
for (UINT16 q : quant_table->quantval) {
if (q > 255) {
precision = 1;
is_baseline = false;
}
@ -123,7 +123,6 @@ bool EncodeDQT(j_compress_ptr cinfo, bool write_all_tables) {
void EncodeSOF(j_compress_ptr cinfo, bool is_baseline) {
if (cinfo->data_precision != kJpegPrecision) {
is_baseline = false;
JPEGLI_ERROR("Unsupported data precision %d", cinfo->data_precision);
}
const uint8_t marker = cinfo->progressive_mode ? 0xc2
@ -302,7 +301,7 @@ void WriteBlock(const int32_t* JXL_RESTRICT symbols,
namespace {
static JXL_INLINE void EmitMarker(JpegBitWriter* bw, int marker) {
JXL_INLINE void EmitMarker(JpegBitWriter* bw, int marker) {
bw->data[bw->pos++] = 0xFF;
bw->data[bw->pos++] = marker;
}

5
third_party/jpeg-xl/lib/jpegli/bitstream.h поставляемый
Просмотреть файл

@ -32,9 +32,8 @@ void EncodeSOS(j_compress_ptr cinfo, int scan_index);
void WriteScanHeader(j_compress_ptr cinfo, int scan_index);
void WriteBlock(const int32_t* JXL_RESTRICT symbols,
const int32_t* JXL_RESTRICT extra_bits, const int num_nonzeros,
const bool emit_eob,
const HuffmanCodeTable* JXL_RESTRICT dc_code,
const int32_t* JXL_RESTRICT extra_bits, int num_nonzeros,
bool emit_eob, const HuffmanCodeTable* JXL_RESTRICT dc_code,
const HuffmanCodeTable* JXL_RESTRICT ac_code,
JpegBitWriter* JXL_RESTRICT bw);
void WriteScanData(j_compress_ptr cinfo, int scan_index);

Просмотреть файл

@ -11,13 +11,14 @@
#include "lib/jpegli/decode_internal.h"
#include "lib/jpegli/error.h"
#include "lib/jxl/base/status.h"
namespace jpegli {
namespace {
static constexpr int kNumColorCellBits[kMaxComponents] = {3, 4, 3, 3};
static constexpr int kCompW[kMaxComponents] = {2, 3, 1, 1};
constexpr int kNumColorCellBits[kMaxComponents] = {3, 4, 3, 3};
constexpr int kCompW[kMaxComponents] = {2, 3, 1, 1};
int Pow(int a, int b) {
int r = 1;
@ -102,8 +103,8 @@ namespace {
// 2^13 priority levels for the PQ seems to be a good compromise between
// accuracy, running time and stack space usage.
static const int kMaxPriority = 1 << 13;
static const int kMaxLevel = 3;
const int kMaxPriority = 1 << 13;
const int kMaxLevel = 3;
// This function is used in the multi-resolution grid to be able to compute
// the keys for the different resolutions by just shifting the first key.
@ -153,7 +154,7 @@ inline int ColorIntQuadDistanceRGB(uint8_t r1, uint8_t g1, uint8_t b1,
}
inline int ScaleQuadDistanceRGB(int d) {
return static_cast<int>(sqrt(d * 0.25) + 0.5);
return static_cast<int>(std::lround(sqrt(d * 0.25)));
}
// The function updates the minimal distances, the clustering and the
@ -216,9 +217,9 @@ struct WangHasher {
// to a unique integer index assigned to the different colors in order of
// appearance in the image. Return the number of unique colors found.
// The colors are pre-quantized to 3 * 6 bits precision.
static int BuildRGBColorIndex(const uint8_t* const image, int const num_pixels,
int* const count, uint8_t* const red,
uint8_t* const green, uint8_t* const blue) {
int BuildRGBColorIndex(const uint8_t* const image, int const num_pixels,
int* const count, uint8_t* const red,
uint8_t* const green, uint8_t* const blue) {
// Impossible because rgb are in the low 24 bits, and the upper 8 bits is 0.
const uint32_t impossible_pixel_value = 0x10000000;
std::unordered_map<uint32_t, int, RGBPixelHasher> index_map(1 << 12);
@ -264,7 +265,7 @@ void ChooseColorMap2Pass(j_decompress_ptr cinfo) {
std::unique_ptr<uint8_t[]> blue(new uint8_t[max_color_count]);
std::vector<int> count(max_color_count, 0);
// number of colors
int n = BuildRGBColorIndex(m->pixels_, num_pixels, &count[0], &red[0],
int n = BuildRGBColorIndex(m->pixels_, num_pixels, count.data(), &red[0],
&green[0], &blue[0]);
std::vector<int> dist(n, std::numeric_limits<int>::max());
@ -285,14 +286,14 @@ void ChooseColorMap2Pass(j_decompress_ptr cinfo) {
winner = i;
}
if (!in_palette[i] && count[i] > count_threshold) {
AddToRGBPalette(&red[0], &green[0], &blue[0], &count[0], i, k++, n,
&dist[0], &cluster[0], &center[0], &error);
AddToRGBPalette(&red[0], &green[0], &blue[0], count.data(), i, k++, n,
dist.data(), cluster.data(), &center[0], &error);
in_palette[i] = true;
}
}
if (k == 0) {
AddToRGBPalette(&red[0], &green[0], &blue[0], &count[0], winner, k++, n,
&dist[0], &cluster[0], &center[0], &error);
AddToRGBPalette(&red[0], &green[0], &blue[0], count.data(), winner, k++, n,
dist.data(), cluster.data(), &center[0], &error);
in_palette[winner] = true;
}
@ -365,8 +366,8 @@ void ChooseColorMap2Pass(j_decompress_ptr cinfo) {
if (priority < top_priority) {
bucket_array[priority].push_back(i);
} else {
AddToRGBPalette(&red[0], &green[0], &blue[0], &count[0], i, k++, n,
&dist[0], &cluster[0], &center[0], &error);
AddToRGBPalette(&red[0], &green[0], &blue[0], count.data(), i, k++, n,
dist.data(), cluster.data(), &center[0], &error);
}
bucket_array[top_priority].pop_back();
while (top_priority >= 0 && bucket_array[top_priority].empty()) {
@ -387,7 +388,7 @@ void ChooseColorMap2Pass(j_decompress_ptr cinfo) {
namespace {
void FindCandidatesForCell(j_decompress_ptr cinfo, int ncomp, int cell[],
void FindCandidatesForCell(j_decompress_ptr cinfo, int ncomp, const int cell[],
std::vector<uint8_t>* candidates) {
int cell_min[kMaxComponents];
int cell_max[kMaxComponents];
@ -404,7 +405,8 @@ void FindCandidatesForCell(j_decompress_ptr cinfo, int ncomp, int cell[],
int dmax = 0;
for (int c = 0; c < ncomp; ++c) {
int palette_c = cinfo->colormap[c][i];
int dminc = 0, dmaxc;
int dminc = 0;
int dmaxc;
if (palette_c < cell_min[c]) {
dminc = cell_min[c] - palette_c;
dmaxc = cell_max[c] - palette_c;
@ -436,6 +438,8 @@ void FindCandidatesForCell(j_decompress_ptr cinfo, int ncomp, int cell[],
void CreateInverseColorMap(j_decompress_ptr cinfo) {
jpeg_decomp_master* m = cinfo->master;
int ncomp = cinfo->out_color_components;
JXL_ASSERT(ncomp > 0);
JXL_ASSERT(ncomp <= kMaxComponents);
int num_cells = 1;
for (int c = 0; c < ncomp; ++c) {
num_cells *= (1 << kNumColorCellBits[c]);
@ -455,7 +459,7 @@ void CreateInverseColorMap(j_decompress_ptr cinfo) {
m->regenerate_inverse_colormap_ = false;
}
int LookupColorIndex(j_decompress_ptr cinfo, JSAMPLE* pixel) {
int LookupColorIndex(j_decompress_ptr cinfo, const JSAMPLE* pixel) {
jpeg_decomp_master* m = cinfo->master;
int num_channels = cinfo->out_color_components;
int index = 0;

Просмотреть файл

@ -20,7 +20,7 @@ void CreateOrderedDitherTables(j_decompress_ptr cinfo);
void InitFSDitherState(j_decompress_ptr cinfo);
int LookupColorIndex(j_decompress_ptr cinfo, JSAMPLE* pixel);
int LookupColorIndex(j_decompress_ptr cinfo, const JSAMPLE* pixel);
} // namespace jpegli

10
third_party/jpeg-xl/lib/jpegli/dct-inl.h поставляемый
Просмотреть файл

@ -187,7 +187,7 @@ void DCT1D(const float* JXL_RESTRICT pixels, size_t pixels_stride,
}
}
static JXL_INLINE JXL_MAYBE_UNUSED void TransformFromPixels(
JXL_INLINE JXL_MAYBE_UNUSED void TransformFromPixels(
const float* JXL_RESTRICT pixels, size_t pixels_stride,
float* JXL_RESTRICT coefficients, float* JXL_RESTRICT scratch_space) {
DCT1D(pixels, pixels_stride, scratch_space);
@ -196,14 +196,14 @@ static JXL_INLINE JXL_MAYBE_UNUSED void TransformFromPixels(
Transpose8x8Block(scratch_space, coefficients);
}
static JXL_INLINE JXL_MAYBE_UNUSED void StoreQuantizedValue(const Vec<DI>& ival,
int16_t* out) {
JXL_INLINE JXL_MAYBE_UNUSED void StoreQuantizedValue(const Vec<DI>& ival,
int16_t* out) {
Rebind<int16_t, DI> di16;
Store(DemoteTo(di16, ival), di16, out);
}
static JXL_INLINE JXL_MAYBE_UNUSED void StoreQuantizedValue(const Vec<DI>& ival,
int32_t* out) {
JXL_INLINE JXL_MAYBE_UNUSED void StoreQuantizedValue(const Vec<DI>& ival,
int32_t* out) {
DI di;
Store(ival, di, out);
}

39
third_party/jpeg-xl/lib/jpegli/decode.cc поставляемый
Просмотреть файл

@ -115,8 +115,10 @@ void InitProgressMonitor(j_decompress_ptr cinfo, bool coef_only) {
cinfo->progress->total_passes = 1;
} else {
int input_passes = !cinfo->buffered_image && m->is_multiscan_ ? 1 : 0;
bool two_pass_quant = cinfo->quantize_colors && !cinfo->colormap &&
cinfo->two_pass_quantize && cinfo->enable_2pass_quant;
bool two_pass_quant = FROM_JXL_BOOL(cinfo->quantize_colors) &&
(cinfo->colormap != nullptr) &&
FROM_JXL_BOOL(cinfo->two_pass_quantize) &&
FROM_JXL_BOOL(cinfo->enable_2pass_quant);
cinfo->progress->total_passes = input_passes + (two_pass_quant ? 2 : 1);
}
cinfo->progress->completed_passes = 0;
@ -175,7 +177,7 @@ void BuildHuffmanLookupTable(j_decompress_ptr cinfo, JHUFF_TBL* table,
for (int i = 0; i < total_count; ++i) {
int value = table->huffval[i];
if (values_seen[value]) {
return JPEGLI_ERROR("Duplicate Huffman code value %d", value);
JPEGLI_ERROR("Duplicate Huffman code value %d", value);
}
values_seen[value] = 1;
values[i] = value;
@ -223,7 +225,7 @@ void PrepareForScan(j_decompress_ptr cinfo) {
HuffmanTableEntry* huff_lut =
&m->dc_huff_lut_[dc_tbl_idx * kJpegHuffmanLutSize];
if (!table) {
return JPEGLI_ERROR("DC Huffman table %d not found", dc_tbl_idx);
JPEGLI_ERROR("DC Huffman table %d not found", dc_tbl_idx);
}
BuildHuffmanLookupTable(cinfo, table, huff_lut);
}
@ -233,7 +235,7 @@ void PrepareForScan(j_decompress_ptr cinfo) {
HuffmanTableEntry* huff_lut =
&m->ac_huff_lut_[ac_tbl_idx * kJpegHuffmanLutSize];
if (!table) {
return JPEGLI_ERROR("AC Huffman table %d not found", ac_tbl_idx);
JPEGLI_ERROR("AC Huffman table %d not found", ac_tbl_idx);
}
BuildHuffmanLookupTable(cinfo, table, huff_lut);
}
@ -543,8 +545,8 @@ void jpegli_CreateDecompress(j_decompress_ptr cinfo, int version,
cinfo->is_decompressor = TRUE;
cinfo->progress = nullptr;
cinfo->src = nullptr;
for (int i = 0; i < NUM_QUANT_TBLS; i++) {
cinfo->quant_tbl_ptrs[i] = nullptr;
for (auto& quant_tbl_ptr : cinfo->quant_tbl_ptrs) {
quant_tbl_ptr = nullptr;
}
for (int i = 0; i < NUM_HUFF_TBLS; i++) {
cinfo->dc_huff_tbl_ptrs[i] = nullptr;
@ -555,8 +557,8 @@ void jpegli_CreateDecompress(j_decompress_ptr cinfo, int version,
cinfo->rec_outbuf_height = 1; // output works with any buffer height
cinfo->master = new jpeg_decomp_master;
jpeg_decomp_master* m = cinfo->master;
for (int i = 0; i < 16; ++i) {
m->app_marker_parsers[i] = nullptr;
for (auto& app_marker_parser : m->app_marker_parsers) {
app_marker_parser = nullptr;
}
m->com_marker_parser = nullptr;
memset(m->markers_to_save_, 0, sizeof(m->markers_to_save_));
@ -661,7 +663,7 @@ boolean jpegli_read_icc_profile(j_decompress_ptr cinfo, JOCTET** icc_data_ptr,
return FALSE;
}
*icc_data_len = m->icc_profile_.size();
*icc_data_ptr = (JOCTET*)malloc(*icc_data_len);
*icc_data_ptr = static_cast<JOCTET*>(malloc(*icc_data_len));
if (*icc_data_ptr == nullptr) {
JPEGLI_ERROR("jpegli_read_icc_profile: Out of memory");
}
@ -738,21 +740,26 @@ void jpegli_calc_output_dimensions(j_decompress_ptr cinfo) {
}
boolean jpegli_has_multiple_scans(j_decompress_ptr cinfo) {
if (cinfo->input_scan_number == 0) {
JPEGLI_ERROR("No SOS marker found.");
if (cinfo->global_state != jpegli::kDecHeaderDone &&
cinfo->global_state != jpegli::kDecProcessScan &&
cinfo->global_state != jpegli::kDecProcessMarkers) {
JPEGLI_ERROR("jpegli_has_multiple_scans: unexpected state %d",
cinfo->global_state);
}
return cinfo->master->is_multiscan_;
return TO_JXL_BOOL(cinfo->master->is_multiscan_);
}
boolean jpegli_input_complete(j_decompress_ptr cinfo) {
return cinfo->master->found_eoi_;
return TO_JXL_BOOL(cinfo->master->found_eoi_);
}
boolean jpegli_start_decompress(j_decompress_ptr cinfo) {
jpeg_decomp_master* m = cinfo->master;
if (cinfo->global_state == jpegli::kDecHeaderDone) {
m->streaming_mode_ = !m->is_multiscan_ && !cinfo->buffered_image &&
(!cinfo->quantize_colors || !cinfo->two_pass_quantize);
m->streaming_mode_ = !m->is_multiscan_ &&
!FROM_JXL_BOOL(cinfo->buffered_image) &&
(!FROM_JXL_BOOL(cinfo->quantize_colors) ||
!FROM_JXL_BOOL(cinfo->two_pass_quantize));
jpegli::AllocateCoefficientBuffer(cinfo);
jpegli_calc_output_dimensions(cinfo);
jpegli::PrepareForScan(cinfo);

Просмотреть файл

@ -18,8 +18,8 @@
namespace jpegli {
namespace {
static constexpr uint8_t kFakeEoiMarker[2] = {0xff, 0xd9};
static constexpr size_t kNumSourceBuffers = 4;
constexpr uint8_t kFakeEoiMarker[2] = {0xff, 0xd9};
constexpr size_t kNumSourceBuffers = 4;
// Custom source manager that refills the input buffer in chunks, simulating
// a file reader with a fixed buffer size.
@ -61,7 +61,7 @@ class SourceManager {
static void init_source(j_decompress_ptr cinfo) {}
static boolean fill_input_buffer(j_decompress_ptr cinfo) {
auto src = reinterpret_cast<SourceManager*>(cinfo->src);
auto* src = reinterpret_cast<SourceManager*>(cinfo->src);
if (src->pos_ < src->len_) {
size_t chunk_size = std::min(src->len_ - src->pos_, src->max_chunk_size_);
size_t next_idx = ++src->chunk_idx_ % kNumSourceBuffers;
@ -79,7 +79,7 @@ class SourceManager {
}
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
auto src = reinterpret_cast<SourceManager*>(cinfo->src);
auto* src = reinterpret_cast<SourceManager*>(cinfo->src);
if (num_bytes <= 0) {
return;
}
@ -166,9 +166,9 @@ void ReadOutputImage(const DecompressParams& dparams, j_decompress_ptr cinfo,
rowdata[c][i] =
y0 + i < ysize ? &output->raw_data[c][(y0 + i) * xsize] : nullptr;
}
data[c] = &rowdata[c][0];
data[c] = rowdata[c].data();
}
num_output_lines = jpegli_read_raw_data(cinfo, &data[0], max_lines);
num_output_lines = jpegli_read_raw_data(cinfo, data.data(), max_lines);
} else {
size_t max_output_lines = dparams.max_output_lines;
if (max_output_lines == 0) max_output_lines = cinfo->output_height;
@ -189,7 +189,7 @@ void ReadOutputImage(const DecompressParams& dparams, j_decompress_ptr cinfo,
scanlines[i] = &output->pixels[yidx * stride];
}
num_output_lines =
jpegli_read_scanlines(cinfo, &scanlines[0], max_lines);
jpegli_read_scanlines(cinfo, scanlines.data(), max_lines);
if (cinfo->quantize_colors) {
for (size_t i = 0; i < num_output_lines; ++i) {
UnmapColors(scanlines[i], cinfo->output_width,
@ -222,7 +222,7 @@ struct TestConfig {
std::vector<uint8_t> GetTestJpegData(TestConfig& config) {
std::vector<uint8_t> compressed;
if (!config.fn.empty()) {
compressed = ReadTestData(config.fn.c_str());
compressed = ReadTestData(config.fn);
} else {
GeneratePixels(&config.input);
JXL_CHECK(EncodeWithJpegli(config.input, config.jparams, &compressed));
@ -297,10 +297,10 @@ void TestAPIBuffered(const CompressParams& jparams,
SetDecompressParams(dparams, cinfo);
jpegli_set_output_format(cinfo, dparams.data_type, dparams.endianness);
VerifyHeader(jparams, cinfo);
bool has_multiple_scans = FROM_JXL_BOOL(jpegli_has_multiple_scans(cinfo));
EXPECT_TRUE(jpegli_start_decompress(cinfo));
// start decompress should not read the whole input in buffered image mode
EXPECT_FALSE(jpegli_input_complete(cinfo));
bool has_multiple_scans = jpegli_has_multiple_scans(cinfo);
EXPECT_EQ(0, cinfo->output_scan_number);
int sos_marker_cnt = 1; // read_header reads the first SOS marker
while (!jpegli_input_complete(cinfo)) {
@ -341,8 +341,11 @@ void TestAPIBuffered(const CompressParams& jparams,
}
TEST(DecodeAPITest, ReuseCinfo) {
TestImage input, output, expected;
std::vector<TestImage> output_progression, expected_output_progression;
TestImage input;
TestImage output;
TestImage expected;
std::vector<TestImage> output_progression;
std::vector<TestImage> expected_output_progression;
CompressParams jparams;
DecompressParams dparams;
std::vector<uint8_t> compressed;
@ -383,8 +386,8 @@ TEST(DecodeAPITest, ReuseCinfo) {
expected.Clear();
DecodeWithLibjpeg(jparams, dparams, compressed, &expected);
output.Clear();
cinfo.buffered_image = false;
cinfo.raw_data_out = false;
cinfo.buffered_image = JXL_FALSE;
cinfo.raw_data_out = JXL_FALSE;
cinfo.scale_num = cinfo.scale_denom = 1;
SourceManager src(compressed.data(), compressed.size(),
1u << 12);
@ -1245,7 +1248,8 @@ std::ostream& operator<<(std::ostream& os, const DecompressParams& dparams) {
}
os << IOMethodName(dparams.data_type, dparams.endianness);
if (dparams.set_out_color_space) {
os << "OutColor" << ColorSpaceName((J_COLOR_SPACE)dparams.out_color_space);
os << "OutColor"
<< ColorSpaceName(static_cast<J_COLOR_SPACE>(dparams.out_color_space));
}
if (dparams.crop_output) {
os << "Crop";
@ -1265,7 +1269,8 @@ std::ostream& operator<<(std::ostream& os, const DecompressParams& dparams) {
if (i > 0) os << "_";
const auto& sparam = dparams.scan_params[i];
os << QuantMode(sparam.color_quant_mode);
os << DitherMode((J_DITHER_MODE)sparam.dither_mode) << "Dither";
os << DitherMode(static_cast<J_DITHER_MODE>(sparam.dither_mode))
<< "Dither";
}
}
if (dparams.skip_scans) {

Просмотреть файл

@ -45,12 +45,13 @@ struct jpeg_decomp_master {
size_t input_buffer_pos_;
// Number of bits after codestream_pos_ that were already processed.
size_t codestream_bits_ahead_;
bool streaming_mode_;
// Coefficient buffers
jvirt_barray_ptr* coef_arrays;
JBLOCKARRAY coeff_rows[jpegli::kMaxComponents];
bool streaming_mode_;
//
// Marker data processing state.
//
@ -58,6 +59,11 @@ struct jpeg_decomp_master {
bool found_dri_;
bool found_sof_;
bool found_eoi_;
// Whether this jpeg has multiple scans (progressive or non-interleaved
// sequential).
bool is_multiscan_;
size_t icc_index_;
size_t icc_total_;
std::vector<uint8_t> icc_profile_;
@ -66,9 +72,6 @@ struct jpeg_decomp_master {
uint8_t markers_to_save_[32];
jpeg_marker_parser_method app_marker_parsers[16];
jpeg_marker_parser_method com_marker_parser;
// Whether this jpeg has multiple scans (progressive or non-interleaved
// sequential).
bool is_multiscan_;
// Fields defined by SOF marker.
size_t iMCU_cols_;
@ -96,9 +99,11 @@ struct jpeg_decomp_master {
//
int output_passes_done_;
JpegliDataType output_data_type_ = JPEGLI_TYPE_UINT8;
bool swap_endianness_ = false;
size_t xoffset_;
bool swap_endianness_ = false;
bool need_context_rows_;
bool regenerate_inverse_colormap_;
bool apply_smoothing;
int min_scaled_dct_size;
int scaled_dct_size[jpegli::kMaxComponents];
@ -127,7 +132,6 @@ struct jpeg_decomp_master {
uint8_t* pixels_;
JSAMPARRAY scanlines_;
std::vector<std::vector<uint8_t>> candidate_lists_;
bool regenerate_inverse_colormap_;
float* dither_[jpegli::kMaxComponents];
float* error_row_[2 * jpegli::kMaxComponents];
size_t dither_size_;
@ -145,7 +149,6 @@ struct jpeg_decomp_master {
// i.e. the bottom half when rendering incomplete scans.
int (*coef_bits_latch)[SAVED_COEFS];
int (*prev_coef_bits_latch)[SAVED_COEFS];
bool apply_smoothing;
};
#endif // LIB_JPEGLI_DECODE_INTERNAL_H_

Просмотреть файл

@ -5,6 +5,7 @@
#include "lib/jpegli/decode_marker.h"
#include <jxl/types.h>
#include <string.h>
#include "lib/jpegli/common.h"
@ -22,23 +23,22 @@ constexpr uint8_t kIccProfileTag[12] = "ICC_PROFILE";
// Macros for commonly used error conditions.
#define JPEG_VERIFY_LEN(n) \
if (pos + (n) > len) { \
return JPEGLI_ERROR("Unexpected end of marker: pos=%" PRIuS \
" need=%d len=%" PRIuS, \
pos, static_cast<int>(n), len); \
#define JPEG_VERIFY_LEN(n) \
if (pos + (n) > len) { \
JPEGLI_ERROR("Unexpected end of marker: pos=%" PRIuS \
" need=%d len=%" PRIuS, \
pos, static_cast<int>(n), len); \
}
#define JPEG_VERIFY_INPUT(var, low, high) \
if ((var) < (low) || (var) > (high)) { \
return JPEGLI_ERROR("Invalid " #var ": %d", static_cast<int>(var)); \
#define JPEG_VERIFY_INPUT(var, low, high) \
if ((var) < (low) || (var) > (high)) { \
JPEGLI_ERROR("Invalid " #var ": %d", static_cast<int>(var)); \
}
#define JPEG_VERIFY_MARKER_END() \
if (pos != len) { \
return JPEGLI_ERROR("Invalid marker length: declared=%" PRIuS \
" actual=%" PRIuS, \
len, pos); \
#define JPEG_VERIFY_MARKER_END() \
if (pos != len) { \
JPEGLI_ERROR("Invalid marker length: declared=%" PRIuS " actual=%" PRIuS, \
len, pos); \
}
inline int ReadUint8(const uint8_t* data, size_t* pos) {
@ -60,7 +60,7 @@ void ProcessSOF(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
JPEGLI_ERROR("Duplicate SOF marker.");
}
m->found_sof_ = true;
cinfo->progressive_mode = (cinfo->unread_marker == 0xc2);
cinfo->progressive_mode = TO_JXL_BOOL(cinfo->unread_marker == 0xc2);
cinfo->arith_code = 0;
size_t pos = 2;
JPEG_VERIFY_LEN(6);
@ -181,7 +181,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
for (int i = 0; i < cinfo->comps_in_scan; ++i) {
int id = ReadUint8(data, &pos);
if (ids_seen[id]) { // (cf. section B.2.3, regarding CSj)
return JPEGLI_ERROR("Duplicate ID %d in SOS.", id);
JPEGLI_ERROR("Duplicate ID %d in SOS.", id);
}
ids_seen[id] = 1;
jpeg_component_info* comp = nullptr;
@ -192,8 +192,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
}
if (!comp) {
return JPEGLI_ERROR("SOS marker: Could not find component with id %d",
id);
JPEGLI_ERROR("SOS marker: Could not find component with id %d", id);
}
int c = ReadUint8(data, &pos);
comp->dc_tbl_no = c >> 4;
@ -222,7 +221,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
if (cinfo->input_scan_number == 0) {
m->is_multiscan_ = (cinfo->comps_in_scan < cinfo->num_components ||
cinfo->progressive_mode);
FROM_JXL_BOOL(cinfo->progressive_mode));
}
if (cinfo->Ah != 0 && cinfo->Al != cinfo->Ah - 1) {
// section G.1.1.1.2 : Successive approximation control only improves
@ -261,12 +260,12 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
int comp_idx = cinfo->cur_comp_info[i]->component_index;
for (int k = cinfo->Ss; k <= cinfo->Se; ++k) {
if (m->scan_progression_[comp_idx][k] & scan_bitmask) {
return JPEGLI_ERROR(
JPEGLI_ERROR(
"Overlapping scans: component=%d k=%d prev_mask: %u cur_mask %u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
}
if (m->scan_progression_[comp_idx][k] & refinement_bitmask) {
return JPEGLI_ERROR(
JPEGLI_ERROR(
"Invalid scan order, a more refined scan was already done: "
"component=%d k=%d prev_mask=%u cur_mask=%u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
@ -275,7 +274,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
}
if (cinfo->Al > 10) {
return JPEGLI_ERROR("Scan parameter Al=%d is not supported.", cinfo->Al);
JPEGLI_ERROR("Scan parameter Al=%d is not supported.", cinfo->Al);
}
}
@ -285,7 +284,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
size_t pos = 2;
if (pos == len) {
return JPEGLI_ERROR("DHT marker: no Huffman table found");
JPEGLI_ERROR("DHT marker: no Huffman table found");
}
while (pos < len) {
JPEG_VERIFY_LEN(1 + kJpegHuffmanMaxBitLength);
@ -293,7 +292,7 @@ void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
// component Huffman codes, 0x10 is added to the index.
int slot_id = ReadUint8(data, &pos);
int huffman_index = slot_id;
int is_ac_table = (slot_id & 0x10) != 0;
bool is_ac_table = ((slot_id & 0x10) != 0);
JHUFF_TBL** table;
if (is_ac_table) {
huffman_index -= 0x10;
@ -343,7 +342,7 @@ void ProcessDQT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
size_t pos = 2;
if (pos == len) {
return JPEGLI_ERROR("DQT marker: no quantization table found");
JPEGLI_ERROR("DQT marker: no quantization table found");
}
while (pos < len) {
JPEG_VERIFY_LEN(1);
@ -377,7 +376,7 @@ void ProcessDNL(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
void ProcessDRI(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
jpeg_decomp_master* m = cinfo->master;
if (m->found_dri_) {
return JPEGLI_ERROR("Duplicate DRI marker.");
JPEGLI_ERROR("Duplicate DRI marker.");
}
m->found_dri_ = true;
size_t pos = 2;
@ -411,24 +410,24 @@ void ProcessAPP(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
payload += sizeof(kIccProfileTag);
payload_size -= sizeof(kIccProfileTag);
if (payload_size < 2) {
return JPEGLI_ERROR("ICC chunk is too small.");
JPEGLI_ERROR("ICC chunk is too small.");
}
uint8_t index = payload[0];
uint8_t total = payload[1];
++m->icc_index_;
if (m->icc_index_ != index) {
return JPEGLI_ERROR("Invalid ICC chunk order.");
JPEGLI_ERROR("Invalid ICC chunk order.");
}
if (total == 0) {
return JPEGLI_ERROR("Invalid ICC chunk total.");
JPEGLI_ERROR("Invalid ICC chunk total.");
}
if (m->icc_total_ == 0) {
m->icc_total_ = total;
} else if (m->icc_total_ != total) {
return JPEGLI_ERROR("Invalid ICC chunk total.");
JPEGLI_ERROR("Invalid ICC chunk total.");
}
if (m->icc_index_ > m->icc_total_) {
return JPEGLI_ERROR("Invalid ICC chunk index.");
JPEGLI_ERROR("Invalid ICC chunk index.");
}
m->icc_profile_.insert(m->icc_profile_.end(), payload + 2,
payload + payload_size);
@ -494,8 +493,8 @@ uint8_t ProcessNextMarker(j_decompress_ptr cinfo, const uint8_t* const data,
marker = data[*pos + 1];
if (num_skipped > 0) {
if (m->found_soi_) {
JPEGLI_WARN("Skipped %d bytes before marker 0x%02x", (int)num_skipped,
marker);
JPEGLI_WARN("Skipped %d bytes before marker 0x%02x",
static_cast<int>(num_skipped), marker);
} else {
JPEGLI_ERROR("Did not find SOI marker.");
}

Просмотреть файл

@ -22,8 +22,8 @@ namespace jpegli {
// EOI marker. Input buffer refill is handled by the caller;
// * JPEG_REACHED_SOS, if the next SOS marker is found;
// * JPEG_REACHED_EOR, if the end of the input is found.
int ProcessMarkers(j_decompress_ptr cinfo, const uint8_t* const data,
const size_t len, size_t* pos);
int ProcessMarkers(j_decompress_ptr cinfo, const uint8_t* data, size_t len,
size_t* pos);
jpeg_marker_parser_method GetMarkerProcessor(j_decompress_ptr cinfo);

Просмотреть файл

@ -61,7 +61,7 @@ struct BitReaderState {
if (bits_left_ <= 16) {
while (bits_left_ <= 56) {
val_ <<= 8;
val_ |= (uint64_t)GetNextByte();
val_ |= static_cast<uint64_t>(GetNextByte());
bits_left_ += 8;
}
}
@ -427,7 +427,7 @@ void PrepareForiMCURow(j_decompress_ptr cinfo) {
int offset = m->streaming_mode_ ? 0 : by0;
m->coeff_rows[c] = (*cinfo->mem->access_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), m->coef_arrays[c], offset,
max_block_rows, true);
max_block_rows, TRUE);
}
}
@ -451,7 +451,8 @@ int ProcessScan(j_decompress_ptr cinfo, const uint8_t* const data,
++num_skipped;
}
if (num_skipped > 0) {
JPEGLI_WARN("Skipped %d bytes before restart marker", (int)num_skipped);
JPEGLI_WARN("Skipped %d bytes before restart marker",
static_cast<int>(num_skipped));
}
if (*pos + 2 > len) {
return kNeedMoreInput;
@ -471,7 +472,7 @@ int ProcessScan(j_decompress_ptr cinfo, const uint8_t* const data,
}
// Decode one MCU.
HWY_ALIGN_MAX coeff_t sink_block[DCTSIZE2];
HWY_ALIGN_MAX static coeff_t sink_block[DCTSIZE2] = {0};
bool scan_ok = true;
for (int i = 0; i < cinfo->comps_in_scan; ++i) {
const jpeg_component_info* comp = cinfo->cur_comp_info[i];

Просмотреть файл

@ -21,8 +21,8 @@ namespace jpegli {
// * JPEG_SUSPENDED, if the input buffer ends before the end of an iMCU row;
// * JPEG_ROW_COMPLETED, if the next iMCU row (but not the scan) is reached;
// * JPEG_SCAN_COMPLETED, if the end of the scan is reached.
int ProcessScan(j_decompress_ptr cinfo, const uint8_t* const data,
const size_t len, size_t* pos, size_t* bit_pos);
int ProcessScan(j_decompress_ptr cinfo, const uint8_t* data, size_t len,
size_t* pos, size_t* bit_pos);
void PrepareForiMCURow(j_decompress_ptr cinfo);

Просмотреть файл

@ -19,13 +19,13 @@ struct StdioDestinationManager {
uint8_t* buffer;
static void init_destination(j_compress_ptr cinfo) {
auto dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = kDestBufferSize;
}
static boolean empty_output_buffer(j_compress_ptr cinfo) {
auto dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
if (fwrite(dest->buffer, 1, kDestBufferSize, dest->f) != kDestBufferSize) {
JPEGLI_ERROR("Failed to write to output stream.");
}
@ -35,7 +35,7 @@ struct StdioDestinationManager {
}
static void term_destination(j_compress_ptr cinfo) {
auto dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<StdioDestinationManager*>(cinfo->dest);
size_t bytes_left = kDestBufferSize - dest->pub.free_in_buffer;
if (bytes_left &&
fwrite(dest->buffer, 1, bytes_left, dest->f) != bytes_left) {
@ -62,7 +62,7 @@ struct MemoryDestinationManager {
static void init_destination(j_compress_ptr cinfo) {}
static boolean empty_output_buffer(j_compress_ptr cinfo) {
auto dest = reinterpret_cast<MemoryDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<MemoryDestinationManager*>(cinfo->dest);
uint8_t* next_buffer =
reinterpret_cast<uint8_t*>(malloc(dest->buffer_size * 2));
memcpy(next_buffer, dest->current_buffer, dest->buffer_size);
@ -80,7 +80,7 @@ struct MemoryDestinationManager {
}
static void term_destination(j_compress_ptr cinfo) {
auto dest = reinterpret_cast<MemoryDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<MemoryDestinationManager*>(cinfo->dest);
*dest->output_size = dest->buffer_size - dest->pub.free_in_buffer;
}
};
@ -99,7 +99,7 @@ void jpegli_stdio_dest(j_compress_ptr cinfo, FILE* outfile) {
cinfo->dest = reinterpret_cast<jpeg_destination_mgr*>(
jpegli::Allocate<jpegli::StdioDestinationManager>(cinfo, 1));
}
auto dest = reinterpret_cast<jpegli::StdioDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<jpegli::StdioDestinationManager*>(cinfo->dest);
dest->f = outfile;
dest->buffer = jpegli::Allocate<uint8_t>(cinfo, jpegli::kDestBufferSize);
dest->pub.next_output_byte = dest->buffer;
@ -122,11 +122,11 @@ void jpegli_mem_dest(j_compress_ptr cinfo, unsigned char** outbuffer,
JPEGLI_ERROR("jpegli_mem_dest: a different dest manager was already set");
}
if (!cinfo->dest) {
auto dest = jpegli::Allocate<jpegli::MemoryDestinationManager>(cinfo, 1);
auto* dest = jpegli::Allocate<jpegli::MemoryDestinationManager>(cinfo, 1);
dest->temp_buffer = nullptr;
cinfo->dest = reinterpret_cast<jpeg_destination_mgr*>(dest);
}
auto dest = reinterpret_cast<jpegli::MemoryDestinationManager*>(cinfo->dest);
auto* dest = reinterpret_cast<jpegli::MemoryDestinationManager*>(cinfo->dest);
dest->pub.init_destination =
jpegli::MemoryDestinationManager::init_destination;
dest->pub.empty_output_buffer =

Просмотреть файл

@ -29,7 +29,7 @@ void DownsampleRow2x1(const float* row_in, size_t len, float* row_out) {
const size_t N = Lanes(d);
const size_t len_out = len / 2;
const auto mul = Set(d, 0.5f);
Vec<D> v0, v1;
Vec<D> v0, v1; // NOLINT
for (size_t x = 0; x < len_out; x += N) {
LoadInterleaved2(d, row_in + 2 * x, v0, v1);
Store(Mul(mul, Add(v0, v1)), d, row_out + x);
@ -40,7 +40,7 @@ void DownsampleRow3x1(const float* row_in, size_t len, float* row_out) {
const size_t N = Lanes(d);
const size_t len_out = len / 3;
const auto mul = Set(d, 1.0f / 3);
Vec<D> v0, v1, v2;
Vec<D> v0, v1, v2; // NOLINT
for (size_t x = 0; x < len_out; x += N) {
LoadInterleaved3(d, row_in + 3 * x, v0, v1, v2);
Store(Mul(mul, Add(Add(v0, v1), v2)), d, row_out + x);
@ -51,7 +51,7 @@ void DownsampleRow4x1(const float* row_in, size_t len, float* row_out) {
const size_t N = Lanes(d);
const size_t len_out = len / 4;
const auto mul = Set(d, 0.25f);
Vec<D> v0, v1, v2, v3;
Vec<D> v0, v1, v2, v3; // NOLINT
for (size_t x = 0; x < len_out; x += N) {
LoadInterleaved4(d, row_in + 4 * x, v0, v1, v2, v3);
Store(Mul(mul, Add(Add(v0, v1), Add(v2, v3))), d, row_out + x);
@ -91,7 +91,7 @@ void Downsample2x2(float* rows_in[MAX_SAMP_FACTOR], size_t len,
const auto mul = Set(d, 0.25f);
float* row0 = rows_in[0];
float* row1 = rows_in[1];
Vec<D> v0, v1, v2, v3;
Vec<D> v0, v1, v2, v3; // NOLINT
for (size_t x = 0; x < len_out; x += N) {
LoadInterleaved2(d, row0 + 2 * x, v0, v1);
LoadInterleaved2(d, row1 + 2 * x, v2, v3);

33
third_party/jpeg-xl/lib/jpegli/encode.cc поставляемый
Просмотреть файл

@ -5,6 +5,8 @@
#include "lib/jpegli/encode.h"
#include <jxl/types.h>
#include <cmath>
#include <initializer_list>
#include <vector>
@ -323,8 +325,8 @@ void ProcessCompressionParams(j_compress_ptr cinfo) {
if (cinfo->scan_info == nullptr) {
SetDefaultScanScript(cinfo);
}
cinfo->progressive_mode =
cinfo->scan_info->Ss != 0 || cinfo->scan_info->Se != DCTSIZE2 - 1;
cinfo->progressive_mode = TO_JXL_BOOL(cinfo->scan_info->Ss != 0 ||
cinfo->scan_info->Se != DCTSIZE2 - 1);
ValidateScanScript(cinfo);
m->scan_token_info =
Allocate<ScanTokenInfo>(cinfo, cinfo->num_scans, JPOOL_IMAGE);
@ -449,7 +451,7 @@ void AllocateBuffers(j_compress_ptr cinfo) {
const size_t ysize_blocks = comp->height_in_blocks;
m->coeff_buffers[c] = (*cinfo->mem->request_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), JPOOL_IMAGE,
/*pre_zero=*/false, xsize_blocks, ysize_blocks, comp->v_samp_factor);
/*pre_zero=*/FALSE, xsize_blocks, ysize_blocks, comp->v_samp_factor);
}
}
if (m->use_adaptive_quantization) {
@ -663,8 +665,8 @@ void jpegli_CreateCompress(j_compress_ptr cinfo, int version,
cinfo->num_components = 0;
cinfo->jpeg_color_space = JCS_UNKNOWN;
cinfo->comp_info = nullptr;
for (int i = 0; i < NUM_QUANT_TBLS; ++i) {
cinfo->quant_tbl_ptrs[i] = nullptr;
for (auto& quant_tbl_ptr : cinfo->quant_tbl_ptrs) {
quant_tbl_ptr = nullptr;
}
for (int i = 0; i < NUM_HUFF_TBLS; ++i) {
cinfo->dc_huff_tbl_ptrs[i] = nullptr;
@ -673,7 +675,7 @@ void jpegli_CreateCompress(j_compress_ptr cinfo, int version,
memset(cinfo->arith_dc_L, 0, sizeof(cinfo->arith_dc_L));
memset(cinfo->arith_dc_U, 0, sizeof(cinfo->arith_dc_U));
memset(cinfo->arith_ac_K, 0, sizeof(cinfo->arith_ac_K));
cinfo->write_Adobe_marker = false;
cinfo->write_Adobe_marker = FALSE;
cinfo->master = jpegli::Allocate<jpeg_comp_master>(cinfo, 1);
jpegli::InitializeCompressParams(cinfo);
cinfo->master->force_baseline = true;
@ -763,7 +765,7 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) {
JPEGLI_ERROR("Unsupported jpeg colorspace %d", colorspace);
}
// Adobe marker is only needed to distinguish CMYK and YCCK JPEGs.
cinfo->write_Adobe_marker = (cinfo->jpeg_color_space == JCS_YCCK);
cinfo->write_Adobe_marker = TO_JXL_BOOL(cinfo->jpeg_color_space == JCS_YCCK);
if (cinfo->comp_info == nullptr) {
cinfo->comp_info =
jpegli::Allocate<jpeg_component_info>(cinfo, MAX_COMPONENTS);
@ -810,7 +812,7 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) {
void jpegli_set_distance(j_compress_ptr cinfo, float distance,
boolean force_baseline) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->master->force_baseline = force_baseline;
cinfo->master->force_baseline = FROM_JXL_BOOL(force_baseline);
float distances[NUM_QUANT_TBLS] = {distance, distance, distance};
jpegli::SetQuantMatrices(cinfo, distances, /*add_two_chroma_tables=*/true);
}
@ -834,7 +836,7 @@ void jpegli_set_psnr(j_compress_ptr cinfo, float psnr, float tolerance,
void jpegli_set_quality(j_compress_ptr cinfo, int quality,
boolean force_baseline) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->master->force_baseline = force_baseline;
cinfo->master->force_baseline = FROM_JXL_BOOL(force_baseline);
float distance = jpegli_quality_to_distance(quality);
float distances[NUM_QUANT_TBLS] = {distance, distance, distance};
jpegli::SetQuantMatrices(cinfo, distances, /*add_two_chroma_tables=*/false);
@ -843,7 +845,7 @@ void jpegli_set_quality(j_compress_ptr cinfo, int quality,
void jpegli_set_linear_quality(j_compress_ptr cinfo, int scale_factor,
boolean force_baseline) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->master->force_baseline = force_baseline;
cinfo->master->force_baseline = FROM_JXL_BOOL(force_baseline);
float distance = jpegli::LinearQualityToDistance(scale_factor);
float distances[NUM_QUANT_TBLS] = {distance, distance, distance};
jpegli::SetQuantMatrices(cinfo, distances, /*add_two_chroma_tables=*/false);
@ -894,7 +896,7 @@ void jpegli_add_quant_table(j_compress_ptr cinfo, int which_tbl,
void jpegli_enable_adaptive_quantization(j_compress_ptr cinfo, boolean value) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->master->use_adaptive_quantization = value;
cinfo->master->use_adaptive_quantization = FROM_JXL_BOOL(value);
}
void jpegli_simple_progression(j_compress_ptr cinfo) {
@ -955,7 +957,7 @@ void jpegli_copy_critical_parameters(j_decompress_ptr srcinfo,
jpegli_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
if (dstinfo->num_components != srcinfo->num_components) {
const auto& cinfo = dstinfo;
return JPEGLI_ERROR("Mismatch between src colorspace and components");
JPEGLI_ERROR("Mismatch between src colorspace and components");
}
dstinfo->data_precision = srcinfo->data_precision;
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
@ -1005,7 +1007,7 @@ void jpegli_write_coefficients(j_compress_ptr cinfo,
jvirt_barray_ptr* coef_arrays) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->global_state = jpegli::kEncWriteCoeffs;
jpegli::InitCompress(cinfo, /*write_all_tables=*/true);
jpegli::InitCompress(cinfo, /*write_all_tables=*/TRUE);
cinfo->master->coeff_buffers = coef_arrays;
cinfo->next_scanline = cinfo->image_height;
cinfo->master->next_input_row = cinfo->image_height;
@ -1047,7 +1049,7 @@ void jpegli_write_m_header(j_compress_ptr cinfo, int marker,
marker_data[1] = marker;
marker_data[2] = (datalen + 2) >> 8;
marker_data[3] = (datalen + 2) & 0xff;
jpegli::WriteOutput(cinfo, &marker_data[0], 4);
jpegli::WriteOutput(cinfo, marker_data.data(), 4);
}
void jpegli_write_m_byte(j_compress_ptr cinfo, int val) {
@ -1213,7 +1215,8 @@ void jpegli_finish_compress(j_compress_ptr cinfo) {
}
const bool tokens_done = jpegli::IsStreamingSupported(cinfo);
const bool bitstream_done = tokens_done && !cinfo->optimize_coding;
const bool bitstream_done =
tokens_done && !FROM_JXL_BOOL(cinfo->optimize_coding);
if (!tokens_done) {
jpegli::TokenizeJpeg(cinfo);

Просмотреть файл

@ -133,12 +133,11 @@ TEST(EncodeAPITest, ReuseCinfoSameMemOutput) {
jpegli_destroy_compress(&cinfo);
}
size_t pos = 0;
for (size_t i = 0; i < all_configs.size(); ++i) {
for (auto& config : all_configs) {
TestImage output;
pos +=
DecodeWithLibjpeg(all_configs[i].jparams, DecompressParams(), nullptr,
0, buffer + pos, buffer_size - pos, &output);
VerifyOutputImage(all_configs[i].input, output, all_configs[i].max_dist);
pos += DecodeWithLibjpeg(config.jparams, DecompressParams(), nullptr, 0,
buffer + pos, buffer_size - pos, &output);
VerifyOutputImage(config.input, output, config.max_dist);
}
if (buffer) free(buffer);
}
@ -164,20 +163,21 @@ TEST(EncodeAPITest, ReuseCinfoSameStdOutput) {
size_t total_size = ftell(tmpf);
rewind(tmpf);
std::vector<uint8_t> compressed(total_size);
JXL_CHECK(total_size == fread(&compressed[0], 1, total_size, tmpf));
JXL_CHECK(total_size == fread(compressed.data(), 1, total_size, tmpf));
fclose(tmpf);
size_t pos = 0;
for (size_t i = 0; i < all_configs.size(); ++i) {
for (auto& config : all_configs) {
TestImage output;
pos += DecodeWithLibjpeg(all_configs[i].jparams, DecompressParams(),
nullptr, 0, &compressed[pos],
compressed.size() - pos, &output);
VerifyOutputImage(all_configs[i].input, output, all_configs[i].max_dist);
pos +=
DecodeWithLibjpeg(config.jparams, DecompressParams(), nullptr, 0,
&compressed[pos], compressed.size() - pos, &output);
VerifyOutputImage(config.input, output, config.max_dist);
}
}
TEST(EncodeAPITest, ReuseCinfoChangeParams) {
TestImage input, output;
TestImage input;
TestImage output;
CompressParams jparams;
DecompressParams dparams;
uint8_t* buffer = nullptr;

Просмотреть файл

@ -213,6 +213,8 @@ float FindDistanceForPSNR(j_compress_ptr cinfo) {
d = best_distance;
if (sampling == 1 && PSNR_SEARCH_DBG) {
printf("Final PSNR %.2f at distance %.4f\n", best_psnr, d);
} else {
(void)best_psnr;
}
}
return d;

Просмотреть файл

@ -99,10 +99,16 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
TokenArray* ta = &m->token_arrays[m->cur_token_array];
sti->token_offset = m->total_num_tokens + ta->num_tokens;
sti->restarts = Allocate<size_t>(cinfo, num_restarts, JPOOL_IMAGE);
const auto emit_eob_run = [&]() {
int nbits = jxl::FloorLog2Nonzero<uint32_t>(eob_run);
int symbol = nbits << 4u;
*m->next_token++ = Token(context, symbol, eob_run & ((1 << nbits) - 1));
eob_run = 0;
};
for (JDIMENSION by = 0; by < comp->height_in_blocks; ++by) {
JBLOCKARRAY ba = (*cinfo->mem->access_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), m->coeff_buffers[comp_idx], by,
1, false);
1, FALSE);
// Each coefficient can appear in at most one token, but we have to reserve
// one extra EOBrun token that was rolled over from the previous block-row
// and has to be flushed at the end.
@ -121,13 +127,7 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
}
for (JDIMENSION bx = 0; bx < comp->width_in_blocks; ++bx) {
if (restart_interval > 0 && restarts_to_go == 0) {
if (eob_run > 0) {
int nbits = jxl::FloorLog2Nonzero<uint32_t>(eob_run);
int symbol = nbits << 4u;
*m->next_token++ =
Token(context, symbol, eob_run & ((1 << nbits) - 1));
eob_run = 0;
}
if (eob_run > 0) emit_eob_run();
ta->num_tokens = m->next_token - ta->tokens;
sti->restarts[restart_idx++] = m->total_num_tokens + ta->num_tokens;
restarts_to_go = restart_interval;
@ -139,7 +139,8 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
int num_nzeros = 0;
int num_future_nzeros = 0;
for (int k = Ss; k <= Se; ++k) {
if ((temp = block[k]) == 0) {
temp = block[k];
if (temp == 0) {
r++;
continue;
}
@ -156,13 +157,7 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
num_future_nzeros++;
continue;
}
if (eob_run > 0) {
int nbits = jxl::FloorLog2Nonzero<uint32_t>(eob_run);
int symbol = nbits << 4u;
*m->next_token++ =
Token(context, symbol, eob_run & ((1 << nbits) - 1));
eob_run = 0;
}
if (eob_run > 0) emit_eob_run();
while (r > 15) {
*m->next_token++ = Token(context, 0xf0, 0);
r -= 16;
@ -175,13 +170,7 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
}
if (r > 0) {
++eob_run;
if (eob_run == 0x7FFF) {
int nbits = jxl::FloorLog2Nonzero<uint32_t>(eob_run);
int symbol = nbits << 4u;
*m->next_token++ =
Token(context, symbol, eob_run & ((1 << nbits) - 1));
eob_run = 0;
}
if (eob_run == 0x7FFF) emit_eob_run();
}
sti->num_nonzeros += num_nzeros;
sti->num_future_nonzeros += num_future_nzeros;
@ -190,11 +179,8 @@ void TokenizeACProgressiveScan(j_compress_ptr cinfo, int scan_index,
ta->num_tokens = m->next_token - ta->tokens;
}
if (eob_run > 0) {
int nbits = jxl::FloorLog2Nonzero<uint32_t>(eob_run);
int symbol = nbits << 4u;
*m->next_token++ = Token(context, symbol, eob_run & ((1 << nbits) - 1));
emit_eob_run();
++ta->num_tokens;
eob_run = 0;
}
sti->num_tokens = m->total_num_tokens + ta->num_tokens - sti->token_offset;
sti->restarts[restart_idx++] = m->total_num_tokens + ta->num_tokens;
@ -229,7 +215,7 @@ void TokenizeACRefinementScan(j_compress_ptr cinfo, int scan_index,
for (JDIMENSION by = 0; by < comp->height_in_blocks; ++by) {
JBLOCKARRAY ba = (*cinfo->mem->access_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), m->coeff_buffers[comp_idx], by,
1, false);
1, FALSE);
for (JDIMENSION bx = 0; bx < comp->width_in_blocks; ++bx) {
if (restart_interval > 0 && restarts_to_go == 0) {
sti->restarts[restart_idx++] = next_token - sti->tokens;
@ -337,7 +323,7 @@ void TokenizeScan(j_compress_ptr cinfo, size_t scan_index, int ac_ctx_offset,
// "Non-interleaved" means color data comes in separate scans, in other words
// each scan can contain only one color component.
const bool is_interleaved = (scan_info->comps_in_scan > 1);
const bool is_progressive = cinfo->progressive_mode;
const bool is_progressive = FROM_JXL_BOOL(cinfo->progressive_mode);
const int Ah = scan_info->Ah;
const int Al = scan_info->Al;
HWY_ALIGN constexpr coeff_t kSinkBlock[DCTSIZE2] = {0};
@ -373,7 +359,7 @@ void TokenizeScan(j_compress_ptr cinfo, size_t scan_index, int ac_ctx_offset,
int max_block_rows = std::min(n_blocks_y, block_rows_left);
ba[i] = (*cinfo->mem->access_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), m->coeff_buffers[comp_idx],
by0, max_block_rows, false);
by0, max_block_rows, FALSE);
}
if (!cinfo->progressive_mode) {
int max_tokens_per_mcu_row = MaxNumTokensPerMCURow(cinfo);
@ -557,7 +543,7 @@ float HistogramCost(const Histogram& histo) {
}
counts[kJpegHuffmanAlphabetSize] = 1;
CreateHuffmanTree(counts.data(), counts.size(), kJpegHuffmanMaxBitLength,
&depths[0]);
depths.data());
size_t header_bits = (1 + kJpegHuffmanMaxBitLength) * 8;
size_t data_bits = 0;
for (size_t i = 0; i < kJpegHuffmanAlphabetSize; ++i) {
@ -576,8 +562,8 @@ void AddHistograms(const Histogram& a, const Histogram& b, Histogram* c) {
}
bool IsEmptyHistogram(const Histogram& histo) {
for (size_t i = 0; i < kJpegHuffmanAlphabetSize; ++i) {
if (histo.count[i]) return false;
for (int count : histo.count) {
if (count) return false;
}
return true;
}
@ -668,7 +654,7 @@ void BuildJpegHuffmanTable(const Histogram& histo, JHUFF_TBL* table) {
}
counts[kJpegHuffmanAlphabetSize] = 1;
CreateHuffmanTree(counts.data(), counts.size(), kJpegHuffmanMaxBitLength,
&depths[0]);
depths.data());
memset(table, 0, sizeof(JHUFF_TBL));
for (size_t i = 0; i < kJpegHuffmanAlphabetSize; ++i) {
if (depths[i] > 0) {
@ -726,7 +712,7 @@ void OptimizeHuffmanCodes(j_compress_ptr cinfo) {
jpeg_comp_master* m = cinfo->master;
// Build DC and AC histograms.
std::vector<Histogram> histograms(m->num_contexts);
BuildHistograms(cinfo, &histograms[0]);
BuildHistograms(cinfo, histograms.data());
// Cluster DC histograms.
JpegClusteredHistograms dc_clusters;
@ -760,7 +746,7 @@ void OptimizeHuffmanCodes(j_compress_ptr cinfo) {
m->context_map = Allocate<uint8_t>(cinfo, m->num_contexts, JPOOL_IMAGE);
memset(m->context_map, 0, m->num_contexts);
for (size_t i = 0; i < m->num_contexts; ++i) {
if (i < (size_t)cinfo->num_components) {
if (i < static_cast<size_t>(cinfo->num_components)) {
m->context_map[i] = dc_clusters.histogram_indexes[i];
} else if (i >= 4) {
m->context_map[i] = num_dc_huff + ac_clusters.histogram_indexes[i - 4];

5
third_party/jpeg-xl/lib/jpegli/error.h поставляемый
Просмотреть файл

@ -10,6 +10,7 @@
#include <stdint.h>
#include "lib/jpegli/common.h"
#include "lib/jxl/base/status.h"
namespace jpegli {
@ -17,10 +18,12 @@ bool FormatString(char* buffer, const char* format, ...);
} // namespace jpegli
// `error_exit` should be no-return; but let's add some guarantees on our side.
#define JPEGLI_ERROR(format, ...) \
jpegli::FormatString(cinfo->err->msg_parm.s, ("%s:%d: " format), __FILE__, \
__LINE__, ##__VA_ARGS__), \
(*cinfo->err->error_exit)(reinterpret_cast<j_common_ptr>(cinfo))
(*cinfo->err->error_exit)(reinterpret_cast<j_common_ptr>(cinfo)), \
(void)jxl::Abort()
#define JPEGLI_WARN(format, ...) \
jpegli::FormatString(cinfo->err->msg_parm.s, ("%s:%d: " format), __FILE__, \

Просмотреть файл

@ -241,9 +241,10 @@ TEST(EncoderErrorHandlingTest, InvalidQuantValue) {
cinfo.image_height = 1;
cinfo.input_components = 1;
jpegli_set_defaults(&cinfo);
cinfo.quant_tbl_ptrs[0] = jpegli_alloc_quant_table((j_common_ptr)&cinfo);
for (size_t k = 0; k < DCTSIZE2; ++k) {
cinfo.quant_tbl_ptrs[0]->quantval[k] = 0;
cinfo.quant_tbl_ptrs[0] =
jpegli_alloc_quant_table(reinterpret_cast<j_common_ptr>(&cinfo));
for (UINT16& q : cinfo.quant_tbl_ptrs[0]->quantval) {
q = 0;
}
jpegli_start_compress(&cinfo, TRUE);
JSAMPLE image[1] = {0};
@ -992,7 +993,7 @@ TEST(EncoderErrorHandlingTest, AddOnTableNoStringParam) {
jpegli_destroy_compress(&cinfo);
}
static const uint8_t kCompressed0[] = {
const uint8_t kCompressed0[] = {
// SOI
0xff, 0xd8, //
// DQT
@ -1036,12 +1037,12 @@ static const uint8_t kCompressed0[] = {
// EOI
0xff, 0xd9, //
};
static const size_t kLen0 = sizeof(kCompressed0);
const size_t kLen0 = sizeof(kCompressed0);
static const size_t kDQTOffset = 2;
static const size_t kSOFOffset = 71;
static const size_t kDHTOffset = 84;
static const size_t kSOSOffset = 296;
const size_t kDQTOffset = 2;
const size_t kSOFOffset = 71;
const size_t kDHTOffset = 84;
const size_t kSOSOffset = 296;
TEST(DecoderErrorHandlingTest, MinimalSuccess) {
JXL_CHECK(kCompressed0[kDQTOffset] == 0xff);
@ -1130,7 +1131,7 @@ TEST(DecoderErrorHandlingTest, NoReadScanlines) {
jpegli_destroy_decompress(&cinfo);
}
static const size_t kMaxImageWidth = 0xffff;
const size_t kMaxImageWidth = 0xffff;
JSAMPLE kOutputBuffer[MAX_COMPONENTS * kMaxImageWidth];
bool ParseCompressed(const std::vector<uint8_t>& compressed) {

5
third_party/jpeg-xl/lib/jpegli/huffman.cc поставляемый
Просмотреть файл

@ -183,7 +183,8 @@ void CreateHuffmanTree(const uint32_t* data, const size_t length,
size_t i = 0; // Points to the next leaf node.
size_t j = n + 1; // Points to the next non-leaf node.
for (size_t k = n - 1; k != 0; --k) {
size_t left, right;
size_t left;
size_t right;
if (tree[i].total_count <= tree[j].total_count) {
left = i;
++i;
@ -210,7 +211,7 @@ void CreateHuffmanTree(const uint32_t* data, const size_t length,
tree.push_back(sentinel);
}
JXL_DASSERT(tree.size() == 2 * n + 1);
SetDepth(tree[2 * n - 1], &tree[0], depth, 0);
SetDepth(tree[2 * n - 1], tree.data(), depth, 0);
// We need to pack the Huffman tree in tree_limit bits.
// If this was not successful, add fake entities to the lowest values

5
third_party/jpeg-xl/lib/jpegli/idct.cc поставляемый
Просмотреть файл

@ -197,7 +197,7 @@ void InverseTransformBlock8x8(const int16_t* JXL_RESTRICT qblock,
// Computes the N-point IDCT of in[], and stores the result in out[]. The in[]
// array is at most 8 values long, values in[8:N-1] are assumed to be 0.
void Compute1dIDCT(float* in, float* out, size_t N) {
void Compute1dIDCT(const float* in, float* out, size_t N) {
switch (N) {
case 3: {
static constexpr float kC3[3] = {
@ -608,6 +608,9 @@ void Compute1dIDCT(float* in, float* out, size_t N) {
out[8] = even7 - odd7;
break;
}
default:
JXL_ABORT("Compute1dIDCT does not support N=%d", static_cast<int>(N));
break;
}
}

18
third_party/jpeg-xl/lib/jpegli/input.cc поставляемый
Просмотреть файл

@ -89,7 +89,7 @@ void ReadUint8RowInterleaved2(const uint8_t* row_in, size_t len,
const size_t simd_len = len & (~(N - 1));
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
Vec<DU8> out0, out1;
Vec<DU8> out0, out1; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved2(du8, row_in + 2 * x, out0, out1);
Store(ConvertTo(d, PromoteTo(du, out0)), d, row0 + x);
@ -105,7 +105,7 @@ void ReadUint8RowInterleaved3(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
Vec<DU8> out0, out1, out2;
Vec<DU8> out0, out1, out2; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved3(du8, row_in + 3 * x, out0, out1, out2);
Store(ConvertTo(d, PromoteTo(du, out0)), d, row0 + x);
@ -123,7 +123,7 @@ void ReadUint8RowInterleaved4(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
float* JXL_RESTRICT const row3 = row_out[3];
Vec<DU8> out0, out1, out2, out3;
Vec<DU8> out0, out1, out2, out3; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved4(du8, row_in + 4 * x, out0, out1, out2, out3);
Store(ConvertTo(d, PromoteTo(du, out0)), d, row0 + x);
@ -158,7 +158,7 @@ void ReadUint16RowInterleaved2(const uint8_t* row_in, size_t len,
reinterpret_cast<const uint16_t*>(row_in);
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
Vec<DU16> out0, out1;
Vec<DU16> out0, out1; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved2(du16, row + 2 * x, out0, out1);
Store(Mul(mul, ConvertTo(d, PromoteTo(du, out0))), d, row0 + x);
@ -177,7 +177,7 @@ void ReadUint16RowInterleaved3(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
Vec<DU16> out0, out1, out2;
Vec<DU16> out0, out1, out2; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved3(du16, row + 3 * x, out0, out1, out2);
Store(Mul(mul, ConvertTo(d, PromoteTo(du, out0))), d, row0 + x);
@ -198,7 +198,7 @@ void ReadUint16RowInterleaved4(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
float* JXL_RESTRICT const row3 = row_out[3];
Vec<DU16> out0, out1, out2, out3;
Vec<DU16> out0, out1, out2, out3; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved4(du16, row + 4 * x, out0, out1, out2, out3);
Store(Mul(mul, ConvertTo(d, PromoteTo(du, out0))), d, row0 + x);
@ -250,7 +250,7 @@ void ReadFloatRowInterleaved2(const uint8_t* row_in, size_t len,
const float* JXL_RESTRICT const row = reinterpret_cast<const float*>(row_in);
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
Vec<D> out0, out1;
Vec<D> out0, out1; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved2(d, row + 2 * x, out0, out1);
Store(Mul(mul, out0), d, row0 + x);
@ -268,7 +268,7 @@ void ReadFloatRowInterleaved3(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row0 = row_out[0];
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
Vec<D> out0, out1, out2;
Vec<D> out0, out1, out2; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved3(d, row + 3 * x, out0, out1, out2);
Store(Mul(mul, out0), d, row0 + x);
@ -288,7 +288,7 @@ void ReadFloatRowInterleaved4(const uint8_t* row_in, size_t len,
float* JXL_RESTRICT const row1 = row_out[1];
float* JXL_RESTRICT const row2 = row_out[2];
float* JXL_RESTRICT const row3 = row_out[3];
Vec<D> out0, out1, out2, out3;
Vec<D> out0, out1, out2, out3; // NOLINT
for (size_t x = 0; x < simd_len; x += N) {
LoadInterleaved4(d, row + 4 * x, out0, out1, out2, out3);
Store(Mul(mul, out0), d, row0 + x);

Просмотреть файл

@ -17,7 +17,7 @@
namespace jpegli {
namespace {
static constexpr uint8_t kFakeEoiMarker[2] = {0xff, 0xd9};
constexpr uint8_t kFakeEoiMarker[2] = {0xff, 0xd9};
struct SourceManager {
SourceManager(const uint8_t* data, size_t len, size_t max_chunk_size,
@ -50,14 +50,14 @@ struct SourceManager {
}
if (pub_.bytes_in_buffer > 0) {
EXPECT_LE(pub_.bytes_in_buffer, buffer_.size());
memmove(&buffer_[0], pub_.next_input_byte, pub_.bytes_in_buffer);
memmove(buffer_.data(), pub_.next_input_byte, pub_.bytes_in_buffer);
}
size_t chunk_size =
pos_ < len_ ? std::min(len_ - pos_, max_chunk_size_) : 2;
buffer_.resize(pub_.bytes_in_buffer + chunk_size);
memcpy(&buffer_[pub_.bytes_in_buffer],
pos_ < len_ ? data_ + pos_ : kFakeEoiMarker, chunk_size);
pub_.next_input_byte = &buffer_[0];
pub_.next_input_byte = buffer_.data();
pub_.bytes_in_buffer += chunk_size;
pos_ += chunk_size;
return true;
@ -73,7 +73,7 @@ struct SourceManager {
bool is_partial_file_;
static void init_source(j_decompress_ptr cinfo) {
auto src = reinterpret_cast<SourceManager*>(cinfo->src);
auto* src = reinterpret_cast<SourceManager*>(cinfo->src);
src->pub_.next_input_byte = nullptr;
src->pub_.bytes_in_buffer = 0;
}
@ -81,7 +81,7 @@ struct SourceManager {
static boolean fill_input_buffer(j_decompress_ptr cinfo) { return FALSE; }
static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
auto src = reinterpret_cast<SourceManager*>(cinfo->src);
auto* src = reinterpret_cast<SourceManager*>(cinfo->src);
if (num_bytes <= 0) {
return;
}
@ -156,10 +156,10 @@ void ReadOutputImage(const DecompressParams& dparams, j_decompress_ptr cinfo,
rowdata[c][i] =
y0 + i < ysize ? &output->raw_data[c][(y0 + i) * xsize] : nullptr;
}
data[c] = &rowdata[c][0];
data[c] = rowdata[c].data();
}
while ((num_output_lines =
jpegli_read_raw_data(cinfo, &data[0], max_lines)) == 0) {
jpegli_read_raw_data(cinfo, data.data(), max_lines)) == 0) {
JXL_CHECK(src && src->LoadNextChunk());
}
} else {
@ -173,7 +173,7 @@ void ReadOutputImage(const DecompressParams& dparams, j_decompress_ptr cinfo,
size_t yidx = cinfo->output_scanline + i;
scanlines[i] = &output->pixels[yidx * stride];
}
while ((num_output_lines = jpegli_read_scanlines(cinfo, &scanlines[0],
while ((num_output_lines = jpegli_read_scanlines(cinfo, scanlines.data(),
max_lines)) == 0) {
JXL_CHECK(src && src->LoadNextChunk());
}
@ -197,7 +197,7 @@ struct TestConfig {
std::vector<uint8_t> GetTestJpegData(TestConfig& config) {
if (!config.fn.empty()) {
return ReadTestData(config.fn.c_str());
return ReadTestData(config.fn);
}
GeneratePixels(&config.input);
std::vector<uint8_t> compressed;
@ -249,7 +249,7 @@ TEST_P(InputSuspensionTestParam, InputOutputLockStepNonBuffered) {
EXPECT_EQ(0, memcmp(markers_seen, kMarkerSequence, num_markers_seen));
}
VerifyHeader(config.jparams, &cinfo);
cinfo.raw_data_out = dparams.output_mode == RAW_DATA;
cinfo.raw_data_out = TO_JXL_BOOL(dparams.output_mode == RAW_DATA);
if (dparams.output_mode == COEFFICIENTS) {
jvirt_barray_ptr* coef_arrays;
@ -303,7 +303,7 @@ TEST_P(InputSuspensionTestParam, InputOutputLockStepBuffered) {
jpegli_set_output_format(&cinfo, dparams.data_type, dparams.endianness);
cinfo.buffered_image = TRUE;
cinfo.raw_data_out = dparams.output_mode == RAW_DATA;
cinfo.raw_data_out = TO_JXL_BOOL(dparams.output_mode == RAW_DATA);
EXPECT_TRUE(jpegli_start_decompress(&cinfo));
EXPECT_FALSE(jpegli_input_complete(&cinfo));
@ -380,8 +380,8 @@ TEST_P(InputSuspensionTestParam, PreConsumeInputBuffered) {
}
EXPECT_EQ(JPEG_REACHED_SOS, jpegli_consume_input(&cinfo));
cinfo.buffered_image = TRUE;
cinfo.raw_data_out = dparams.output_mode == RAW_DATA;
cinfo.do_block_smoothing = dparams.do_block_smoothing;
cinfo.raw_data_out = TO_JXL_BOOL(dparams.output_mode == RAW_DATA);
cinfo.do_block_smoothing = TO_JXL_BOOL(dparams.do_block_smoothing);
EXPECT_TRUE(jpegli_start_decompress(&cinfo));
EXPECT_FALSE(jpegli_input_complete(&cinfo));
@ -446,8 +446,8 @@ TEST_P(InputSuspensionTestParam, PreConsumeInputNonBuffered) {
}
}
EXPECT_EQ(JPEG_REACHED_SOS, jpegli_consume_input(&cinfo));
cinfo.raw_data_out = dparams.output_mode == RAW_DATA;
cinfo.do_block_smoothing = dparams.do_block_smoothing;
cinfo.raw_data_out = TO_JXL_BOOL(dparams.output_mode == RAW_DATA);
cinfo.do_block_smoothing = TO_JXL_BOOL(dparams.do_block_smoothing);
if (dparams.output_mode == COEFFICIENTS) {
jpegli_read_coefficients(&cinfo);

Просмотреть файл

@ -37,12 +37,13 @@ void ReadOutputPass(j_decompress_ptr cinfo, const DecompressParams& dparams,
output->ysize = ysize_cropped;
output->components = cinfo->out_color_components;
if (cinfo->quantize_colors) {
jxl::msan::UnpoisonMemory(cinfo->colormap, cinfo->out_color_components *
sizeof(cinfo->colormap[0]));
JSAMPLE** colormap = cinfo->colormap;
jxl::msan::UnpoisonMemory(reinterpret_cast<void*>(colormap),
cinfo->out_color_components * sizeof(JSAMPLE*));
for (int c = 0; c < cinfo->out_color_components; ++c) {
jxl::msan::UnpoisonMemory(
cinfo->colormap[c],
cinfo->actual_number_of_colors * sizeof(cinfo->colormap[c][0]));
reinterpret_cast<void*>(colormap[c]),
cinfo->actual_number_of_colors * sizeof(JSAMPLE));
}
}
if (!cinfo->raw_data_out) {
@ -89,10 +90,10 @@ void ReadOutputPass(j_decompress_ptr cinfo, const DecompressParams& dparams,
rowdata[c][i] =
y0 + i < ysize ? &output->raw_data[c][(y0 + i) * xsize] : nullptr;
}
data[c] = &rowdata[c][0];
data[c] = rowdata[c].data();
}
JXL_CHECK(iMCU_height ==
jpeg_read_raw_data(cinfo, &data[0], iMCU_height));
jpeg_read_raw_data(cinfo, data.data(), iMCU_height));
}
}
JXL_CHECK(cinfo->total_iMCU_rows ==

Просмотреть файл

@ -122,11 +122,11 @@ boolean jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr,
}
void jpeg_abort_decompress(j_decompress_ptr cinfo) {
return jpegli_abort_decompress(cinfo);
jpegli_abort_decompress(cinfo);
}
void jpeg_destroy_decompress(j_decompress_ptr cinfo) {
return jpegli_destroy_decompress(cinfo);
jpegli_destroy_decompress(cinfo);
}
void jpeg_CreateCompress(j_compress_ptr cinfo, int version, size_t structsize) {

Просмотреть файл

@ -19,7 +19,8 @@ void InitMemoryManager(j_common_ptr cinfo);
template <typename T>
T* Allocate(j_common_ptr cinfo, size_t len, int pool_id = JPOOL_PERMANENT) {
void* p = (*cinfo->mem->alloc_small)(cinfo, pool_id, len * sizeof(T));
const size_t size = len * sizeof(T); // NOLINT
void* p = (*cinfo->mem->alloc_small)(cinfo, pool_id, size);
return reinterpret_cast<T*>(p);
}

Просмотреть файл

@ -10,8 +10,8 @@
namespace jpegli {
namespace {
static constexpr size_t kInitialBufferSize = 1024;
static constexpr size_t kFinalBufferSize = 18;
constexpr size_t kInitialBufferSize = 1024;
constexpr size_t kFinalBufferSize = 18;
struct DestinationManager {
jpeg_destination_mgr pub;
@ -37,7 +37,7 @@ struct DestinationManager {
}
static void init_destination(j_compress_ptr cinfo) {
auto us = reinterpret_cast<DestinationManager*>(cinfo->dest);
auto* us = reinterpret_cast<DestinationManager*>(cinfo->dest);
us->buffer.resize(kInitialBufferSize);
us->Rewind();
}
@ -84,7 +84,7 @@ TEST_P(OutputSuspensionTestParam, PixelData) {
while (cinfo.next_scanline < cinfo.image_height) {
size_t lines_left = cinfo.image_height - cinfo.next_scanline;
size_t num_lines = std::min(config.lines_batch_size, lines_left);
memcpy(&row_bytes[0], &input.pixels[cinfo.next_scanline * stride],
memcpy(row_bytes.data(), &input.pixels[cinfo.next_scanline * stride],
num_lines * stride);
std::vector<JSAMPROW> rows(num_lines);
for (size_t i = 0; i < num_lines; ++i) {
@ -142,7 +142,7 @@ TEST_P(OutputSuspensionTestParam, RawData) {
std::vector<JSAMPARRAY> data(cinfo.num_components);
for (int c = 0; c < cinfo.num_components; ++c) {
rowdata[c].resize(config.jparams.v_samp(c) * DCTSIZE);
data[c] = &rowdata[c][0];
data[c] = rowdata[c].data();
}
while (cinfo.next_scanline < cinfo.image_height) {
for (int c = 0; c < cinfo.num_components; ++c) {
@ -155,7 +155,7 @@ TEST_P(OutputSuspensionTestParam, RawData) {
(y0 + i < cheight ? &raw_data[c][(y0 + i) * cwidth] : nullptr);
}
}
while (jpegli_write_raw_data(&cinfo, &data[0], max_lines) == 0) {
while (jpegli_write_raw_data(&cinfo, data.data(), max_lines) == 0) {
dest.EmptyTo(&compressed, config.buffer_size);
}
}

18
third_party/jpeg-xl/lib/jpegli/quant.cc поставляемый
Просмотреть файл

@ -26,7 +26,7 @@ namespace {
constexpr float kGlobalScaleXYB = 1.43951668f;
constexpr float kGlobalScaleYCbCr = 1.73966010f;
static constexpr float kBaseQuantMatrixXYB[] = {
constexpr float kBaseQuantMatrixXYB[] = {
// c = 0
7.5629935265f,
19.8247814178f,
@ -224,7 +224,7 @@ static constexpr float kBaseQuantMatrixXYB[] = {
63.6065597534f,
};
static const float kBaseQuantMatrixYCbCr[] = {
const float kBaseQuantMatrixYCbCr[] = {
// c = 0
1.2397409345866273f, //
1.7227115097630963f, //
@ -422,8 +422,8 @@ static const float kBaseQuantMatrixYCbCr[] = {
114.89202448569779f, //
};
static const float k420GlobalScale = 1.22;
static const float k420Rescale[64] = {
const float k420GlobalScale = 1.22;
const float k420Rescale[64] = {
0.4093, 0.3209, 0.3477, 0.3333, 0.3144, 0.2823, 0.3214, 0.3354, //
0.3209, 0.3111, 0.3489, 0.2801, 0.3059, 0.3119, 0.4135, 0.3445, //
0.3477, 0.3489, 0.3586, 0.3257, 0.2727, 0.3754, 0.3369, 0.3484, //
@ -434,7 +434,7 @@ static const float k420Rescale[64] = {
0.3354, 0.3445, 0.3484, 0.3839, 0.3836, 0.0726, 0.0553, 0.3368, //
};
static const float kBaseQuantMatrixStd[] = {
const float kBaseQuantMatrixStd[] = {
// c = 0
16.0f, 11.0f, 10.0f, 16.0f, 24.0f, 40.0f, 51.0f, 61.0f, //
12.0f, 12.0f, 14.0f, 19.0f, 26.0f, 58.0f, 60.0f, 55.0f, //
@ -455,7 +455,7 @@ static const float kBaseQuantMatrixStd[] = {
99.0f, 99.0f, 99.0f, 99.0f, 99.0f, 99.0f, 99.0f, 99.0f, //
};
static const float kZeroBiasMulYCbCrLQ[] = {
const float kZeroBiasMulYCbCrLQ[] = {
// c = 0
0.0000f, 0.0568f, 0.3880f, 0.6190f, 0.6190f, 0.4490f, 0.4490f, 0.6187f, //
0.0568f, 0.5829f, 0.6189f, 0.6190f, 0.6190f, 0.7190f, 0.6190f, 0.6189f, //
@ -485,7 +485,7 @@ static const float kZeroBiasMulYCbCrLQ[] = {
0.2960f, 0.2113f, 0.2426f, 0.1590f, 0.5403f, 0.3060f, 0.3060f, 0.3060f, //
};
static const float kZeroBiasMulYCbCrHQ[] = {
const float kZeroBiasMulYCbCrHQ[] = {
// c = 0
0.0000f, 0.0044f, 0.2521f, 0.6547f, 0.8161f, 0.6130f, 0.8841f, 0.8155f, //
0.0044f, 0.6831f, 0.6553f, 0.6295f, 0.7848f, 0.7843f, 0.8474f, 0.7836f, //
@ -515,9 +515,9 @@ static const float kZeroBiasMulYCbCrHQ[] = {
0.4836f, 0.4897f, 0.2583f, 0.3565f, 0.5949f, 0.6629f, 0.6644f, 0.6644f, //
};
static const float kZeroBiasOffsetYCbCrDC[] = {0.0f, 0.0f, 0.0f};
const float kZeroBiasOffsetYCbCrDC[] = {0.0f, 0.0f, 0.0f};
static const float kZeroBiasOffsetYCbCrAC[] = {
const float kZeroBiasOffsetYCbCrAC[] = {
0.59082f,
0.58146f,
0.57988f,

31
third_party/jpeg-xl/lib/jpegli/render.cc поставляемый
Просмотреть файл

@ -8,7 +8,6 @@
#include <string.h>
#include <array>
#include <atomic>
#include <cmath>
#include <cstddef>
#include <cstdint>
@ -203,12 +202,13 @@ void WriteToOutput(j_decompress_ptr cinfo, float* JXL_RESTRICT rows[],
if (cinfo->quantize_colors && m->quant_pass_ == 1) {
float* error_row[kMaxComponents];
float* next_error_row[kMaxComponents];
if (cinfo->dither_mode == JDITHER_ORDERED) {
J_DITHER_MODE dither_mode = cinfo->dither_mode;
if (dither_mode == JDITHER_ORDERED) {
for (size_t c = 0; c < num_channels; ++c) {
DitherRow(cinfo, &rows[c][xoffset], c, cinfo->output_scanline,
cinfo->output_width);
}
} else if (cinfo->dither_mode == JDITHER_FS) {
} else if (dither_mode == JDITHER_FS) {
for (size_t c = 0; c < num_channels; ++c) {
if (cinfo->output_scanline % 2 == 0) {
error_row[c] = m->error_row_[c];
@ -221,12 +221,12 @@ void WriteToOutput(j_decompress_ptr cinfo, float* JXL_RESTRICT rows[],
}
}
const float mul = 255.0f;
if (cinfo->dither_mode != JDITHER_FS) {
if (dither_mode != JDITHER_FS) {
StoreUnsignedRow(rows, xoffset, len, num_channels, mul, scratch_space);
}
for (size_t i = 0; i < len; ++i) {
uint8_t* pixel = &scratch_space[num_channels * i];
if (cinfo->dither_mode == JDITHER_FS) {
if (dither_mode == JDITHER_FS) {
for (size_t c = 0; c < num_channels; ++c) {
float val = rows[c][i] * mul + LimitError(error_row[c][i]);
pixel[c] = std::round(std::min(255.0f, std::max(0.0f, val)));
@ -234,7 +234,7 @@ void WriteToOutput(j_decompress_ptr cinfo, float* JXL_RESTRICT rows[],
}
int index = LookupColorIndex(cinfo, pixel);
output[i] = index;
if (cinfo->dither_mode == JDITHER_FS) {
if (dither_mode == JDITHER_FS) {
size_t prev_i = i > 0 ? i - 1 : 0;
size_t next_i = i + 1 < len ? i + 1 : len - 1;
for (size_t c = 0; c < num_channels; ++c) {
@ -293,19 +293,18 @@ HWY_EXPORT(DecenterRow);
void GatherBlockStats(const int16_t* JXL_RESTRICT coeffs,
const size_t coeffs_size, int32_t* JXL_RESTRICT nonzeros,
int32_t* JXL_RESTRICT sumabs) {
return HWY_DYNAMIC_DISPATCH(GatherBlockStats)(coeffs, coeffs_size, nonzeros,
sumabs);
HWY_DYNAMIC_DISPATCH(GatherBlockStats)(coeffs, coeffs_size, nonzeros, sumabs);
}
void WriteToOutput(j_decompress_ptr cinfo, float* JXL_RESTRICT rows[],
size_t xoffset, size_t len, size_t num_channels,
uint8_t* JXL_RESTRICT output) {
return HWY_DYNAMIC_DISPATCH(WriteToOutput)(cinfo, rows, xoffset, len,
num_channels, output);
HWY_DYNAMIC_DISPATCH(WriteToOutput)
(cinfo, rows, xoffset, len, num_channels, output);
}
void DecenterRow(float* row, size_t xsize) {
return HWY_DYNAMIC_DISPATCH(DecenterRow)(row, xsize);
HWY_DYNAMIC_DISPATCH(DecenterRow)(row, xsize);
}
bool ShouldApplyDequantBiases(j_decompress_ptr cinfo, int ci) {
@ -360,8 +359,8 @@ bool do_smoothing(j_decompress_ptr cinfo) {
if (!cinfo->progressive_mode || cinfo->coef_bits == nullptr) {
return false;
}
auto coef_bits_latch = m->coef_bits_latch;
auto prev_coef_bits_latch = m->prev_coef_bits_latch;
auto* coef_bits_latch = m->coef_bits_latch;
auto* prev_coef_bits_latch = m->prev_coef_bits_latch;
for (int ci = 0; ci < cinfo->num_components; ci++) {
jpeg_component_info* compptr = &cinfo->comp_info[ci];
@ -468,6 +467,7 @@ void PredictSmooth(j_decompress_ptr cinfo, JBLOCKARRAY blocks, int component,
return swap_indices ? dc_values[j][i] : dc_values[i][j];
};
Al = coef_bits[coef_index];
JXL_ASSERT(coef_index >= 0 && coef_index < 10);
switch (coef_index) {
case 0:
// set the DC
@ -520,6 +520,7 @@ void PredictSmooth(j_decompress_ptr cinfo, JBLOCKARRAY blocks, int component,
break;
case 7:
case 8:
default:
// set Q12 and Q21
num = (dc(1, 1) - 3 * dc(1, 2) + dc(1, 3) - dc(3, 1) + 3 * dc(3, 2) -
dc(3, 3));
@ -551,7 +552,7 @@ void PredictSmooth(j_decompress_ptr cinfo, JBLOCKARRAY blocks, int component,
void PrepareForOutput(j_decompress_ptr cinfo) {
jpeg_decomp_master* m = cinfo->master;
bool smoothing = do_smoothing(cinfo);
m->apply_smoothing = smoothing && cinfo->do_block_smoothing;
m->apply_smoothing = smoothing && FROM_JXL_BOOL(cinfo->do_block_smoothing);
size_t coeffs_per_block = cinfo->num_components * DCTSIZE2;
memset(m->nonzeros_, 0, coeffs_per_block * sizeof(m->nonzeros_[0]));
memset(m->sumabs_, 0, coeffs_per_block * sizeof(m->sumabs_[0]));
@ -584,7 +585,7 @@ void DecodeCurrentiMCURow(j_decompress_ptr cinfo) {
int offset = m->streaming_mode_ ? 0 : by0;
ba[c] = (*cinfo->mem->access_virt_barray)(
reinterpret_cast<j_common_ptr>(cinfo), m->coef_arrays[c], offset,
max_block_rows, false);
max_block_rows, FALSE);
}
for (int c = 0; c < cinfo->num_components; ++c) {
size_t k0 = c * DCTSIZE2;

Просмотреть файл

@ -39,7 +39,7 @@ struct StdioSourceManager {
uint8_t* buffer;
static boolean fill_input_buffer(j_decompress_ptr cinfo) {
auto src = reinterpret_cast<StdioSourceManager*>(cinfo->src);
auto* src = reinterpret_cast<StdioSourceManager*>(cinfo->src);
size_t num_bytes_read = fread(src->buffer, 1, kStdioBufferSize, src->f);
if (num_bytes_read == 0) {
return EmitFakeEoiMarker(cinfo);
@ -77,7 +77,7 @@ void jpegli_stdio_src(j_decompress_ptr cinfo, FILE* infile) {
cinfo->src = reinterpret_cast<jpeg_source_mgr*>(
jpegli::Allocate<jpegli::StdioSourceManager>(cinfo, 1));
}
auto src = reinterpret_cast<jpegli::StdioSourceManager*>(cinfo->src);
auto* src = reinterpret_cast<jpegli::StdioSourceManager*>(cinfo->src);
src->f = infile;
src->buffer = jpegli::Allocate<uint8_t>(cinfo, jpegli::kStdioBufferSize);
src->pub.next_input_byte = src->buffer;

Просмотреть файл

@ -50,7 +50,7 @@ FILE* MemOpen(const std::vector<uint8_t>& data) {
TEST_P(SourceManagerTestParam, TestStdioSourceManager) {
TestConfig config = GetParam();
std::vector<uint8_t> compressed = ReadTestData(config.fn.c_str());
std::vector<uint8_t> compressed = ReadTestData(config.fn);
if (config.dparams.size_factor < 1.0) {
compressed.resize(compressed.size() * config.dparams.size_factor);
}
@ -77,7 +77,7 @@ TEST_P(SourceManagerTestParam, TestStdioSourceManager) {
TEST_P(SourceManagerTestParam, TestMemSourceManager) {
TestConfig config = GetParam();
std::vector<uint8_t> compressed = ReadTestData(config.fn.c_str());
std::vector<uint8_t> compressed = ReadTestData(config.fn);
if (config.dparams.size_factor < 1.0f) {
compressed.resize(compressed.size() * config.dparams.size_factor);
}

Просмотреть файл

@ -36,13 +36,13 @@ struct SourceManager {
// input buffer. The buffer size is kept short because empty_output_buffer() is
// called only when the output buffer is full, and we want to update the decoder
// input frequently to demonstrate that streaming works.
static constexpr size_t kOutputBufferSize = 1024;
constexpr size_t kOutputBufferSize = 1024;
struct DestinationManager {
jpeg_destination_mgr pub;
std::vector<uint8_t> buffer;
SourceManager* dest;
DestinationManager(SourceManager* src)
explicit DestinationManager(SourceManager* src)
: buffer(kOutputBufferSize), dest(src) {
pub.next_output_byte = buffer.data();
pub.free_in_buffer = buffer.size();
@ -54,7 +54,7 @@ struct DestinationManager {
static void init_destination(j_compress_ptr cinfo) {}
static boolean empty_output_buffer(j_compress_ptr cinfo) {
auto us = reinterpret_cast<DestinationManager*>(cinfo->dest);
auto* us = reinterpret_cast<DestinationManager*>(cinfo->dest);
jpeg_destination_mgr* src = &us->pub;
jpeg_source_mgr* dst = &us->dest->pub;
std::vector<uint8_t>& src_buf = us->buffer;
@ -69,7 +69,7 @@ struct DestinationManager {
dst->bytes_in_buffer = dst_buf.size();
src->next_output_byte = src_buf.data();
src->free_in_buffer = src_buf.size();
return true;
return TRUE;
}
static void term_destination(j_compress_ptr cinfo) {
@ -87,6 +87,7 @@ class StreamingTestParam : public ::testing::TestWithParam<TestConfig> {};
TEST_P(StreamingTestParam, TestStreaming) {
jpeg_decompress_struct dinfo = {};
jpeg_compress_struct cinfo = {};
SourceManager src;
TestConfig config = GetParam();
TestImage& input = config.input;
TestImage output;
@ -99,7 +100,6 @@ TEST_P(StreamingTestParam, TestStreaming) {
// compressor's output is connected to the decompressor's input.
jpegli_create_decompress(&dinfo);
jpegli_create_compress(&cinfo);
SourceManager src;
dinfo.src = reinterpret_cast<jpeg_source_mgr*>(&src);
DestinationManager dest(&src);
cinfo.dest = reinterpret_cast<jpeg_destination_mgr*>(&dest);
@ -107,7 +107,7 @@ TEST_P(StreamingTestParam, TestStreaming) {
cinfo.image_width = input.xsize;
cinfo.image_height = input.ysize;
cinfo.input_components = input.components;
cinfo.in_color_space = (J_COLOR_SPACE)input.color_space;
cinfo.in_color_space = static_cast<J_COLOR_SPACE>(input.color_space);
jpegli_set_defaults(&cinfo);
cinfo.comp_info[0].v_samp_factor = config.jparams.v_sampling[0];
jpegli_set_progressive_level(&cinfo, 0);
@ -122,13 +122,13 @@ TEST_P(StreamingTestParam, TestStreaming) {
while (yin < cinfo.image_height) {
// Feed one iMCU row at a time to the compressor.
size_t lines_in = std::min(iMCU_height, cinfo.image_height - yin);
memcpy(&row_bytes[0], &input.pixels[yin * stride], lines_in * stride);
memcpy(row_bytes.data(), &input.pixels[yin * stride], lines_in * stride);
std::vector<JSAMPROW> rows_in(lines_in);
for (size_t i = 0; i < lines_in; ++i) {
rows_in[i] = &row_bytes[i * stride];
}
EXPECT_EQ(lines_in,
jpegli_write_scanlines(&cinfo, &rows_in[0], lines_in));
jpegli_write_scanlines(&cinfo, rows_in.data(), lines_in));
yin += lines_in;
if (yin == cinfo.image_height) {
jpegli_finish_compress(&cinfo);
@ -180,7 +180,7 @@ TEST_P(StreamingTestParam, TestStreaming) {
reinterpret_cast<JSAMPLE*>(&output.pixels[(yout + i) * stride]);
}
EXPECT_EQ(lines_out,
jpegli_read_scanlines(&dinfo, &rows_out[0], lines_out));
jpegli_read_scanlines(&dinfo, rows_out.data(), lines_out));
VerifyOutputImage(input, output, yout, lines_out, 3.8f);
yout += lines_out;

Просмотреть файл

@ -8,20 +8,20 @@
// include paths for the jpeg headers.
// Sequential non-interleaved.
static constexpr jpeg_scan_info kScript1[] = {
constexpr jpeg_scan_info kScript1[] = {
{1, {0}, 0, 63, 0, 0},
{1, {1}, 0, 63, 0, 0},
{1, {2}, 0, 63, 0, 0},
};
// Sequential partially interleaved, chroma first.
static constexpr jpeg_scan_info kScript2[] = {
constexpr jpeg_scan_info kScript2[] = {
{2, {1, 2}, 0, 63, 0, 0},
{1, {0}, 0, 63, 0, 0},
};
// Rest of the scan scripts are progressive.
static constexpr jpeg_scan_info kScript3[] = {
constexpr jpeg_scan_info kScript3[] = {
// Interleaved full DC.
{3, {0, 1, 2}, 0, 0, 0, 0},
// Full AC scans.
@ -29,7 +29,7 @@ static constexpr jpeg_scan_info kScript3[] = {
{1, {1}, 1, 63, 0, 0},
{1, {2}, 1, 63, 0, 0},
};
static constexpr jpeg_scan_info kScript4[] = {
constexpr jpeg_scan_info kScript4[] = {
// Non-interleaved full DC.
{1, {0}, 0, 0, 0, 0},
{1, {1}, 0, 0, 0, 0},
@ -39,7 +39,7 @@ static constexpr jpeg_scan_info kScript4[] = {
{1, {1}, 1, 63, 0, 0},
{1, {2}, 1, 63, 0, 0},
};
static constexpr jpeg_scan_info kScript5[] = {
constexpr jpeg_scan_info kScript5[] = {
// Partially interleaved full DC, chroma first.
{2, {1, 2}, 0, 0, 0, 0},
{1, {0}, 0, 0, 0, 0},
@ -52,7 +52,7 @@ static constexpr jpeg_scan_info kScript5[] = {
{1, {1}, 1, 63, 1, 0},
{1, {2}, 1, 63, 1, 0},
};
static constexpr jpeg_scan_info kScript6[] = {
constexpr jpeg_scan_info kScript6[] = {
// Interleaved DC shifted by 2 bits.
{3, {0, 1, 2}, 0, 0, 0, 2},
// Interleaved DC refinement scans.
@ -64,7 +64,7 @@ static constexpr jpeg_scan_info kScript6[] = {
{1, {2}, 1, 63, 0, 0},
};
static constexpr jpeg_scan_info kScript7[] = {
constexpr jpeg_scan_info kScript7[] = {
// Non-interleaved DC shifted by 2 bits.
{1, {0}, 0, 0, 0, 2},
{1, {1}, 0, 0, 0, 2},
@ -83,7 +83,7 @@ static constexpr jpeg_scan_info kScript7[] = {
{1, {2}, 1, 63, 0, 0},
};
static constexpr jpeg_scan_info kScript8[] = {
constexpr jpeg_scan_info kScript8[] = {
// Partially interleaved DC shifted by 2 bits, chroma first
{2, {1, 2}, 0, 0, 0, 2},
{1, {0}, 0, 0, 0, 2},
@ -99,7 +99,7 @@ static constexpr jpeg_scan_info kScript8[] = {
{1, {2}, 1, 63, 0, 0},
};
static constexpr jpeg_scan_info kScript9[] = {
constexpr jpeg_scan_info kScript9[] = {
// Interleaved full DC.
{3, {0, 1, 2}, 0, 0, 0, 0},
// AC scans for component 0
@ -123,7 +123,7 @@ static constexpr jpeg_scan_info kScript9[] = {
{1, {2}, 17, 63, 1, 0},
};
static constexpr jpeg_scan_info kScript10[] = {
constexpr jpeg_scan_info kScript10[] = {
// Interleaved full DC.
{3, {0, 1, 2}, 0, 0, 0, 0},
// AC scans for spectral range 1..16
@ -156,14 +156,14 @@ struct ScanScript {
const jpeg_scan_info* scans;
};
static constexpr ScanScript kTestScript[] = {
constexpr ScanScript kTestScript[] = {
{ARRAY_SIZE(kScript1), kScript1}, {ARRAY_SIZE(kScript2), kScript2},
{ARRAY_SIZE(kScript3), kScript3}, {ARRAY_SIZE(kScript4), kScript4},
{ARRAY_SIZE(kScript5), kScript5}, {ARRAY_SIZE(kScript6), kScript6},
{ARRAY_SIZE(kScript7), kScript7}, {ARRAY_SIZE(kScript8), kScript8},
{ARRAY_SIZE(kScript9), kScript9}, {ARRAY_SIZE(kScript10), kScript10},
};
static constexpr int kNumTestScripts = ARRAY_SIZE(kTestScript);
constexpr int kNumTestScripts = ARRAY_SIZE(kTestScript);
void SetScanDecompressParams(const DecompressParams& dparams,
j_decompress_ptr cinfo, int scan_number) {
@ -178,7 +178,7 @@ void SetScanDecompressParams(const DecompressParams& dparams,
return;
}
if (dparams.quantize_colors) {
cinfo->dither_mode = (J_DITHER_MODE)sparams->dither_mode;
cinfo->dither_mode = static_cast<J_DITHER_MODE>(sparams->dither_mode);
if (sparams->color_quant_mode == CQUANT_1PASS) {
cinfo->two_pass_quantize = FALSE;
cinfo->colormap = nullptr;
@ -194,7 +194,8 @@ void SetScanDecompressParams(const DecompressParams& dparams,
cinfo->colormap = (*cinfo->mem->alloc_sarray)(
reinterpret_cast<j_common_ptr>(cinfo), JPOOL_IMAGE,
cinfo->actual_number_of_colors, 3);
jxl::msan::UnpoisonMemory(cinfo->colormap, 3 * sizeof(JSAMPROW));
jxl::msan::UnpoisonMemory(reinterpret_cast<void*>(cinfo->colormap),
3 * sizeof(JSAMPLE*));
for (int i = 0; i < kTestColorMapNumColors; ++i) {
cinfo->colormap[0][i] = (kTestColorMap[i] >> 16) & 0xff;
cinfo->colormap[1][i] = (kTestColorMap[i] >> 8) & 0xff;
@ -212,20 +213,21 @@ void SetScanDecompressParams(const DecompressParams& dparams,
void SetDecompressParams(const DecompressParams& dparams,
j_decompress_ptr cinfo) {
cinfo->do_block_smoothing = dparams.do_block_smoothing;
cinfo->do_fancy_upsampling = dparams.do_fancy_upsampling;
cinfo->do_block_smoothing = dparams.do_block_smoothing ? 1 : 0;
cinfo->do_fancy_upsampling = dparams.do_fancy_upsampling ? 1 : 0;
if (dparams.output_mode == RAW_DATA) {
cinfo->raw_data_out = TRUE;
}
if (dparams.set_out_color_space) {
cinfo->out_color_space = (J_COLOR_SPACE)dparams.out_color_space;
cinfo->out_color_space =
static_cast<J_COLOR_SPACE>(dparams.out_color_space);
if (dparams.out_color_space == JCS_UNKNOWN) {
cinfo->jpeg_color_space = JCS_UNKNOWN;
}
}
cinfo->scale_num = dparams.scale_num;
cinfo->scale_denom = dparams.scale_denom;
cinfo->quantize_colors = dparams.quantize_colors;
cinfo->quantize_colors = dparams.quantize_colors ? 1 : 0;
cinfo->desired_number_of_colors = dparams.desired_number_of_colors;
if (!dparams.scan_params.empty()) {
if (cinfo->buffered_image) {
@ -420,7 +422,7 @@ void CopyCoefficients(j_decompress_ptr cinfo, jvirt_barray_ptr* coef_arrays,
DCTSIZE2);
for (size_t by = 0; by < comp->height_in_blocks; ++by) {
JBLOCKARRAY ba = (*cinfo->mem->access_virt_barray)(comptr, coef_arrays[c],
by, 1, true);
by, 1, TRUE);
size_t stride = comp->width_in_blocks * sizeof(JBLOCK);
size_t offset = by * comp->width_in_blocks * DCTSIZE2;
memcpy(&coeffs[offset], ba[0], stride);

81
third_party/jpeg-xl/lib/jpegli/test_utils.cc поставляемый
Просмотреть файл

@ -153,7 +153,7 @@ bool ReadPNM(const std::vector<uint8_t>& data, size_t* xsize, size_t* ysize,
return false;
}
pixels->resize(data.data() + data.size() - pos);
memcpy(&(*pixels)[0], pos, pixels->size());
memcpy(pixels->data(), pos, pixels->size());
return true;
}
@ -216,7 +216,8 @@ std::ostream& operator<<(std::ostream& os, const TestImage& input) {
os << input.xsize << "x" << input.ysize;
os << IOMethodName(input.data_type, input.endianness);
if (input.color_space != JCS_RGB) {
os << "InputColor" << ColorSpaceName((J_COLOR_SPACE)input.color_space);
os << "InputColor"
<< ColorSpaceName(static_cast<J_COLOR_SPACE>(input.color_space));
}
if (input.color_space == JCS_UNKNOWN) {
os << input.components;
@ -229,18 +230,18 @@ std::ostream& operator<<(std::ostream& os, const CompressParams& jparams) {
os << SamplingId(jparams);
if (jparams.set_jpeg_colorspace) {
os << "JpegColor"
<< ColorSpaceName((J_COLOR_SPACE)jparams.jpeg_color_space);
<< ColorSpaceName(static_cast<J_COLOR_SPACE>(jparams.jpeg_color_space));
}
if (!jparams.comp_ids.empty()) {
os << "CID";
for (size_t i = 0; i < jparams.comp_ids.size(); ++i) {
os << jparams.comp_ids[i];
for (int cid : jparams.comp_ids) {
os << cid;
}
}
if (!jparams.quant_indexes.empty()) {
os << "QIDX";
for (size_t i = 0; i < jparams.quant_indexes.size(); ++i) {
os << jparams.quant_indexes[i];
for (int qi : jparams.quant_indexes) {
os << qi;
}
for (const auto& table : jparams.quant_tables) {
os << "TABLE" << table.slot_idx << "T" << table.table_type << "F"
@ -320,7 +321,7 @@ void RGBToYCbCr(float r, float g, float b, float* y, float* cb, float* cr) {
void ConvertPixel(const uint8_t* input_rgb, uint8_t* out,
J_COLOR_SPACE colorspace, size_t num_channels,
JpegliDataType data_type = JPEGLI_TYPE_UINT8,
bool swap_endianness = JPEGLI_NATIVE_ENDIAN) {
JXL_BOOL swap_endianness = JPEGLI_NATIVE_ENDIAN) {
const float kMul = 255.0f;
float r = input_rgb[0] / kMul;
float g = input_rgb[1] / kMul;
@ -334,7 +335,9 @@ void ConvertPixel(const uint8_t* input_rgb, uint8_t* out,
out8[c] = input_rgb[std::min<size_t>(2, c)];
}
} else if (colorspace == JCS_YCbCr) {
float Y, Cb, Cr;
float Y;
float Cb;
float Cr;
RGBToYCbCr(r, g, b, &Y, &Cb, &Cr);
out8[0] = static_cast<uint8_t>(std::round(Y * kMul));
out8[1] = static_cast<uint8_t>(std::round(Cb * kMul));
@ -350,7 +353,9 @@ void ConvertPixel(const uint8_t* input_rgb, uint8_t* out,
out8[1] = static_cast<uint8_t>(std::round((1.0f - g) * kMul));
out8[2] = static_cast<uint8_t>(std::round((1.0f - b) * kMul));
} else if (colorspace == JCS_YCCK) {
float Y, Cb, Cr;
float Y;
float Cb;
float Cr;
RGBToYCbCr(r, g, b, &Y, &Cb, &Cr);
out8[0] = static_cast<uint8_t>(std::round(Y * kMul));
out8[1] = static_cast<uint8_t>(std::round(Cb * kMul));
@ -399,7 +404,10 @@ void ConvertToGrayscale(TestImage* img) {
void GeneratePixels(TestImage* img) {
const std::vector<uint8_t> imgdata = ReadTestData("jxl/flower/flower.pnm");
size_t xsize, ysize, channels, bitdepth;
size_t xsize;
size_t ysize;
size_t channels;
size_t bitdepth;
std::vector<uint8_t> pixels;
JXL_CHECK(ReadPNM(imgdata, &xsize, &ysize, &channels, &bitdepth, &pixels));
if (img->xsize == 0) img->xsize = xsize;
@ -412,7 +420,8 @@ void GeneratePixels(TestImage* img) {
size_t in_stride = xsize * in_bytes_per_pixel;
size_t x0 = (xsize - img->xsize) / 2;
size_t y0 = (ysize - img->ysize) / 2;
SetNumChannels((J_COLOR_SPACE)img->color_space, &img->components);
SetNumChannels(static_cast<J_COLOR_SPACE>(img->color_space),
&img->components);
size_t out_bytes_per_pixel =
jpegli_bytes_per_sample(img->data_type) * img->components;
size_t out_stride = img->xsize * out_bytes_per_pixel;
@ -427,8 +436,9 @@ void GeneratePixels(TestImage* img) {
size_t idx_in = y * in_stride + x * in_bytes_per_pixel;
size_t idx_out = iy * out_stride + ix * out_bytes_per_pixel;
ConvertPixel(&pixels[idx_in], &img->pixels[idx_out],
(J_COLOR_SPACE)img->color_space, img->components,
img->data_type, swap_endianness);
static_cast<J_COLOR_SPACE>(img->color_space),
img->components, img->data_type,
TO_JXL_BOOL(swap_endianness));
}
}
}
@ -492,7 +502,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
jpegli_set_progressive_level(cinfo, 0);
}
jpegli_set_defaults(cinfo);
cinfo->in_color_space = (J_COLOR_SPACE)input.color_space;
cinfo->in_color_space = static_cast<J_COLOR_SPACE>(input.color_space);
jpegli_default_colorspace(cinfo);
if (jparams.override_JFIF >= 0) {
cinfo->write_JFIF_header = jparams.override_JFIF;
@ -501,7 +511,8 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
cinfo->write_Adobe_marker = jparams.override_Adobe;
}
if (jparams.set_jpeg_colorspace) {
jpegli_set_colorspace(cinfo, (J_COLOR_SPACE)jparams.jpeg_color_space);
jpegli_set_colorspace(cinfo,
static_cast<J_COLOR_SPACE>(jparams.jpeg_color_space));
}
if (!jparams.comp_ids.empty()) {
for (int c = 0; c < cinfo->num_components; ++c) {
@ -522,15 +533,16 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
for (const auto& table : jparams.quant_tables) {
if (table.add_raw) {
cinfo->quant_tbl_ptrs[table.slot_idx] =
jpegli_alloc_quant_table((j_common_ptr)cinfo);
jpegli_alloc_quant_table(reinterpret_cast<j_common_ptr>(cinfo));
for (int k = 0; k < DCTSIZE2; ++k) {
cinfo->quant_tbl_ptrs[table.slot_idx]->quantval[k] =
table.quantval[k];
}
cinfo->quant_tbl_ptrs[table.slot_idx]->sent_table = FALSE;
} else {
jpegli_add_quant_table(cinfo, table.slot_idx, &table.basic_table[0],
table.scale_factor, table.force_baseline);
jpegli_add_quant_table(cinfo, table.slot_idx, table.basic_table.data(),
table.scale_factor,
TO_JXL_BOOL(table.force_baseline));
}
}
}
@ -546,7 +558,8 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
jpegli_set_progressive_level(cinfo, jparams.progressive_mode);
}
jpegli_set_input_format(cinfo, input.data_type, input.endianness);
jpegli_enable_adaptive_quantization(cinfo, jparams.use_adaptive_quantization);
jpegli_enable_adaptive_quantization(
cinfo, TO_JXL_BOOL(jparams.use_adaptive_quantization));
cinfo->restart_interval = jparams.restart_interval;
cinfo->restart_in_rows = jparams.restart_in_rows;
cinfo->smoothing_factor = jparams.smoothing_factor;
@ -555,7 +568,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
} else if (jparams.optimize_coding == 0) {
cinfo->optimize_coding = FALSE;
}
cinfo->raw_data_in = !input.raw_data.empty();
cinfo->raw_data_in = TO_JXL_BOOL(!input.raw_data.empty());
if (jparams.optimize_coding == 0 && jparams.use_flat_dc_luma_code) {
JHUFF_TBL* tbl = cinfo->dc_huff_tbl_ptrs[0];
memset(tbl, 0, sizeof(*tbl));
@ -572,13 +585,13 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
cinfo->ac_huff_tbl_ptrs[0]->sent_table = TRUE;
cinfo->ac_huff_tbl_ptrs[1]->sent_table = TRUE;
}
jpegli_start_compress(cinfo, write_all_tables);
jpegli_start_compress(cinfo, TO_JXL_BOOL(write_all_tables));
if (jparams.add_marker) {
jpegli_write_marker(cinfo, kSpecialMarker0, kMarkerData,
sizeof(kMarkerData));
jpegli_write_m_header(cinfo, kSpecialMarker1, sizeof(kMarkerData));
for (size_t p = 0; p < sizeof(kMarkerData); ++p) {
jpegli_write_m_byte(cinfo, kMarkerData[p]);
for (uint8_t c : kMarkerData) {
jpegli_write_m_byte(cinfo, c);
}
for (size_t i = 0; i < kMarkerSequenceLen; ++i) {
jpegli_write_marker(cinfo, kMarkerSequence[i], kMarkerData,
@ -597,7 +610,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
std::vector<JSAMPARRAY> data(cinfo->num_components);
for (int c = 0; c < cinfo->num_components; ++c) {
rowdata[c].resize(jparams.v_samp(c) * DCTSIZE);
data[c] = &rowdata[c][0];
data[c] = rowdata[c].data();
}
while (cinfo->next_scanline < cinfo->image_height) {
for (int c = 0; c < cinfo->num_components; ++c) {
@ -610,7 +623,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
(y0 + i < cheight ? &raw_data[c][(y0 + i) * cwidth] : nullptr);
}
}
size_t num_lines = jpegli_write_raw_data(cinfo, &data[0], max_lines);
size_t num_lines = jpegli_write_raw_data(cinfo, data.data(), max_lines);
JXL_CHECK(num_lines == max_lines);
}
} else if (!input.coeffs.empty()) {
@ -630,15 +643,15 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
jpegli_write_marker(cinfo, kSpecialMarker0, kMarkerData,
sizeof(kMarkerData));
jpegli_write_m_header(cinfo, kSpecialMarker1, sizeof(kMarkerData));
for (size_t p = 0; p < sizeof(kMarkerData); ++p) {
jpegli_write_m_byte(cinfo, kMarkerData[p]);
for (uint8_t c : kMarkerData) {
jpegli_write_m_byte(cinfo, c);
}
}
for (int c = 0; c < cinfo->num_components; ++c) {
jpeg_component_info* comp = &cinfo->comp_info[c];
for (size_t by = 0; by < comp->height_in_blocks; ++by) {
JBLOCKARRAY ba = (*cinfo->mem->access_virt_barray)(
comptr, coef_arrays[c], by, 1, true);
comptr, coef_arrays[c], by, 1, TRUE);
size_t stride = comp->width_in_blocks * sizeof(JBLOCK);
size_t offset = by * comp->width_in_blocks * DCTSIZE2;
memcpy(ba[0], &input.coeffs[c][offset], stride);
@ -649,7 +662,7 @@ void EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
jpegli_bytes_per_sample(input.data_type);
std::vector<uint8_t> row_bytes(stride);
for (size_t y = 0; y < cinfo->image_height; ++y) {
memcpy(&row_bytes[0], &input.pixels[y * stride], stride);
memcpy(row_bytes.data(), &input.pixels[y * stride], stride);
JSAMPROW row[] = {row_bytes.data()};
jpegli_write_scanlines(cinfo, row, 1);
}
@ -681,15 +694,15 @@ bool EncodeWithJpegli(const TestImage& input, const CompressParams& jparams,
int NumTestScanScripts() { return kNumTestScripts; }
void DumpImage(const TestImage& image, const std::string fn) {
void DumpImage(const TestImage& image, const std::string& fn) {
JXL_CHECK(image.components == 1 || image.components == 3);
size_t bytes_per_sample = jpegli_bytes_per_sample(image.data_type);
uint32_t maxval = (1u << (8 * bytes_per_sample)) - 1;
char type = image.components == 1 ? '5' : '6';
std::ofstream out(fn.c_str(), std::ofstream::binary);
out << "P" << type << std::endl
<< image.xsize << " " << image.ysize << std::endl
<< maxval << std::endl;
out << "P" << type << "\n"
<< image.xsize << " " << image.ysize << "\n"
<< maxval << "\n";
out.write(reinterpret_cast<const char*>(image.pixels.data()),
image.pixels.size());
out.close();

20
third_party/jpeg-xl/lib/jpegli/testing.h поставляемый
Просмотреть файл

@ -6,15 +6,7 @@
#ifndef LIB_JPEGLI_TESTING_H_
#define LIB_JPEGLI_TESTING_H_
// GTest/GMock specific macros / wrappers.
// gmock unconditionally redefines those macros (to wrong values).
// Lets include it only here and mitigate the problem.
#pragma push_macro("PRIdS")
#pragma push_macro("PRIuS")
#include "gmock/gmock.h"
#pragma pop_macro("PRIuS")
#pragma pop_macro("PRIdS")
// GTest specific macros / wrappers.
#include "gtest/gtest.h"
@ -28,8 +20,12 @@
// Ensures that we don't make our test bounds too lax, effectively disabling the
// tests.
MATCHER_P(IsSlightlyBelow, max, "") {
return max * 0.75 <= arg && arg <= max * 1.0;
}
#define EXPECT_SLIGHTLY_BELOW(A, E) \
{ \
double _actual = (A); \
double _expected = (E); \
EXPECT_LE(_actual, _expected); \
EXPECT_GE(_actual, 0.75 * _expected); \
}
#endif // LIB_JPEGLI_TESTING_H_

Просмотреть файл

@ -18,8 +18,8 @@ namespace HWY_NAMESPACE {
namespace {
#if HWY_CAP_GE256
static JXL_INLINE void Transpose8x8Block(const float* JXL_RESTRICT from,
float* JXL_RESTRICT to) {
JXL_INLINE void Transpose8x8Block(const float* JXL_RESTRICT from,
float* JXL_RESTRICT to) {
const HWY_CAPPED(float, 8) d;
auto i0 = Load(d, from);
auto i1 = Load(d, from + 1 * 8);
@ -67,8 +67,8 @@ static JXL_INLINE void Transpose8x8Block(const float* JXL_RESTRICT from,
Store(i7, d, to + 7 * 8);
}
#elif HWY_TARGET != HWY_SCALAR
static JXL_INLINE void Transpose8x8Block(const float* JXL_RESTRICT from,
float* JXL_RESTRICT to) {
JXL_INLINE void Transpose8x8Block(const float* JXL_RESTRICT from,
float* JXL_RESTRICT to) {
const HWY_CAPPED(float, 4) d;
for (size_t n = 0; n < 8; n += 4) {
for (size_t m = 0; m < 8; m += 4) {

6
third_party/jpeg-xl/lib/jpegli/upsample.cc поставляемый
Просмотреть файл

@ -122,7 +122,7 @@ HWY_EXPORT(Upsample2Vertical);
void Upsample2Horizontal(float* JXL_RESTRICT row,
float* JXL_RESTRICT scratch_space, size_t len_out) {
return HWY_DYNAMIC_DISPATCH(Upsample2Horizontal)(row, scratch_space, len_out);
HWY_DYNAMIC_DISPATCH(Upsample2Horizontal)(row, scratch_space, len_out);
}
void Upsample2Vertical(const float* JXL_RESTRICT row_top,
@ -130,8 +130,8 @@ void Upsample2Vertical(const float* JXL_RESTRICT row_top,
const float* JXL_RESTRICT row_bot,
float* JXL_RESTRICT row_out0,
float* JXL_RESTRICT row_out1, size_t len) {
return HWY_DYNAMIC_DISPATCH(Upsample2Vertical)(row_top, row_mid, row_bot,
row_out0, row_out1, len);
HWY_DYNAMIC_DISPATCH(Upsample2Vertical)
(row_top, row_mid, row_bot, row_out0, row_out1, len);
}
} // namespace jpegli
#endif // HWY_ONCE

10
third_party/jpeg-xl/lib/jxl/ac_strategy.h поставляемый
Просмотреть файл

@ -144,7 +144,7 @@ class AcStrategy {
8, 4, 8, 16, 8, 16, 32, 16, 32};
static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
"Update LUT");
return kLut[size_t(strategy_)];
return kLut[static_cast<size_t>(strategy_)];
}
JXL_INLINE size_t covered_blocks_y() const {
@ -153,7 +153,7 @@ class AcStrategy {
8, 8, 4, 16, 16, 8, 32, 32, 16};
static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
"Update LUT");
return kLut[size_t(strategy_)];
return kLut[static_cast<size_t>(strategy_)];
}
JXL_INLINE size_t log2_covered_blocks() const {
@ -162,7 +162,7 @@ class AcStrategy {
6, 5, 5, 8, 7, 7, 10, 9, 9};
static_assert(sizeof(kLut) / sizeof(*kLut) == kNumValidStrategies,
"Update LUT");
return kLut[size_t(strategy_)];
return kLut[static_cast<size_t>(strategy_)];
}
private:
@ -181,7 +181,9 @@ class AcStrategyRow {
public:
explicit AcStrategyRow(const uint8_t* row) : row_(row) {}
AcStrategy operator[](size_t x) const {
return AcStrategy(static_cast<AcStrategy::Type>(row_[x] >> 1), row_[x] & 1);
AcStrategy::Type strategy = static_cast<AcStrategy::Type>(row_[x] >> 1);
bool is_first = static_cast<bool>(row_[x] & 1);
return AcStrategy(strategy, is_first);
}
private:

Просмотреть файл

@ -81,7 +81,8 @@ class AcStrategyRoundtrip : public ::hwy::TestWithParamTargetAndT<int> {
HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(
AcStrategyRoundtrip,
::testing::Range(0, int(AcStrategy::Type::kNumValidStrategies)));
::testing::Range(0,
static_cast<int>(AcStrategy::Type::kNumValidStrategies)));
TEST_P(AcStrategyRoundtrip, Test) { Run(); }
@ -141,7 +142,8 @@ class AcStrategyRoundtripDownsample
HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(
AcStrategyRoundtripDownsample,
::testing::Range(0, int(AcStrategy::Type::kNumValidStrategies)));
::testing::Range(0,
static_cast<int>(AcStrategy::Type::kNumValidStrategies)));
TEST_P(AcStrategyRoundtripDownsample, Test) { Run(); }
@ -205,7 +207,8 @@ class AcStrategyDownsample : public ::hwy::TestWithParamTargetAndT<int> {
HWY_TARGET_INSTANTIATE_TEST_SUITE_P_T(
AcStrategyDownsample,
::testing::Range(0, int(AcStrategy::Type::kNumValidStrategies)));
::testing::Range(0,
static_cast<int>(AcStrategy::Type::kNumValidStrategies)));
TEST_P(AcStrategyDownsample, Test) { Run(); }

111
third_party/jpeg-xl/lib/jxl/alpha_test.cc поставляемый
Просмотреть файл

@ -5,69 +5,59 @@
#include "lib/jxl/alpha.h"
#include "lib/jxl/test_utils.h"
#include <array>
#include "lib/jxl/base/common.h"
#include "lib/jxl/testing.h"
namespace jxl {
namespace {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::FloatNear;
TEST(AlphaTest, BlendingWithNonPremultiplied) {
const float bg_rgb[3] = {100, 110, 120};
const Color bg_rgb{100, 110, 120};
const float bg_a = 180.f / 255;
const float fg_rgb[3] = {25, 21, 23};
const Color fg_rgb{25, 21, 23};
const float fg_a = 15420.f / 65535;
const float fg_a2 = 2.0f;
float out_rgb[3];
Color out_rgb;
float out_a;
PerformAlphaBlending(
/*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a},
/*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a},
/*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1,
/*alpha_is_premultiplied=*/false, /*clamp=*/false);
EXPECT_THAT(out_rgb,
ElementsAre(FloatNear(77.2f, .05f), FloatNear(83.0f, .05f),
FloatNear(90.6f, .05f)));
EXPECT_ARRAY_NEAR(out_rgb, (Color{77.2f, 83.0f, 90.6f}), 0.05f);
EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5);
PerformAlphaBlending(
/*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a},
/*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2},
/*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1,
/*alpha_is_premultiplied=*/false, /*clamp=*/true);
EXPECT_THAT(out_rgb, ElementsAre(FloatNear(fg_rgb[0], .05f),
FloatNear(fg_rgb[1], .05f),
FloatNear(fg_rgb[2], .05f)));
EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f);
EXPECT_NEAR(out_a, 1.0f, 1e-5);
}
TEST(AlphaTest, BlendingWithPremultiplied) {
const float bg_rgb[3] = {100, 110, 120};
const Color bg_rgb{100, 110, 120};
const float bg_a = 180.f / 255;
const float fg_rgb[3] = {25, 21, 23};
const Color fg_rgb{25, 21, 23};
const float fg_a = 15420.f / 65535;
const float fg_a2 = 2.0f;
float out_rgb[3];
Color out_rgb;
float out_a;
PerformAlphaBlending(
/*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a},
/*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a},
/*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1,
/*alpha_is_premultiplied=*/true, /*clamp=*/false);
EXPECT_THAT(out_rgb,
ElementsAre(FloatNear(101.5f, .05f), FloatNear(105.1f, .05f),
FloatNear(114.8f, .05f)));
EXPECT_ARRAY_NEAR(out_rgb, (Color{101.5f, 105.1f, 114.8f}), 0.05f);
EXPECT_NEAR(out_a, 3174.f / 4095, 1e-5);
PerformAlphaBlending(
/*bg=*/{&bg_rgb[0], &bg_rgb[1], &bg_rgb[2], &bg_a},
/*fg=*/{&fg_rgb[0], &fg_rgb[1], &fg_rgb[2], &fg_a2},
/*out=*/{&out_rgb[0], &out_rgb[1], &out_rgb[2], &out_a}, 1,
/*alpha_is_premultiplied=*/true, /*clamp=*/true);
EXPECT_THAT(out_rgb, ElementsAre(FloatNear(fg_rgb[0], .05f),
FloatNear(fg_rgb[1], .05f),
FloatNear(fg_rgb[2], .05f)));
EXPECT_ARRAY_NEAR(out_rgb, fg_rgb, 0.05f);
EXPECT_NEAR(out_a, 1.0f, 1e-5);
}
@ -76,58 +66,51 @@ TEST(AlphaTest, Mul) {
const float fg = 25;
float out;
PerformMulBlending(&bg, &fg, &out, 1, /*clamp=*/false);
EXPECT_THAT(out, FloatNear(fg * bg, .05f));
EXPECT_NEAR(out, fg * bg, .05f);
PerformMulBlending(&bg, &fg, &out, 1, /*clamp=*/true);
EXPECT_THAT(out, FloatNear(bg, .05f));
EXPECT_NEAR(out, bg, .05f);
}
TEST(AlphaTest, PremultiplyAndUnpremultiply) {
const float alpha[] = {0.f, 63.f / 255, 127.f / 255, 1.f};
float r[] = {120, 130, 140, 150};
float g[] = {124, 134, 144, 154};
float b[] = {127, 137, 147, 157};
using F4 = std::array<float, 4>;
const F4 alpha{0.f, 63.f / 255, 127.f / 255, 1.f};
F4 r{120, 130, 140, 150};
F4 g{124, 134, 144, 154};
F4 b{127, 137, 147, 157};
PremultiplyAlpha(r, g, b, alpha, 4);
EXPECT_THAT(
r, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(130 * 63.f / 255, 1e-5f),
FloatNear(140 * 127.f / 255, 1e-5f), 150));
EXPECT_THAT(
g, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(134 * 63.f / 255, 1e-5f),
FloatNear(144 * 127.f / 255, 1e-5f), 154));
EXPECT_THAT(
b, ElementsAre(FloatNear(0.f, 1e-5f), FloatNear(137 * 63.f / 255, 1e-5f),
FloatNear(147 * 127.f / 255, 1e-5f), 157));
PremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size());
EXPECT_ARRAY_NEAR(r, (F4{0.0f, 130 * 63.f / 255, 140 * 127.f / 255, 150}),
1e-5f);
EXPECT_ARRAY_NEAR(g, (F4{0.0f, 134 * 63.f / 255, 144 * 127.f / 255, 154}),
1e-5f);
EXPECT_ARRAY_NEAR(b, (F4{0.0f, 137 * 63.f / 255, 147 * 127.f / 255, 157}),
1e-5f);
UnpremultiplyAlpha(r, g, b, alpha, 4);
EXPECT_THAT(r, ElementsAre(FloatNear(120, 1e-4f), FloatNear(130, 1e-4f),
FloatNear(140, 1e-4f), FloatNear(150, 1e-4f)));
EXPECT_THAT(g, ElementsAre(FloatNear(124, 1e-4f), FloatNear(134, 1e-4f),
FloatNear(144, 1e-4f), FloatNear(154, 1e-4f)));
EXPECT_THAT(b, ElementsAre(FloatNear(127, 1e-4f), FloatNear(137, 1e-4f),
FloatNear(147, 1e-4f), FloatNear(157, 1e-4f)));
UnpremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size());
EXPECT_ARRAY_NEAR(r, (F4{120, 130, 140, 150}), 1e-4f);
EXPECT_ARRAY_NEAR(g, (F4{124, 134, 144, 154}), 1e-4f);
EXPECT_ARRAY_NEAR(b, (F4{127, 137, 147, 157}), 1e-4f);
}
TEST(AlphaTest, UnpremultiplyAndPremultiply) {
const float alpha[] = {0.f, 63.f / 255, 127.f / 255, 1.f};
float r[] = {50, 60, 70, 80};
float g[] = {54, 64, 74, 84};
float b[] = {57, 67, 77, 87};
using F4 = std::array<float, 4>;
const F4 alpha{0.f, 63.f / 255, 127.f / 255, 1.f};
F4 r{50, 60, 70, 80};
F4 g{54, 64, 74, 84};
F4 b{57, 67, 77, 87};
UnpremultiplyAlpha(r, g, b, alpha, 4);
EXPECT_THAT(r, ElementsAre(_, FloatNear(60 * 255.f / 63, 1e-4f),
FloatNear(70 * 255.f / 127, 1e-4f), 80));
EXPECT_THAT(g, ElementsAre(_, FloatNear(64 * 255.f / 63, 1e-4f),
FloatNear(74 * 255.f / 127, 1e-4f), 84));
EXPECT_THAT(b, ElementsAre(_, FloatNear(67 * 255.f / 63, 1e-4f),
FloatNear(77 * 255.f / 127, 1e-4f), 87));
UnpremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size());
EXPECT_ARRAY_NEAR(
r, (F4{50.0f * (1 << 26), 60 * 255.f / 63, 70 * 255.f / 127, 80}), 1e-4f);
EXPECT_ARRAY_NEAR(
g, (F4{54.0f * (1 << 26), 64 * 255.f / 63, 74 * 255.f / 127, 84}), 1e-4f);
EXPECT_ARRAY_NEAR(
b, (F4{57.0f * (1 << 26), 67 * 255.f / 63, 77 * 255.f / 127, 87}), 1e-4f);
PremultiplyAlpha(r, g, b, alpha, 4);
EXPECT_THAT(r, ElementsAre(FloatNear(50, 1e-4f), FloatNear(60, 1e-4f),
FloatNear(70, 1e-4f), FloatNear(80, 1e-4f)));
EXPECT_THAT(g, ElementsAre(FloatNear(54, 1e-4f), FloatNear(64, 1e-4f),
FloatNear(74, 1e-4f), FloatNear(84, 1e-4f)));
EXPECT_THAT(b, ElementsAre(FloatNear(57, 1e-4f), FloatNear(67, 1e-4f),
FloatNear(77, 1e-4f), FloatNear(87, 1e-4f)));
PremultiplyAlpha(r.data(), g.data(), b.data(), alpha.data(), alpha.size());
EXPECT_ARRAY_NEAR(r, (F4{50, 60, 70, 80}), 1e-4);
EXPECT_ARRAY_NEAR(g, (F4{54, 64, 74, 84}), 1e-4);
EXPECT_ARRAY_NEAR(b, (F4{57, 67, 77, 87}), 1e-4);
}
} // namespace

3
third_party/jpeg-xl/lib/jxl/ans_common.h поставляемый
Просмотреть файл

@ -24,7 +24,8 @@ namespace jxl {
static JXL_INLINE uint32_t GetPopulationCountPrecision(uint32_t logcount,
uint32_t shift) {
int32_t r = std::min<int>(
logcount, int(shift) - int((ANS_LOG_TAB_SIZE - logcount) >> 1));
logcount, static_cast<int>(shift) -
static_cast<int>((ANS_LOG_TAB_SIZE - logcount) >> 1));
if (r < 0) return 0;
return r;
}

17
third_party/jpeg-xl/lib/jxl/ans_test.cc поставляемый
Просмотреть файл

@ -113,8 +113,8 @@ void RoundtripRandomUnbalancedStream(int alphabet_size) {
Rng rng(0);
for (size_t i = 0; i < kReps; i++) {
std::vector<int> distributions[kNumHistograms] = {};
for (int j = 0; j < kNumHistograms; j++) {
distributions[j].resize(kPrecision);
for (auto& distr : distributions) {
distr.resize(kPrecision);
int symbol = 0;
int remaining = 1;
for (int k = 0; k < kPrecision; k++) {
@ -126,7 +126,7 @@ void RoundtripRandomUnbalancedStream(int alphabet_size) {
// sufficiently dissimilar.
remaining = rng.UniformU(0, kPrecision - k + 1);
}
distributions[j][k] = symbol;
distr[k] = symbol;
remaining--;
}
}
@ -158,7 +158,8 @@ TEST(ANSTest, RandomUnbalancedStreamRoundtripBig) {
TEST(ANSTest, UintConfigRoundtrip) {
for (size_t log_alpha_size = 5; log_alpha_size <= 8; log_alpha_size++) {
std::vector<HybridUintConfig> uint_config, uint_config_dec;
std::vector<HybridUintConfig> uint_config;
std::vector<HybridUintConfig> uint_config_dec;
for (size_t i = 0; i < log_alpha_size; i++) {
for (size_t j = 0; j <= i; j++) {
for (size_t k = 0; k <= i - j; k++) {
@ -187,16 +188,16 @@ TEST(ANSTest, UintConfigRoundtrip) {
void TestCheckpointing(bool ans, bool lz77) {
std::vector<std::vector<Token>> input_values(1);
for (size_t i = 0; i < 1024; i++) {
input_values[0].push_back(Token(0, i % 4));
input_values[0].emplace_back(0, i % 4);
}
// up to lz77 window size.
for (size_t i = 0; i < (1 << 20) - 1022; i++) {
input_values[0].push_back(Token(0, (i % 5) + 4));
input_values[0].emplace_back(0, (i % 5) + 4);
}
// Ensure that when the window wraps around, new values are different.
input_values[0].push_back(Token(0, 0));
input_values[0].emplace_back(0, 0);
for (size_t i = 0; i < 1024; i++) {
input_values[0].push_back(Token(0, i % 4));
input_values[0].emplace_back(0, i % 4);
}
std::vector<uint8_t> context_map;

3
third_party/jpeg-xl/lib/jxl/base/bits.h поставляемый
Просмотреть файл

@ -26,7 +26,8 @@ struct SizeTag {};
template <typename T>
constexpr bool IsSigned() {
return T(0) > T(-1);
// TODO(eustas): remove dupes
return static_cast<T>(0) > static_cast<T>(-1);
}
// Undefined results for x == 0.

Просмотреть файл

@ -237,22 +237,22 @@ struct OrderLE {};
// Wrappers for calling from generic code.
static JXL_INLINE void Store16(OrderBE /*tag*/, const uint32_t native,
uint8_t* p) {
return StoreBE16(native, p);
StoreBE16(native, p);
}
static JXL_INLINE void Store16(OrderLE /*tag*/, const uint32_t native,
uint8_t* p) {
return StoreLE16(native, p);
StoreLE16(native, p);
}
static JXL_INLINE void Store32(OrderBE /*tag*/, const uint32_t native,
uint8_t* p) {
return StoreBE32(native, p);
StoreBE32(native, p);
}
static JXL_INLINE void Store32(OrderLE /*tag*/, const uint32_t native,
uint8_t* p) {
return StoreLE32(native, p);
StoreLE32(native, p);
}
static JXL_INLINE uint32_t Load16(OrderBE /*tag*/, const uint8_t* p) {

41
third_party/jpeg-xl/lib/jxl/base/common.h поставляемый
Просмотреть файл

@ -8,11 +8,13 @@
// Shared constants and helper functions.
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <memory>
#include <string>
#include <type_traits>
#include "lib/jxl/base/compiler_specific.h"
@ -22,11 +24,11 @@ namespace jxl {
constexpr size_t kBitsPerByte = 8; // more clear than CHAR_BIT
constexpr inline size_t RoundUpBitsToByteMultiple(size_t bits) {
return (bits + 7) & ~size_t(7);
return (bits + 7) & ~static_cast<size_t>(7);
}
constexpr inline size_t RoundUpToBlockDim(size_t dim) {
return (dim + 7) & ~size_t(7);
return (dim + 7) & ~static_cast<size_t>(7);
}
static inline bool JXL_MAYBE_UNUSED SafeAdd(const uint64_t a, const uint64_t b,
@ -68,6 +70,37 @@ std::unique_ptr<T> make_unique(Args&&... args) {
using std::make_unique;
#endif
typedef std::array<float, 3> Color;
// Backported std::experimental::to_array
template <typename T>
using remove_cv_t = typename std::remove_cv<T>::type;
template <size_t... I>
struct index_sequence {};
template <size_t N, size_t... I>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, I...> {};
template <size_t... I>
struct make_index_sequence<0, I...> : index_sequence<I...> {};
namespace detail {
template <typename T, size_t N, size_t... I>
constexpr auto to_array(T (&&arr)[N], index_sequence<I...> _)
-> std::array<remove_cv_t<T>, N> {
return {{std::move(arr[I])...}};
}
} // namespace detail
template <typename T, size_t N>
constexpr auto to_array(T (&&arr)[N]) -> std::array<remove_cv_t<T>, N> {
return detail::to_array(std::move(arr), make_index_sequence<N>());
}
template <typename T>
JXL_INLINE T Clamp1(T val, T low, T hi) {
return val < low ? low : val > hi ? hi : val;
@ -77,10 +110,10 @@ JXL_INLINE T Clamp1(T val, T low, T hi) {
template <typename T>
std::string ToString(T n) {
char data[32] = {};
if (T(0.1) != T(0)) {
if (std::is_floating_point<T>::value) {
// float
snprintf(data, sizeof(data), "%g", static_cast<double>(n));
} else if (T(-1) > T(0)) {
} else if (std::is_unsigned<T>::value) {
// unsigned
snprintf(data, sizeof(data), "%llu", static_cast<unsigned long long>(n));
} else {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше