Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:martinbenes1996/jpeglib into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
btlorch committed Nov 20, 2023
2 parents 5522e5e + 533cf91 commit 396e69f
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 138 deletions.
121 changes: 72 additions & 49 deletions src/jpeglib/_bind.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def write_jpeg_dct(
marker_types,
marker_lengths,
markers,
cls.flags_to_mask(flags),
*cls.flags_to_mask(flags),
)
if status == 0:
raise IOError(f"writing DCT to {dstfile} failed")
Expand Down Expand Up @@ -162,7 +162,7 @@ def read_jpeg_spatial(
out_color_space,
dither_mode,
dct_method,
cls.flags_to_mask(flags)
*cls.flags_to_mask(flags)
)
if status == 0:
raise IOError(f"reading of {path} spatial failed")
Expand Down Expand Up @@ -214,7 +214,7 @@ def write_jpeg_spatial(
scan_script,
huffman_bits,
huffman_values,
cls.flags_to_mask(flags, progressive_mode),
*cls.flags_to_mask(flags, progressive_mode),
)
if status == 0:
raise IOError(f"writing spatial to {dstfile} failed")
Expand Down Expand Up @@ -250,34 +250,56 @@ def read_jpeg_progressive(
huffman_values,
qt,
quant_tbl_no,
cls.flags_to_mask(flags, True),
*cls.flags_to_mask(flags, True),
)
if status == 0:
raise IOError(f"reading scanscript of {srcfile} failed")

MASKS = {
# "DO_FANCY_SAMPLING": (0b1 << 0),
# "DO_FANCY_UPSAMPLING": (0b1 << 0),
# "DO_FANCY_DOWNSAMPLING": (0b1 << 0),
# "DO_BLOCK_SMOOTHING": (0b1 << 2),
# "TWO_PASS_QUANTIZE": (0b1 << 4),
# "ENABLE_1PASS_QUANT": (0b1 << 6),
# "ENABLE_EXTERNAL_QUANT": (0b1 << 8),
# "ENABLE_2PASS_QUANT": (0b1 << 10),
# "OPTIMIZE_CODING": (0b1 << 12),
# "PROGRESSIVE_MODE": (0b1 << 14),
# "QUANTIZE_COLORS": (0b1 << 16),
# "ARITH_CODE": (0b1 << 18),
# "WRITE_JFIF_HEADER": (0b1 << 20),
# "WRITE_ADOBE_MARKER": (0b1 << 22),
# "CCIR601_SAMPLING": (0b1 << 24),
# "FORCE_BASELINE": (0b1 << 26),
# "TRELLIS_QUANT": (0b1 << 28),
# "TRELLIS_QUANT_DC": (0b1 << 30),
# "TRELLIS_Q_OPT": (0b1 << 32),
# "OPTIMIZE_SCANS": (0b1 << 34),
# "USE_SCANS_IN_TRELLIS": (0b1 << 36),
# "OVERSHOOT_DERINGING": (0b1 << 38),
"DO_FANCY_SAMPLING": (0b1 << 0),
"DO_FANCY_UPSAMPLING": (0b1 << 0),
"DO_FANCY_DOWNSAMPLING": (0b1 << 0),
"DO_BLOCK_SMOOTHING": (0b1 << 2),
"TWO_PASS_QUANTIZE": (0b1 << 4),
"ENABLE_1PASS_QUANT": (0b1 << 6),
"ENABLE_EXTERNAL_QUANT": (0b1 << 8),
"ENABLE_2PASS_QUANT": (0b1 << 10),
"OPTIMIZE_CODING": (0b1 << 12),
"PROGRESSIVE_MODE": (0b1 << 14),
"QUANTIZE_COLORS": (0b1 << 16),
"ARITH_CODE": (0b1 << 18),
"WRITE_JFIF_HEADER": (0b1 << 20),
"WRITE_ADOBE_MARKER": (0b1 << 22),
"CCIR601_SAMPLING": (0b1 << 24),
"FORCE_BASELINE": (0b1 << 26),
"TRELLIS_QUANT": (0b1 << 28),
"TRELLIS_QUANT_DC": (0b1 << 30),
"TRELLIS_Q_OPT": (0b1 << 32),
"OPTIMIZE_SCANS": (0b1 << 34),
"USE_SCANS_IN_TRELLIS": (0b1 << 36),
"OVERSHOOT_DERINGING": (0b1 << 38),
"DO_BLOCK_SMOOTHING": (0b1 << 1),
"TWO_PASS_QUANTIZE": (0b1 << 2),
"ENABLE_1PASS_QUANT": (0b1 << 3),
"ENABLE_EXTERNAL_QUANT": (0b1 << 4),
"ENABLE_2PASS_QUANT": (0b1 << 5),
"OPTIMIZE_CODING": (0b1 << 6),
"PROGRESSIVE_MODE": (0b1 << 7),
"QUANTIZE_COLORS": (0b1 << 8),
"ARITH_CODE": (0b1 << 9),
"WRITE_JFIF_HEADER": (0b1 << 10),
"WRITE_ADOBE_MARKER": (0b1 << 11),
"CCIR601_SAMPLING": (0b1 << 12),
"FORCE_BASELINE": (0b1 << 13),
"TRELLIS_QUANT": (0b1 << 14),
"TRELLIS_QUANT_DC": (0b1 << 15),
"TRELLIS_Q_OPT": (0b1 << 16),
"OPTIMIZE_SCANS": (0b1 << 17),
"USE_SCANS_IN_TRELLIS": (0b1 << 18),
"OVERSHOOT_DERINGING": (0b1 << 19),
}

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

