Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/extras/enc/jpegli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,9 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings,
}
jpegli_enable_adaptive_quantization(
&cinfo, TO_JXL_BOOL(jpeg_settings.use_adaptive_quantization));
if (jpeg_settings.use_sharpyuv) {
jpegli_set_sharp_yuv(&cinfo, TRUE);
}
if (jpeg_settings.psnr_target > 0.0) {
jpegli_set_psnr(&cinfo, jpeg_settings.psnr_target,
jpeg_settings.search_tolerance,
Expand Down
1 change: 1 addition & 0 deletions lib/extras/enc/jpegli.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PackedPixelFile;

struct JpegSettings {
bool xyb = false;
bool use_sharpyuv = false;
size_t target_size = 0;
float quality = 0.0f;
float distance = 1.f;
Expand Down
1 change: 1 addition & 0 deletions lib/jpegli/common_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class RowBuffer {
size_t xsize() const { return xsize_; };
size_t ysize() const { return ysize_; };
size_t stride() const { return stride_; }
bool HasData() const { return xsize_ > 0; }

void PadRow(size_t y, size_t from, int border) {
float* row = Row(y);
Expand Down
42 changes: 41 additions & 1 deletion lib/jpegli/encode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "lib/jpegli/quant.h"
#include "lib/jpegli/simd.h"
#include "lib/jpegli/types.h"
#include "lib/jpegli/sharp_yuv.h"

namespace jpegli {

Expand Down Expand Up @@ -430,6 +431,12 @@ void AllocateBuffers(j_compress_ptr cinfo) {
for (int c = 0; c < num_all_components; ++c) {
m->input_buffer[c].Allocate(cinfo, ysize_full, xsize_full);
}
if (m->use_sharpyuv && cinfo->in_color_space == JCS_RGB &&
cinfo->jpeg_color_space == JCS_YCbCr) {
for (int c = 0; c < 3; ++c) {
m->input_rgb[c].Allocate(cinfo, ysize_full, xsize_full);
}
}
}
for (int c = 0; c < cinfo->num_components; ++c) {
jpeg_component_info* comp = &cinfo->comp_info[c];
Expand Down Expand Up @@ -490,6 +497,14 @@ void AllocateBuffers(j_compress_ptr cinfo) {
memset(m->zero_bias_mul[c], 0, DCTSIZE2 * sizeof(float));
memset(m->zero_bias_offset[c], 0, DCTSIZE2 * sizeof(float));
}
if (m->use_sharpyuv) {
for (int i = 0; i < 7; ++i) {
m->sharpyuv_workspace[i].Allocate(cinfo, iMCU_height, xsize_full);
}
for (int i = 7; i < 13; ++i) {
m->sharpyuv_workspace[i].Allocate(cinfo, iMCU_height / 2, xsize_full / 2);
}
}
}

void InitProgressMonitor(j_compress_ptr cinfo) {
Expand Down Expand Up @@ -600,7 +615,11 @@ void ProcessiMCURow(j_compress_ptr cinfo) {
JPEGLI_CHECK(cinfo->master->next_iMCU_row < cinfo->total_iMCU_rows);
if (!cinfo->raw_data_in) {
ApplyInputSmoothing(cinfo);
DownsampleInputBuffer(cinfo);
if (cinfo->master->use_sharpyuv && cinfo->jpeg_color_space == JCS_YCbCr) {
ApplySharpYuvDownsample(cinfo);
} else {
DownsampleInputBuffer(cinfo);
}
}
ComputeAdaptiveQuantField(cinfo);
if (IsStreamingSupported(cinfo)) {
Expand Down Expand Up @@ -687,12 +706,14 @@ void jpegli_CreateCompress(j_compress_ptr cinfo, int version,
memset(cinfo->arith_ac_K, 0, sizeof(cinfo->arith_ac_K));
cinfo->write_Adobe_marker = FALSE;
cinfo->master = jpegli::Allocate<jpeg_comp_master>(cinfo, 1);
memset(cinfo->master->input_rgb, 0, sizeof(cinfo->master->input_rgb));
jpegli::InitializeCompressParams(cinfo);
cinfo->master->force_baseline = true;
cinfo->master->xyb_mode = false;
cinfo->master->cicp_transfer_function = 2; // unknown transfer function code
cinfo->master->use_std_tables = false;
cinfo->master->use_adaptive_quantization = true;
cinfo->master->use_sharpyuv = false;
cinfo->master->progressive_level = jpegli::kDefaultProgressiveLevel;
cinfo->master->data_type = JPEGLI_TYPE_UINT8;
cinfo->master->endianness = JPEGLI_NATIVE_ENDIAN;
Expand Down Expand Up @@ -927,6 +948,11 @@ void jpegli_enable_adaptive_quantization(j_compress_ptr cinfo, boolean value) {
cinfo->master->use_adaptive_quantization = FROM_JXL_BOOL(value);
}

void jpegli_set_sharp_yuv(j_compress_ptr cinfo, boolean enable) {
CheckState(cinfo, jpegli::kEncStart);
cinfo->master->use_sharpyuv = FROM_JXL_BOOL(enable);
}

void jpegli_simple_progression(j_compress_ptr cinfo) {
CheckState(cinfo, jpegli::kEncStart);
jpegli_set_progressive_level(cinfo, 2);
Expand Down Expand Up @@ -1149,8 +1175,22 @@ JDIMENSION jpegli_write_scanlines(j_compress_ptr cinfo, JSAMPARRAY scanlines,
cinfo->next_scanline += input_lag;
}
float* rows[jpegli::kMaxComponents];
const bool snapshot_rgb = m->use_sharpyuv &&
cinfo->in_color_space == JCS_RGB &&
cinfo->jpeg_color_space == JCS_YCbCr;
for (size_t i = input_lag; i < num_lines; ++i) {
jpegli::ReadInputRow(cinfo, scanlines[i], rows);
if (snapshot_rgb) {
size_t row_idx = m->next_input_row - 1;
size_t img_w = cinfo->image_width;
size_t pad_w = m->xsize_blocks * DCTSIZE;
for (int c = 0; c < 3; ++c) {
float* rgb_row = m->input_rgb[c].Row(row_idx);
memcpy(rgb_row, rows[c], img_w * sizeof(float));
float last = rgb_row[img_w - 1];
for (size_t x = img_w; x <= pad_w; ++x) rgb_row[x] = last;
}
}
(*m->color_transform)(rows, cinfo->image_width);
jpegli::PadInputBuffer(cinfo, rows);
jpegli::ProcessiMCURows(cinfo);
Expand Down
3 changes: 3 additions & 0 deletions lib/jpegli/encode.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ void jpegli_set_input_format(j_compress_ptr cinfo, JpegliDataType data_type,
// Enabled by default.
void jpegli_enable_adaptive_quantization(j_compress_ptr cinfo, boolean value);

// Enables linear-light sharp YUV downsampling.
void jpegli_set_sharp_yuv(j_compress_ptr cinfo, boolean enable);

// Sets the default progression parameters, where level 0 is sequential, and
// greater level value means more progression steps. Default is 2.
void jpegli_set_progressive_level(j_compress_ptr cinfo, int level);
Expand Down
3 changes: 3 additions & 0 deletions lib/jpegli/encode_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ struct ScanTokenInfo {

struct jpeg_comp_master {
jpegli::RowBuffer<float> input_buffer[jpegli::kMaxComponents];
jpegli::RowBuffer<float> input_rgb[3];
jpegli::RowBuffer<float>* smooth_input[jpegli::kMaxComponents];
jpegli::RowBuffer<float>* raw_data[jpegli::kMaxComponents];
bool force_baseline;
bool xyb_mode;
uint8_t cicp_transfer_function;
bool use_std_tables;
bool use_adaptive_quantization;
bool use_sharpyuv;
int progressive_level;
size_t xsize_blocks;
size_t ysize_blocks;
Expand Down Expand Up @@ -138,6 +140,7 @@ struct jpeg_comp_master {
float psnr_tolerance;
float min_distance;
float max_distance;
jpegli::RowBuffer<float> sharpyuv_workspace[13];
};

#endif // LIB_JPEGLI_ENCODE_INTERNAL_H_
Loading