Skip to content

Commit

Permalink
Add new flag to control the OVERSHOOT_DERINGING option in mozjpeg. Re…
Browse files Browse the repository at this point in the history
…name "flag_is_set" to "flag_to_boolean_value" and "overwrite_flag" to "overwrite_default". Extent mask from 32 bit to 64 bit.
  • Loading branch information
btlorch committed Nov 14, 2023
1 parent 5bf7d01 commit cd27d4d
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 16 deletions.
26 changes: 20 additions & 6 deletions src/jpeglib/_bind.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ def read_jpeg_progressive(
"TRELLIS_Q_OPT": (0b1 << 32),
"OPTIMIZE_SCANS": (0b1 << 34),
"USE_SCANS_IN_TRELLIS": (0b1 << 36),
"OVERSHOOT_DERINGING": (0b1 << 38),
}

@classmethod
Expand All @@ -285,27 +286,40 @@ def flags_to_mask(
flags: List[str],
progressive_mode: bool = None,
):
mask = 0xFFFFFFFF
# Create a 64-bit mask with all 1s
mask = 0xFFFFFFFFFFFFFFFF

if flags is None:
return mask

# progressive mode
if progressive_mode is not None:
mask ^= cls.MASKS['PROGRESSIVE_MODE'] << 1
if not progressive_mode:
mask ^= cls.MASKS['PROGRESSIVE_MODE']

# manual flags
for flag in flags:
# parse sign
sign = '-' if flag[0] == '-' else '+'
if not flag[0].isalpha():
# flag does not have a sign, so we interpret it as +
flag = flag[1:]
# get flags
flagbit = cls.MASKS[flag.upper()]

# The more significant bit indicates whether to keep the default (defbit = 1) or change (defbit = 0).
defbit = cls.MASKS[flag.upper()] << 1
# map
mask ^= defbit # reset default value

# The less significant bit contains the changed value.
flagbit = cls.MASKS[flag.upper()]

# Set defbit to 0, meaning that the default value should be overwritten.
mask ^= defbit

# Set the new value. By default, it is set to 1.
if sign == '-':
mask ^= flagbit # erase bit
# Set new value to 0
mask ^= flagbit

return ctypes.c_ulonglong(mask)

@classmethod
Expand Down
8 changes: 6 additions & 2 deletions src/jpeglib/cjpeglib/cjpeglib_common_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@ extern "C" {

#include "cjpeglib_common_flags.h"

boolean flag_is_set(
boolean flag_to_value(
BITMASK flags,
BITMASK mask
) {
// Flags are encoded as 2 bits. The less significant bit is the new value to be set.
// This method returns *false* when the LSB is set to 0, and *true* when the LSB is set to 1.
return (flags & mask) != 0;
}
unsigned char overwrite_flag(
boolean overwrite_default(
BITMASK flags,
BITMASK mask
) {
// Flags are encoded as 2 bits. The more significant bit indicates whether the default should be kept (= 1) or overwritten (= 0).
// This method returns 1 when the default should be overwritten. It returns 0 when the default should be kept.
return ((flags & (mask << 1)) == 0);
}

Expand Down
6 changes: 4 additions & 2 deletions src/jpeglib/cjpeglib/cjpeglib_common_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,16 @@ extern "C" {

typedef unsigned long long BITMASK;

boolean flag_is_set(
boolean flag_to_boolean_value(
BITMASK flags,
BITMASK mask
);
unsigned char overwrite_flag(
boolean overwrite_default(
BITMASK flags,
BITMASK mask
);

// There are 2 bits per flag. The more significant bit (MSB) indicates whether to keep the default value (= 1) or whether to overwrite the default value (= 0). If the MSB is 1, the less significant bit (LSB) is ignored. If the MSB is 0, the LSB is taken as the new value.
#define DO_FANCY_UPSAMPLING ((BITMASK)0b1 << 0)
#define DO_BLOCK_SMOOTHING ((BITMASK)0b1 << 2)
#define TWO_PASS_QUANTIZE ((BITMASK)0b1 << 4)
Expand All @@ -38,6 +39,7 @@ unsigned char overwrite_flag(
#define TRELLIS_Q_OPT ((BITMASK)0b1 << 32)
#define OPTIMIZE_SCANS ((BITMASK)0b1 << 34)
#define USE_SCANS_IN_TRELLIS ((BITMASK)0b1 << 36)
#define OVERSHOOT_DERINGING ((BITMASK)0b1 << 38)

#ifdef __cplusplus
}
Expand Down
8 changes: 4 additions & 4 deletions src/jpeglib/cjpeglib/cjpeglib_dct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,12 @@ int write_jpeg_dct(
else if (quality > 0) {
jpeg_set_quality(&cinfo_out, quality, TRUE);
}
if (overwrite_flag(flags, OPTIMIZE_CODING)) {
cinfo_out.optimize_coding = flag_is_set(flags, OPTIMIZE_CODING);
if (overwrite_default(flags, OPTIMIZE_CODING)) {
cinfo_out.optimize_coding = flag_to_boolean_value(flags, OPTIMIZE_CODING);
}
#ifdef C_ARITH_CODING_SUPPORTED
if (overwrite_flag(flags, ARITH_CODE)) {
cinfo_out.arith_code = flag_is_set(flags, ARITH_CODE);
if (overwrite_default(flags, ARITH_CODE)) {
cinfo_out.arith_code = flag_to_boolean_value(flags, ARITH_CODE);
}
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/jpeglib/cjpeglib/cjpeglib_progressive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ int read_jpeg_progressive(
if(dct_method >= 0) {
cinfo.dct_method = (J_DCT_METHOD)dct_method;
}
if (overwrite_flag(flags, DO_FANCY_UPSAMPLING)) {
cinfo.do_fancy_upsampling = flag_is_set(flags, DO_FANCY_UPSAMPLING);
if (overwrite_default(flags, DO_FANCY_UPSAMPLING)) {
cinfo.do_fancy_upsampling = flag_to_boolean_value(flags, DO_FANCY_UPSAMPLING);
}

jpeg_calc_output_dimensions(&cinfo);
Expand Down
16 changes: 16 additions & 0 deletions src/jpeglib/cjpeglib/cjpeglib_spatial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern "C" {
#include "vjpeglib.h"
#include "cjpeglib.h"
#include "cjpeglib_common.h"
#include "jpegint.h"


int read_jpeg_spatial(
Expand Down Expand Up @@ -328,6 +329,21 @@ int write_jpeg_spatial(
flag_is_set(flags, TRELLIS_Q_OPT)
);
}
if(overwrite_flag(flags, OVERSHOOT_DERINGING)) {
printf("Going to overwrite overshoot deringing? %d\n", flag_is_set(flags, OVERSHOOT_DERINGING));

jpeg_c_set_bool_param(
&cinfo,
JBOOLEAN_OVERSHOOT_DERINGING,
flag_is_set(flags, OVERSHOOT_DERINGING)
);
}

printf("flags: %llu\n", flags);
printf("cinfo.master->trellis_quant = %d\n", cinfo.master->trellis_quant);
printf("cinfo.master->trellis_quant_dc = %d\n", cinfo.master->trellis_quant_dc);
printf("cinfo.master->master->overshoot_deringing = %d\n", cinfo.master->overshoot_deringing);

// if(overwrite_flag(flags, OPTIMIZE_SCANS)) {
// jpeg_c_set_bool_param(
// &cinfo,
Expand Down

0 comments on commit cd27d4d

Please sign in to comment.