# Create a 32-bit mask with all 1s
mask_overwrite = 0x0
mask_set_value = ~0
# mask = 0xFFFFFFFFFFFFFFFF

uint = ctypes.c_uint
if flags is None:
return mask
return uint(mask_overwrite), uint(mask_set_value)

# progressive mode
if progressive_mode is not None:
mask ^= cls.MASKS['PROGRESSIVE_MODE'] << 1
if not progressive_mode:
mask ^= cls.MASKS['PROGRESSIVE_MODE']
mask_overwrite ^= cls.MASKS['PROGRESSIVE_MODE']
if progressive_mode is False:
mask_set_value ^= 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:]
# The more significant bit indicates whether to keep the default (defbit = 1) or change (defbit = 0).
defbit = cls.MASKS[flag.upper()] << 1
# 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.

# bit indicating whether to keep the default (0 = change)
b_overwrite = cls.MASKS[flag.upper()]

# bit carrying the new value of the bit (if changed)
b_value = cls.MASKS[flag.upper()]

# set b_ovewrite to 1, the default value will be overwritten
mask_overwrite ^= b_overwrite

# set the new value - by default 1
if sign == '-':
# Set new value to 0
mask ^= flagbit
# set to 0
mask_set_value ^= b_value

return ctypes.c_ulonglong(mask)
return uint(mask_overwrite), uint(mask_set_value)

@classmethod
def mask_to_flags(cls, mask: int):
flags = []
bitmask = mask[0]
# PROGRESSIVE_MODE = 0b00100
# mask = ??1?? or ??0??
if ((cls.MASKS["PROGRESSIVE_MODE"]) & bitmask) != 0:
if (bitmask & cls.MASKS["PROGRESSIVE_MODE"]) != 0:
flags.append("PROGRESSIVE_MODE")

return flags
Expand Down
14 changes: 9 additions & 5 deletions src/jpeglib/cjpeglib/cjpeglib.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ int read_jpeg_info(
short *huffman_bits,
short *huffman_values,
int *num_scans,
BITMASK *flags
BITMASK *flags_set_value
);

LIBRARY_API
Expand Down Expand Up @@ -64,7 +64,8 @@ int write_jpeg_dct(
int *marker_types,
int *marker_lengths,
unsigned char *markers,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
);

// ----------- RGB -------------
Expand All @@ -77,7 +78,8 @@ int read_jpeg_spatial(
int out_color_space,
int dither_mode,
int dct_method,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
);

LIBRARY_API
Expand All @@ -102,7 +104,8 @@ int write_jpeg_spatial(
int *scan_script,
short *huffman_bits,
short *huffman_values,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
);

LIBRARY_API
Expand All @@ -119,7 +122,8 @@ int read_jpeg_progressive(
short *huffman_values,
unsigned short *qt,
short *quant_tbl_no,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
);

