summaryrefslogtreecommitdiffstats
path: root/third_party/jpeg-xl/lib/extras/dec
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/jpeg-xl/lib/extras/dec')
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/apng.cc119
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/color_description.cc99
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/color_hints.cc9
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/decode.cc6
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/decode.h2
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/exr.cc9
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/gif.cc28
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/jpegli.cc21
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/jpg.cc30
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/jxl.cc90
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/jxl.h4
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/pgx.cc11
-rw-r--r--third_party/jpeg-xl/lib/extras/dec/pnm.cc31
13 files changed, 283 insertions, 176 deletions
diff --git a/third_party/jpeg-xl/lib/extras/dec/apng.cc b/third_party/jpeg-xl/lib/extras/dec/apng.cc
index f77dab77d1..8b0da06eb1 100644
--- a/third_party/jpeg-xl/lib/extras/dec/apng.cc
+++ b/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;
-
- w0 = w = png_get_uint_32(chunkIHDR.data() + 8);
- h0 = h = png_get_uint_32(chunkIHDR.data() + 12);
+ 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;
+
+ 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;
@@ -813,6 +837,8 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
have_cicp = true;
have_color = true;
ppf->icc.clear();
+ ppf->primary_color_representation =
+ PackedPixelFile::kColorEncodingIsPrimary;
}
} else if (!have_cicp && id == kId_iCCP) {
if (processing_data(png_ptr, info_ptr, chunk.data(), chunk.size())) {
@@ -830,6 +856,7 @@ Status DecodeImageAPNG(const Span<const uint8_t> bytes,
&profile, &proflen);
if (ok && proflen) {
ppf->icc.assign(profile, profile + proflen);
+ ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary;
have_color = true;
have_iccp = true;
} else {
@@ -922,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 =
@@ -944,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();
@@ -984,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
diff --git a/third_party/jpeg-xl/lib/extras/dec/color_description.cc b/third_party/jpeg-xl/lib/extras/dec/color_description.cc
index 54f6aa4206..bf229632d0 100644
--- a/third_party/jpeg-xl/lib/extras/dec/color_description.cc
+++ b/third_party/jpeg-xl/lib/extras/dec/color_description.cc
@@ -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},
-};
-
-const EnumName<JxlWhitePoint> kJxlWhitePointNames[] = {
- {"D65", JXL_WHITE_POINT_D65},
- {"Cst", JXL_WHITE_POINT_CUSTOM},
- {"EER", JXL_WHITE_POINT_E},
- {"DCI", JXL_WHITE_POINT_DCI},
-};
-
-const EnumName<JxlPrimaries> kJxlPrimariesNames[] = {
- {"SRG", JXL_PRIMARIES_SRGB},
- {"Cst", JXL_PRIMARIES_CUSTOM},
- {"202", JXL_PRIMARIES_2100},
- {"DCI", JXL_PRIMARIES_P3},
-};
-
-const EnumName<JxlTransferFunction> kJxlTransferFunctionNames[] = {
- {"709", JXL_TRANSFER_FUNCTION_709},
- {"TF?", JXL_TRANSFER_FUNCTION_UNKNOWN},
- {"Lin", JXL_TRANSFER_FUNCTION_LINEAR},
- {"SRG", JXL_TRANSFER_FUNCTION_SRGB},
- {"PeQ", JXL_TRANSFER_FUNCTION_PQ},
- {"DCI", JXL_TRANSFER_FUNCTION_DCI},
- {"HLG", JXL_TRANSFER_FUNCTION_HLG},
- {"", JXL_TRANSFER_FUNCTION_GAMMA},
-};
-
-const EnumName<JxlRenderingIntent> kJxlRenderingIntentNames[] = {
- {"Per", JXL_RENDERING_INTENT_PERCEPTUAL},
- {"Rel", JXL_RENDERING_INTENT_RELATIVE},
- {"Sat", JXL_RENDERING_INTENT_SATURATION},
- {"Abs", JXL_RENDERING_INTENT_ABSOLUTE},
-};
-
-template <typename T>
-Status ParseEnum(const std::string& token, const EnumName<T>* enum_values,
- size_t enum_len, T* value) {
- for (size_t i = 0; i < enum_len; i++) {
+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}});
+
+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}});
+
+constexpr auto kJxlPrimariesNames =
+ to_array<EnumName<JxlPrimaries>>({{"SRG", JXL_PRIMARIES_SRGB},
+ {"Cst", JXL_PRIMARIES_CUSTOM},
+ {"202", JXL_PRIMARIES_2100},
+ {"DCI", JXL_PRIMARIES_P3}});
+
+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}});
+
+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, 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;
}
diff --git a/third_party/jpeg-xl/lib/extras/dec/color_hints.cc b/third_party/jpeg-xl/lib/extras/dec/color_hints.cc
index 5c6d7b84a0..b1edd9f6ea 100644
--- a/third_party/jpeg-xl/lib/extras/dec/color_hints.cc
+++ b/third_party/jpeg-xl/lib/extras/dec/color_hints.cc
@@ -43,20 +43,21 @@ Status ApplyColorHints(const ColorHints& color_hints,
} else if (key == "icc") {
const uint8_t* data = reinterpret_cast<const uint8_t*>(value.data());
std::vector<uint8_t> icc(data, data + value.size());
- ppf->icc.swap(icc);
+ ppf->icc = std::move(icc);
+ ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary;
got_color_space = true;
} else if (key == "exif") {
const uint8_t* data = reinterpret_cast<const uint8_t*>(value.data());
std::vector<uint8_t> blob(data, data + value.size());
- ppf->metadata.exif.swap(blob);
+ ppf->metadata.exif = std::move(blob);
} else if (key == "xmp") {
const uint8_t* data = reinterpret_cast<const uint8_t*>(value.data());
std::vector<uint8_t> blob(data, data + value.size());
- ppf->metadata.xmp.swap(blob);
+ ppf->metadata.xmp = std::move(blob);
} else if (key == "jumbf") {
const uint8_t* data = reinterpret_cast<const uint8_t*>(value.data());
std::vector<uint8_t> blob(data, data + value.size());
- ppf->metadata.jumbf.swap(blob);
+ ppf->metadata.jumbf = std::move(blob);
} else {
JXL_WARNING("Ignoring %s hint", key.c_str());
}
diff --git a/third_party/jpeg-xl/lib/extras/dec/decode.cc b/third_party/jpeg-xl/lib/extras/dec/decode.cc
index b3ca711bb2..3546cb65c0 100644
--- a/third_party/jpeg-xl/lib/extras/dec/decode.cc
+++ b/third_party/jpeg-xl/lib/extras/dec/decode.cc
@@ -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) &&
diff --git a/third_party/jpeg-xl/lib/extras/dec/decode.h b/third_party/jpeg-xl/lib/extras/dec/decode.h
index 0d7dfcbef2..1a90f4c6a3 100644
--- a/third_party/jpeg-xl/lib/extras/dec/decode.h
+++ b/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);
diff --git a/third_party/jpeg-xl/lib/extras/dec/exr.cc b/third_party/jpeg-xl/lib/extras/dec/exr.cc
index 821e0f4b21..d5903155e9 100644
--- a/third_party/jpeg-xl/lib/extras/dec/exr.cc
+++ b/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;
diff --git a/third_party/jpeg-xl/lib/extras/dec/gif.cc b/third_party/jpeg-xl/lib/extras/dec/gif.cc
index 3d963941c0..3f89d460b8 100644
--- a/third_party/jpeg-xl/lib/extras/dec/gif.cc
+++ b/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) {
diff --git a/third_party/jpeg-xl/lib/extras/dec/jpegli.cc b/third_party/jpeg-xl/lib/extras/dec/jpegli.cc
index ffa1b79c25..443dfe86ba 100644
--- a/third_party/jpeg-xl/lib/extras/dec/jpegli.cc
+++ b/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;
@@ -188,7 +188,11 @@ Status DecodeJpeg(const std::vector<uint8_t>& compressed,
} else if (dparams.force_grayscale) {
cinfo.out_color_space = JCS_GRAYSCALE;
}
- if (!ReadICCProfile(&cinfo, &ppf->icc)) {
+ if (ReadICCProfile(&cinfo, &ppf->icc)) {
+ ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary;
+ } else {
+ ppf->primary_color_representation =
+ PackedPixelFile::kColorEncodingIsPrimary;
ppf->icc.clear();
// Default to SRGB
ppf->color_encoding.color_space =
@@ -214,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;
@@ -227,8 +231,8 @@ Status DecodeJpeg(const std::vector<uint8_t>& compressed,
if (dparams.num_colors > 0) {
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = dparams.num_colors;
- cinfo.two_pass_quantize = dparams.two_pass_quant;
- cinfo.dither_mode = (J_DITHER_MODE)dparams.dither_mode;
+ cinfo.two_pass_quantize = static_cast<boolean>(dparams.two_pass_quant);
+ cinfo.dither_mode = static_cast<J_DITHER_MODE>(dparams.dither_mode);
}
jpegli_start_decompress(&cinfo);
@@ -242,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 <=
diff --git a/third_party/jpeg-xl/lib/extras/dec/jpg.cc b/third_party/jpeg-xl/lib/extras/dec/jpg.cc
index 3c8a4bccfe..4a3e0d3b21 100644
--- a/third_party/jpeg-xl/lib/extras/dec/jpg.cc
+++ b/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;
@@ -242,7 +242,11 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes,
if (nbcomp != 1 && nbcomp != 3) {
return failure("unsupported number of components in JPEG");
}
- if (!ReadICCProfile(&cinfo, &ppf->icc)) {
+ if (ReadICCProfile(&cinfo, &ppf->icc)) {
+ ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary;
+ } else {
+ ppf->primary_color_representation =
+ PackedPixelFile::kColorEncodingIsPrimary;
ppf->icc.clear();
// Default to SRGB
// Actually, (cinfo.output_components == nbcomp) will be checked after
@@ -266,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;
@@ -278,8 +282,8 @@ Status DecodeImageJPG(const Span<const uint8_t> bytes,
if (dparams && dparams->num_colors > 0) {
cinfo.quantize_colors = TRUE;
cinfo.desired_number_of_colors = dparams->num_colors;
- cinfo.two_pass_quantize = dparams->two_pass_quant;
- cinfo.dither_mode = (J_DITHER_MODE)dparams->dither_mode;
+ cinfo.two_pass_quantize = static_cast<boolean>(dparams->two_pass_quant);
+ cinfo.dither_mode = static_cast<J_DITHER_MODE>(dparams->dither_mode);
}
jpeg_start_decompress(&cinfo);
@@ -295,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) {
diff --git a/third_party/jpeg-xl/lib/extras/dec/jxl.cc b/third_party/jpeg-xl/lib/extras/dec/jxl.cc
index f3e62c970a..5b7fa03f02 100644
--- a/third_party/jpeg-xl/lib/extras/dec/jxl.cc
+++ b/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;
}
@@ -351,24 +356,26 @@ bool DecodeImageJXL(const uint8_t* bytes, size_t bytes_size,
}
size_t icc_size = 0;
JxlColorProfileTarget target = JXL_COLOR_PROFILE_TARGET_DATA;
- ppf->color_encoding.color_space = JXL_COLOR_SPACE_UNKNOWN;
- if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsEncodedProfile(
- dec, target, &ppf->color_encoding) ||
- dparams.need_icc) {
- // only get ICC if it is not an Enum color encoding
- if (JXL_DEC_SUCCESS !=
- JxlDecoderGetICCProfileSize(dec, target, &icc_size)) {
- fprintf(stderr, "JxlDecoderGetICCProfileSize failed\n");
- }
- if (icc_size != 0) {
- ppf->icc.resize(icc_size);
- if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsICCProfile(
- dec, target, ppf->icc.data(), icc_size)) {
- fprintf(stderr, "JxlDecoderGetColorAsICCProfile failed\n");
- return false;
- }
+ if (JXL_DEC_SUCCESS !=
+ JxlDecoderGetICCProfileSize(dec, target, &icc_size)) {
+ fprintf(stderr, "JxlDecoderGetICCProfileSize failed\n");
+ }
+ if (icc_size != 0) {
+ ppf->primary_color_representation = PackedPixelFile::kIccIsPrimary;
+ ppf->icc.resize(icc_size);
+ if (JXL_DEC_SUCCESS != JxlDecoderGetColorAsICCProfile(
+ dec, target, ppf->icc.data(), icc_size)) {
+ fprintf(stderr, "JxlDecoderGetColorAsICCProfile failed\n");
+ return false;
}
}
+ if (JXL_DEC_SUCCESS == JxlDecoderGetColorAsEncodedProfile(
+ dec, target, &ppf->color_encoding)) {
+ ppf->primary_color_representation =
+ PackedPixelFile::kColorEncodingIsPrimary;
+ } else {
+ ppf->color_encoding.color_space = JXL_COLOR_SPACE_UNKNOWN;
+ }
icc_size = 0;
target = JXL_COLOR_PROFILE_TARGET_ORIGINAL;
if (JXL_DEC_SUCCESS !=
@@ -385,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;
}
@@ -423,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);
@@ -492,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(
diff --git a/third_party/jpeg-xl/lib/extras/dec/jxl.h b/third_party/jpeg-xl/lib/extras/dec/jxl.h
index cbada1f6dd..5f4ed7f683 100644
--- a/third_party/jpeg-xl/lib/extras/dec/jxl.h
+++ b/third_party/jpeg-xl/lib/extras/dec/jxl.h
@@ -41,10 +41,6 @@ struct JXLDecompressParams {
// Whether truncated input should be treated as an error.
bool allow_partial_input = false;
- // Set to true if an ICC profile has to be synthesized for Enum color
- // encodings
- bool need_icc = false;
-
// How many passes to decode at most. By default, decode everything.
uint32_t max_passes = std::numeric_limits<uint32_t>::max();
diff --git a/third_party/jpeg-xl/lib/extras/dec/pgx.cc b/third_party/jpeg-xl/lib/extras/dec/pgx.cc
index a99eb0f4ee..4499069d77 100644
--- a/third_party/jpeg-xl/lib/extras/dec/pgx.cc
+++ b/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) {
diff --git a/third_party/jpeg-xl/lib/extras/dec/pnm.cc b/third_party/jpeg-xl/lib/extras/dec/pnm.cc
index 4c4618d41d..040c0bff81 100644
--- a/third_party/jpeg-xl/lib/extras/dec/pnm.cc
+++ b/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;
}