// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
for (uint32_t i = 0; i < num_passes - 1; i++) {
JXL_QUIET_RETURN_IF_ERROR(visitor->Bits(2, 0, &shift[i]));
}
shift[num_passes - 1] = 0;
for (uint32_t i = 0; i < num_downsample; ++i) {
JXL_QUIET_RETURN_IF_ERROR(
visitor->U32(Val(1), Val(2), Val(4), Val(8), 1, &downsample[i])); if (i > 0 && downsample[i] >= downsample[i - 1]) { return JXL_FAILURE("downsample sequence should be decreasing");
}
} for (uint32_t i = 0; i < num_downsample; ++i) {
JXL_QUIET_RETURN_IF_ERROR(
visitor->U32(Val(0), Val(1), Val(2), Bits(3), 0, &last_pass[i])); if (i > 0 && last_pass[i] <= last_pass[i - 1]) { return JXL_FAILURE("last_pass sequence should be increasing");
} if (last_pass[i] >= num_passes) { return JXL_FAILURE("last_pass %u >= num_passes %u", last_pass[i],
num_passes);
}
}
}
returntrue;
}
#if JXL_DEBUG_V_LEVEL >= 1
std::string Passes::DebugString() const {
std::ostringstream os;
os << "p=" << num_passes; if (num_downsample) {
os << ",ds="; for (uint32_t i = 0; i < num_downsample; ++i) {
os << last_pass[i] << ":" << downsample[i]; if (i + 1 < num_downsample) os << ";";
}
} bool have_shifts = false; for (uint32_t i = 0; i < num_passes; ++i) { if (shift[i]) have_shifts = true;
} if (have_shifts) {
os << ",shifts="; for (uint32_t i = 0; i < num_passes; ++i) {
os << shift[i]; if (i + 1 < num_passes) os << ";";
}
} return os.str();
} #endif
Status FrameHeader::VisitFields(Visitor* JXL_RESTRICT visitor) { if (visitor->AllDefault(*this, &all_default)) { // Overwrite all serialized fields, but not any nonserialized_*.
visitor->SetDefault(this); returntrue;
}
JXL_QUIET_RETURN_IF_ERROR(
VisitFrameType(visitor, FrameType::kRegularFrame, &frame_type)); if (visitor->IsReading() && nonserialized_is_preview &&
frame_type != kRegularFrame) { return JXL_FAILURE("Only regular frame could be a preview");
}
// Chroma subsampling for YCbCr, if no DC frame is used. if (visitor->Conditional(color_transform == ColorTransform::kYCbCr &&
((flags & kUseDcFrame) == 0))) {
JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&chroma_subsampling));
}
// Not useful for kPatchSource if (visitor->Conditional(frame_type != FrameType::kReferenceOnly)) {
JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&passes));
}
if (visitor->Conditional(frame_type == FrameType::kDCFrame)) { // Up to 4 pyramid levels - for up to 16384x downsampling.
JXL_QUIET_RETURN_IF_ERROR(
visitor->U32(Val(1), Val(2), Val(3), Val(4), 1, &dc_level));
} if (frame_type != FrameType::kDCFrame) {
dc_level = 0;
}
// Blending info, animation info and whether this is the last frame or not. if (visitor->Conditional(frame_type == FrameType::kRegularFrame ||
frame_type == FrameType::kSkipProgressive)) {
blending_info.nonserialized_num_extra_channels = num_extra_channels;
blending_info.nonserialized_is_partial_frame = is_partial_frame;
JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&blending_info)); bool replace_all = (blending_info.mode == BlendMode::kReplace);
extra_channel_blending_info.resize(num_extra_channels); for (size_t i = 0; i < num_extra_channels; i++) { auto& ec_blending_info = extra_channel_blending_info[i];
ec_blending_info.nonserialized_is_partial_frame = is_partial_frame;
ec_blending_info.nonserialized_num_extra_channels = num_extra_channels;
JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&ec_blending_info));
replace_all &= (ec_blending_info.mode == BlendMode::kReplace);
} if (visitor->IsReading() && nonserialized_is_preview) { if (!replace_all || custom_size_or_origin) { return JXL_FAILURE("Preview is not compatible with blending");
}
} if (visitor->Conditional(nonserialized_metadata != nullptr &&
nonserialized_metadata->m.have_animation)) {
animation_frame.nonserialized_metadata = nonserialized_metadata;
JXL_QUIET_RETURN_IF_ERROR(visitor->VisitNested(&animation_frame));
}
JXL_QUIET_RETURN_IF_ERROR(visitor->Bool(true, &is_last));
} else {
is_last = false;
}
// ID of that can be used to refer to this frame. 0 for a non-zero-duration // frame means that it will not be referenced. Not necessary for the last // frame. if (visitor->Conditional(frame_type != kDCFrame && !is_last)) {
JXL_QUIET_RETURN_IF_ERROR(
visitor->U32(Val(0), Val(1), Val(2), Val(3), 0, &save_as_reference));
}
// If this frame is not blended on another frame post-color-transform, it may // be stored for being referenced either before or after the color transform. // If it is blended post-color-transform, it must be blended after. It must // also be blended after if this is a kRegular frame that does not cover the // full frame, as samples outside the partial region are from a // post-color-transform frame. if (frame_type != FrameType::kDCFrame) { if (visitor->Conditional(CanBeReferenced() &&
blending_info.mode == BlendMode::kReplace &&
!is_partial_frame &&
(frame_type == FrameType::kRegularFrame ||
frame_type == FrameType::kSkipProgressive))) {
JXL_QUIET_RETURN_IF_ERROR(
visitor->Bool(false, &save_before_color_transform));
} elseif (visitor->Conditional(frame_type == FrameType::kReferenceOnly)) {
JXL_QUIET_RETURN_IF_ERROR(
visitor->Bool(true, &save_before_color_transform));
size_t xsize = custom_size_or_origin ? frame_size.xsize
: nonserialized_metadata->xsize();
size_t ysize = custom_size_or_origin ? frame_size.ysize
: nonserialized_metadata->ysize(); if (!save_before_color_transform &&
(xsize < nonserialized_metadata->xsize() ||
ysize < nonserialized_metadata->ysize() || frame_origin.x0 != 0 ||
frame_origin.y0 != 0)) { return JXL_FAILURE( "non-patch reference frame with invalid crop: %" PRIuS "x%" PRIuS "%+d%+d",
xsize, ysize, static_cast<int>(frame_origin.x0), static_cast<int>(frame_origin.y0));
}
}
} else {
save_before_color_transform = true;
}
JXL_QUIET_RETURN_IF_ERROR(visitor->BeginExtensions(&extensions)); // Extensions: in chronological order of being added to the format. return visitor->EndExtensions();
}
if (flags) {
os << ",";
uint32_t remaining = flags;
#define TEST_FLAG(name) \ if (flags & Flags::k##name) { \
remaining &= ~Flags::k##name; \
os << #name; \ if (remaining) os << "|"; \
}
TEST_FLAG(Noise);
TEST_FLAG(Patches);
TEST_FLAG(Splines);
TEST_FLAG(UseDcFrame);
TEST_FLAG(SkipAdaptiveDCSmoothing); #undef TEST_FLAG
}
os << ",";
os << (color_transform == ColorTransform::kXYB ? "XYB"
: color_transform == ColorTransform::kYCbCr ? "YCbCr"
: "None");
if (encoding == FrameEncoding::kModular) {
os << ",shift=" << group_size_shift;
} elseif (color_transform == ColorTransform::kXYB) {
os << ",qm=" << x_qm_scale << ";" << b_qm_scale;
} if (frame_type != FrameType::kReferenceOnly) {
os << "," << passes.DebugString();
} if (custom_size_or_origin) {
os << ",xs=" << frame_size.xsize;
os << ",ys=" << frame_size.ysize; if (frame_type == FrameType::kRegularFrame ||
frame_type == FrameType::kSkipProgressive) {
os << ",x0=" << frame_origin.x0;
os << ",y0=" << frame_origin.y0;
}
} if (upsampling > 1) os << ",up=" << upsampling; if (loop_filter.gab) os << ",Gaborish"; if (loop_filter.epf_iters > 0) os << ",epf=" << loop_filter.epf_iters; if (animation_frame.duration > 0) os << ",dur=" << animation_frame.duration; if (frame_type == FrameType::kRegularFrame ||
frame_type == FrameType::kSkipProgressive) {
os << ",";
os << blending_info.DebugString(); for (size_t i = 0; i < extra_channel_blending_info.size(); ++i) {
os << (i == 0 ? "[" : ";");
os << extra_channel_blending_info[i].DebugString(); if (i + 1 == extra_channel_blending_info.size()) os << "]";
}
} if (save_as_reference > 0) os << ",ref=" << save_as_reference;
os << "," << (save_before_color_transform ? "before" : "after") << "_ct"; if (is_last) os << ",last"; return os.str();
} #endif
} // namespace jxl
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.