// int jpeg_lib_version(void) { return JPEG_LIB_VERSION; }
Expand Down
10 changes: 7 additions & 3 deletions src/jpeglib/cjpeglib/cjpeglib_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ int read_jpeg_info(
short *huffman_bits,
short *huffman_values,
int *num_scans,
BITMASK *flags
BITMASK *flags_set_value
) {
// allocate
FILE *fp = NULL;
Expand Down Expand Up @@ -129,8 +129,12 @@ int read_jpeg_info(
samp_factor[ch*2 + 1] = cinfo.comp_info[ch].h_samp_factor;
}

if (flags != NULL) {
*flags = (((cinfo.progressive_mode) ? (-1) : 0) & PROGRESSIVE_MODE) | (*flags);
if (flags_set_value != NULL) {
*flags_set_value = 0;
if(cinfo.progressive_mode)
*flags_set_value |= PROGRESSIVE_MODE;

// *flags_set_value = (((cinfo.progressive_mode) ? (-1) : 0) & PROGRESSIVE_MODE) | (*flags_set_value);
}

if(huffman_bits != NULL) {
Expand Down
5 changes: 4 additions & 1 deletion src/jpeglib/cjpeglib/cjpeglib_common_flags.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ extern "C" {

#include "cjpeglib_common_flags.h"


boolean flag_to_boolean_value(
BITMASK flags,
BITMASK mask
Expand All @@ -19,9 +20,11 @@ boolean overwrite_default(
) {
// 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);
return ((flags & mask) != 0);
}

// TODO: merge?

#ifdef __cplusplus
}
#endif
61 changes: 41 additions & 20 deletions src/jpeglib/cjpeglib/cjpeglib_common_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern "C" {
#include <stdio.h>
#include "vjpeglib.h"

typedef unsigned long long BITMASK;
typedef unsigned int BITMASK;

boolean flag_to_boolean_value(
BITMASK flags,
Expand All @@ -21,26 +21,47 @@ boolean overwrite_default(
);

// 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)
// #define ENABLE_1PASS_QUANT ((BITMASK)0b1 << 6)
// #define ENABLE_EXTERNAL_QUANT ((BITMASK)0b1 << 8)
// #define ENABLE_2PASS_QUANT ((BITMASK)0b1 << 10)
// #define OPTIMIZE_CODING ((BITMASK)0b1 << 12)
// #define PROGRESSIVE_MODE ((BITMASK)0b1 << 14)
// #define QUANTIZE_COLORS ((BITMASK)0b1 << 16)
// #define ARITH_CODE ((BITMASK)0b1 << 18)
// #define WRITE_JFIF_HEADER ((BITMASK)0b1 << 20)
// #define WRITE_ADOBE_MARKER ((BITMASK)0b1 << 22)
// #define CCIR601_SAMPLING ((BITMASK)0b1 << 24)
// #define FORCE_BASELINE ((BITMASK)0b1 << 26)
// #define TRELLIS_QUANT ((BITMASK)0b1 << 28)
// #define TRELLIS_QUANT_DC ((BITMASK)0b1 << 30)
// #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)

#define DO_FANCY_UPSAMPLING ((BITMASK)0b1 << 0)
#define DO_BLOCK_SMOOTHING ((BITMASK)0b1 << 2)
#define TWO_PASS_QUANTIZE ((BITMASK)0b1 << 4)
#define ENABLE_1PASS_QUANT ((BITMASK)0b1 << 6)
#define ENABLE_EXTERNAL_QUANT ((BITMASK)0b1 << 8)
#define ENABLE_2PASS_QUANT ((BITMASK)0b1 << 10)
#define OPTIMIZE_CODING ((BITMASK)0b1 << 12)
#define PROGRESSIVE_MODE ((BITMASK)0b1 << 14)
#define QUANTIZE_COLORS ((BITMASK)0b1 << 16)
#define ARITH_CODE ((BITMASK)0b1 << 18)
#define WRITE_JFIF_HEADER ((BITMASK)0b1 << 20)
#define WRITE_ADOBE_MARKER ((BITMASK)0b1 << 22)
#define CCIR601_SAMPLING ((BITMASK)0b1 << 24)
#define FORCE_BASELINE ((BITMASK)0b1 << 26)
#define TRELLIS_QUANT ((BITMASK)0b1 << 28)
#define TRELLIS_QUANT_DC ((BITMASK)0b1 << 30)
#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)
#define DO_BLOCK_SMOOTHING ((BITMASK)0b1 << 1)
#define TWO_PASS_QUANTIZE ((BITMASK)0b1 << 2)
#define ENABLE_1PASS_QUANT ((BITMASK)0b1 << 3)
#define ENABLE_EXTERNAL_QUANT ((BITMASK)0b1 << 4)
#define ENABLE_2PASS_QUANT ((BITMASK)0b1 << 5)
#define OPTIMIZE_CODING ((BITMASK)0b1 << 6)
#define PROGRESSIVE_MODE ((BITMASK)0b1 << 7)
#define QUANTIZE_COLORS ((BITMASK)0b1 << 8)
#define ARITH_CODE ((BITMASK)0b1 << 9)
#define WRITE_JFIF_HEADER ((BITMASK)0b1 << 10)
#define WRITE_ADOBE_MARKER ((BITMASK)0b1 << 11)
#define CCIR601_SAMPLING ((BITMASK)0b1 << 12)
#define FORCE_BASELINE ((BITMASK)0b1 << 13)
#define TRELLIS_QUANT ((BITMASK)0b1 << 14)
#define TRELLIS_QUANT_DC ((BITMASK)0b1 << 15)
#define TRELLIS_Q_OPT ((BITMASK)0b1 << 16)
#define OPTIMIZE_SCANS ((BITMASK)0b1 << 17)
#define USE_SCANS_IN_TRELLIS ((BITMASK)0b1 << 18)
#define OVERSHOOT_DERINGING ((BITMASK)0b1 << 19)

#ifdef __cplusplus
}
Expand Down
11 changes: 6 additions & 5 deletions src/jpeglib/cjpeglib/cjpeglib_dct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,8 @@ int write_jpeg_dct(
int *marker_types,
int *marker_lengths,
unsigned char *markers,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
) {
// allocate
FILE *fp_in = NULL, *fp_out = NULL;
Expand Down Expand Up @@ -224,12 +225,12 @@ int write_jpeg_dct(
else if (quality > 0) {
jpeg_set_quality(&cinfo_out, quality, TRUE);
}
if (overwrite_default(flags, OPTIMIZE_CODING)) {
cinfo_out.optimize_coding = flag_to_boolean_value(flags, OPTIMIZE_CODING);
if (overwrite_default(flags_overwrite, OPTIMIZE_CODING)) {
cinfo_out.optimize_coding = flag_to_boolean_value(flags_set_value, OPTIMIZE_CODING);
}
#ifdef C_ARITH_CODING_SUPPORTED
if (overwrite_default(flags, ARITH_CODE)) {
cinfo_out.arith_code = flag_to_boolean_value(flags, ARITH_CODE);
if (overwrite_default(flags_overwrite, ARITH_CODE)) {
cinfo_out.arith_code = flag_to_boolean_value(flags_set_value, ARITH_CODE);
}
#endif

Expand Down
7 changes: 4 additions & 3 deletions src/jpeglib/cjpeglib/cjpeglib_progressive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ int read_jpeg_progressive(
short *huffman_values,
unsigned short *qt,
short *quant_tbl_no,
BITMASK flags
BITMASK flags_overwrite,
BITMASK flags_set_value
) {
// allocate
FILE *fp = NULL;
Expand All @@ -42,8 +43,8 @@ int read_jpeg_progressive(
if(dct_method >= 0) {
cinfo.dct_method = (J_DCT_METHOD)dct_method;
}
if (overwrite_default(flags, DO_FANCY_UPSAMPLING)) {
cinfo.do_fancy_upsampling = flag_to_boolean_value(flags, DO_FANCY_UPSAMPLING);
if (overwrite_default(flags_overwrite, DO_FANCY_UPSAMPLING)) {
cinfo.do_fancy_upsampling = flag_to_boolean_value(flags_set_value, DO_FANCY_UPSAMPLING);
}

jpeg_calc_output_dimensions(&cinfo);
Expand Down
Loading

0 comments on commit 396e69f

Please sign in to comment.