Merge mozjpeg into libjpeg-turbo
* origin/master: (23 commits) Update .gitignore .func/.endfunc are only necessary when generating STABS debug info, which basically went out of style with parachute pants and Rick Astley. At any rate, none of the platforms for which we're building the ARM code use it (DWARF is the common format these days), and the .func/.endfunc directives cause the clang integrated assembler to fail (http://llvm.org/bugs/show_bug.cgi?id=20424). Enable DC trellis by default Avoid double inline attribute Detect libpng Implement DHT Merging Add .gitignore for autotools files Check memory alloc success Update cjpeg usage text Implement DQT merging Fix issue with scan printout Get rid of unnecessary and obsolete platform configuration instructions. Add error checks for malloc calls that don't already have them. Issue #87. yuvjpeg: fix trivial leak Parse quality as float PNG reading support Fix issue with DC trellis Add option to split DC scans Add trellis for DC Bump version to 2.1. ... Conflicts: BUILDING.txt cdjpeg.h jcdctmgr.c jchuff.h jcmarker.c jcmaster.c jconfig.txt jpeglib.h rdswitch.c
This commit is contained in:
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Makefile.in
|
||||||
|
/autom4te.cache
|
||||||
|
/aclocal.m4
|
||||||
|
/compile
|
||||||
|
/configure
|
||||||
|
/depcomp
|
||||||
|
/install-sh
|
||||||
|
/missing
|
||||||
|
/stamp-h1
|
||||||
|
/config.guess
|
||||||
|
/config.h.in
|
||||||
|
/config.sub
|
||||||
|
/ltmain.sh
|
||||||
|
/ar-lib
|
||||||
11
BUILDING.txt
11
BUILDING.txt
@@ -216,17 +216,6 @@ Add
|
|||||||
to the configure command line.
|
to the configure command line.
|
||||||
|
|
||||||
|
|
||||||
64-bit Build on 64-bit OS X
|
|
||||||
---------------------------
|
|
||||||
|
|
||||||
Add
|
|
||||||
|
|
||||||
--host x86_64-apple-darwin NASM=/opt/local/bin/nasm
|
|
||||||
|
|
||||||
to the configure command line. NASM 2.07 or later from MacPorts must be
|
|
||||||
installed.
|
|
||||||
|
|
||||||
|
|
||||||
32-bit Build on 64-bit OS X
|
32-bit Build on 64-bit OS X
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ if(POLICY CMP0022)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
project(libmozjpeg C)
|
project(libmozjpeg C)
|
||||||
set(VERSION 2.0.1)
|
set(VERSION 2.1)
|
||||||
|
|
||||||
if(CYGWIN OR NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
if(CYGWIN OR NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||||
execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE BUILD)
|
execute_process(COMMAND "date" "+%Y%m%d" OUTPUT_VARIABLE BUILD)
|
||||||
|
|||||||
@@ -116,6 +116,12 @@ cjpeg_LDADD = libjpeg.la
|
|||||||
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
|
cjpeg_CFLAGS = -DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED \
|
||||||
-DTARGA_SUPPORTED
|
-DTARGA_SUPPORTED
|
||||||
|
|
||||||
|
if HAVE_LIBPNG
|
||||||
|
cjpeg_CFLAGS += -DPNG_SUPPORTED $(libpng_CFLAGS)
|
||||||
|
cjpeg_LDADD += $(libpng_LIBS)
|
||||||
|
cjpeg_SOURCES += rdpng.c
|
||||||
|
endif
|
||||||
|
|
||||||
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
|
djpeg_SOURCES = cdjpeg.h cderror.h cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \
|
||||||
wrbmp.c wrgif.c wrppm.c wrtarga.c
|
wrbmp.c wrgif.c wrppm.c wrtarga.c
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ The idea is to reduce transfer times for JPEGs on the Web, thus reducing page lo
|
|||||||
|
|
||||||
'mozjpeg' is not intended to be a general JPEG library replacement. It makes tradeoffs that are intended to benefit Web use cases and focuses solely on improving encoding. It is best used as part of a Web encoding workflow. For a general JPEG library (e.g. your system libjpeg), especially if you care about decoding, we recommend libjpeg-turbo.
|
'mozjpeg' is not intended to be a general JPEG library replacement. It makes tradeoffs that are intended to benefit Web use cases and focuses solely on improving encoding. It is best used as part of a Web encoding workflow. For a general JPEG library (e.g. your system libjpeg), especially if you care about decoding, we recommend libjpeg-turbo.
|
||||||
|
|
||||||
For more information, see the project announcement:
|
More information:
|
||||||
|
|
||||||
https://blog.mozilla.org/research/2014/03/05/introducing-the-mozjpeg-project/
|
* [Version 1.0 Announcement](https://blog.mozilla.org/research/2014/03/05/introducing-the-mozjpeg-project/)
|
||||||
|
* [Version 2.0 Announcement](https://blog.mozilla.org/research/2014/07/15/mozilla-advances-jpeg-encoding-with-mozjpeg-2-0/)
|
||||||
|
* [Mailing List](https://lists.mozilla.org/listinfo/dev-mozjpeg)</a>
|
||||||
|
|||||||
@@ -122,6 +122,10 @@ JMESSAGE(JERR_UNKNOWN_FORMAT, "Unrecognized input file format")
|
|||||||
#endif
|
#endif
|
||||||
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
|
JMESSAGE(JERR_UNSUPPORTED_FORMAT, "Unsupported output file format")
|
||||||
|
|
||||||
|
#ifdef PNG_SUPPORTED
|
||||||
|
JMESSAGE(JERR_PNG_ERROR, "Unable to read PNG file: %s")
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef JMAKE_ENUM_LIST
|
#ifdef JMAKE_ENUM_LIST
|
||||||
|
|
||||||
JMSG_LASTADDONCODE
|
JMSG_LASTADDONCODE
|
||||||
|
|||||||
1
cdjpeg.h
1
cdjpeg.h
@@ -104,6 +104,7 @@ EXTERN(cjpeg_source_ptr) jinit_read_gif (j_compress_ptr cinfo);
|
|||||||
EXTERN(djpeg_dest_ptr) jinit_write_gif (j_decompress_ptr cinfo);
|
EXTERN(djpeg_dest_ptr) jinit_write_gif (j_decompress_ptr cinfo);
|
||||||
EXTERN(cjpeg_source_ptr) jinit_read_jpeg (j_compress_ptr cinfo);
|
EXTERN(cjpeg_source_ptr) jinit_read_jpeg (j_compress_ptr cinfo);
|
||||||
EXTERN(cjpeg_source_ptr) jinit_read_ppm (j_compress_ptr cinfo);
|
EXTERN(cjpeg_source_ptr) jinit_read_ppm (j_compress_ptr cinfo);
|
||||||
|
EXTERN(cjpeg_source_ptr) jinit_read_png (j_compress_ptr cinfo);
|
||||||
EXTERN(djpeg_dest_ptr) jinit_write_ppm (j_decompress_ptr cinfo);
|
EXTERN(djpeg_dest_ptr) jinit_write_ppm (j_decompress_ptr cinfo);
|
||||||
EXTERN(cjpeg_source_ptr) jinit_read_rle (j_compress_ptr cinfo);
|
EXTERN(cjpeg_source_ptr) jinit_read_rle (j_compress_ptr cinfo);
|
||||||
EXTERN(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo);
|
EXTERN(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo);
|
||||||
|
|||||||
29
cjpeg.c
29
cjpeg.c
@@ -113,6 +113,10 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)
|
|||||||
case 'P':
|
case 'P':
|
||||||
return jinit_read_ppm(cinfo);
|
return jinit_read_ppm(cinfo);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef PNG_SUPPORTED
|
||||||
|
case 0x89:
|
||||||
|
return jinit_read_png(cinfo);
|
||||||
|
#endif
|
||||||
#ifdef RLE_SUPPORTED
|
#ifdef RLE_SUPPORTED
|
||||||
case 'R':
|
case 'R':
|
||||||
return jinit_read_rle(cinfo);
|
return jinit_read_rle(cinfo);
|
||||||
@@ -168,13 +172,17 @@ usage (void)
|
|||||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||||
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n");
|
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n");
|
||||||
#endif
|
#endif
|
||||||
|
fprintf(stderr, " -baseline Create baseline JPEG file (disable progressive coding)\n");
|
||||||
#ifdef TARGA_SUPPORTED
|
#ifdef TARGA_SUPPORTED
|
||||||
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
|
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\n");
|
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\n");
|
||||||
fprintf(stderr, " -fastcrush Disable progressive scan optimization\n");
|
fprintf(stderr, " -fastcrush Disable progressive scan optimization\n");
|
||||||
fprintf(stderr, " -multidcscan Use multiple DC scans (may be incompatible with some JPEG decoders)\n");
|
fprintf(stderr, " -opt-dc-scan Optimize DC scans (may be incompatible with some JPEG decoders)\n");
|
||||||
|
fprintf(stderr, " -split-dc-scan Use one DC scan per component (may be incompatible with some JPEG decoders?)\n");
|
||||||
fprintf(stderr, " -notrellis Disable trellis optimization\n");
|
fprintf(stderr, " -notrellis Disable trellis optimization\n");
|
||||||
|
fprintf(stderr, " -trellis-dc Enable trellis optimization of DC coefficients (default)\n");
|
||||||
|
fprintf(stderr, " -notrellis-dc Disable trellis optimization of DC coefficients\n");
|
||||||
fprintf(stderr, " -tune-psnr Tune trellis optimization for PSNR\n");
|
fprintf(stderr, " -tune-psnr Tune trellis optimization for PSNR\n");
|
||||||
fprintf(stderr, " -tune-hvs-psnr Tune trellis optimization for PSNR-HVS (default)\n");
|
fprintf(stderr, " -tune-hvs-psnr Tune trellis optimization for PSNR-HVS (default)\n");
|
||||||
fprintf(stderr, " -tune-ssim Tune trellis optimization for SSIM\n");
|
fprintf(stderr, " -tune-ssim Tune trellis optimization for SSIM\n");
|
||||||
@@ -206,7 +214,6 @@ usage (void)
|
|||||||
#endif
|
#endif
|
||||||
fprintf(stderr, " -verbose or -debug Emit debug output\n");
|
fprintf(stderr, " -verbose or -debug Emit debug output\n");
|
||||||
fprintf(stderr, "Switches for wizards:\n");
|
fprintf(stderr, "Switches for wizards:\n");
|
||||||
fprintf(stderr, " -baseline Force baseline quantization tables\n");
|
|
||||||
fprintf(stderr, " -qtables file Use quantization tables given in file\n");
|
fprintf(stderr, " -qtables file Use quantization tables given in file\n");
|
||||||
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
|
fprintf(stderr, " -qslots N[,...] Set component quantization tables\n");
|
||||||
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
|
fprintf(stderr, " -sample HxV[,...] Set component sampling factors\n");
|
||||||
@@ -279,6 +286,10 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
} else if (keymatch(arg, "baseline", 1)) {
|
} else if (keymatch(arg, "baseline", 1)) {
|
||||||
/* Force baseline-compatible output (8-bit quantizer values). */
|
/* Force baseline-compatible output (8-bit quantizer values). */
|
||||||
force_baseline = TRUE;
|
force_baseline = TRUE;
|
||||||
|
/* Disable multiple scans */
|
||||||
|
simple_progressive = FALSE;
|
||||||
|
cinfo->num_scans = 0;
|
||||||
|
cinfo->scan_info = NULL;
|
||||||
|
|
||||||
} else if (keymatch(arg, "dct", 2)) {
|
} else if (keymatch(arg, "dct", 2)) {
|
||||||
/* Select DCT algorithm. */
|
/* Select DCT algorithm. */
|
||||||
@@ -349,7 +360,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
lval *= 1000L;
|
lval *= 1000L;
|
||||||
cinfo->mem->max_memory_to_use = lval * 1000L;
|
cinfo->mem->max_memory_to_use = lval * 1000L;
|
||||||
|
|
||||||
} else if (keymatch(arg, "multidcscan", 3)) {
|
} else if (keymatch(arg, "opt-dc-scan", 6)) {
|
||||||
cinfo->one_dc_scan = FALSE;
|
cinfo->one_dc_scan = FALSE;
|
||||||
|
|
||||||
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
|
} else if (keymatch(arg, "optimize", 1) || keymatch(arg, "optimise", 1)) {
|
||||||
@@ -475,14 +486,26 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
|||||||
usage();
|
usage();
|
||||||
cinfo->smoothing_factor = val;
|
cinfo->smoothing_factor = val;
|
||||||
|
|
||||||
|
} else if (keymatch(arg, "split-dc-scans", 3)) {
|
||||||
|
cinfo->one_dc_scan = FALSE;
|
||||||
|
cinfo->sep_dc_scan = TRUE;
|
||||||
|
|
||||||
} else if (keymatch(arg, "targa", 1)) {
|
} else if (keymatch(arg, "targa", 1)) {
|
||||||
/* Input file is Targa format. */
|
/* Input file is Targa format. */
|
||||||
is_targa = TRUE;
|
is_targa = TRUE;
|
||||||
|
|
||||||
|
} else if (keymatch(arg, "notrellis-dc", 11)) {
|
||||||
|
/* disable trellis quantization */
|
||||||
|
cinfo->trellis_quant_dc = FALSE;
|
||||||
|
|
||||||
} else if (keymatch(arg, "notrellis", 1)) {
|
} else if (keymatch(arg, "notrellis", 1)) {
|
||||||
/* disable trellis quantization */
|
/* disable trellis quantization */
|
||||||
cinfo->trellis_quant = FALSE;
|
cinfo->trellis_quant = FALSE;
|
||||||
|
|
||||||
|
} else if (keymatch(arg, "trellis-dc", 9)) {
|
||||||
|
/* enable DC trellis quantization */
|
||||||
|
cinfo->trellis_quant_dc = TRUE;
|
||||||
|
|
||||||
} else if (keymatch(arg, "tune-psnr", 6)) {
|
} else if (keymatch(arg, "tune-psnr", 6)) {
|
||||||
cinfo->use_flat_quant_tbl = TRUE;
|
cinfo->use_flat_quant_tbl = TRUE;
|
||||||
cinfo->lambda_log_scale1 = 9.0;
|
cinfo->lambda_log_scale1 = 9.0;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
AC_PREREQ([2.56])
|
AC_PREREQ([2.56])
|
||||||
AC_INIT([libmozjpeg], [2.0.1])
|
AC_INIT([libmozjpeg], [2.1])
|
||||||
BUILD=`date +%Y%m%d`
|
BUILD=`date +%Y%m%d`
|
||||||
|
|
||||||
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
|
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
|
||||||
@@ -93,6 +93,11 @@ fi
|
|||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
AC_CHECK_LIB([m],[pow])
|
AC_CHECK_LIB([m],[pow])
|
||||||
|
|
||||||
|
PKG_CHECK_MODULES([libpng], [libpng], [HAVE_LIBPNG=1], [
|
||||||
|
PKG_CHECK_MODULES([libpng], [libpng12], [HAVE_LIBPNG=1], [HAVE_LIBPNG=0])
|
||||||
|
])
|
||||||
|
AM_CONDITIONAL([HAVE_LIBPNG], [test "$HAVE_LIBPNG" -eq 1])
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
AC_CHECK_HEADERS([stddef.h stdlib.h locale.h string.h])
|
AC_CHECK_HEADERS([stddef.h stdlib.h locale.h string.h])
|
||||||
@@ -263,7 +268,7 @@ int bar() { return foo();], ljt_cv_inline="__inline",
|
|||||||
AC_TRY_COMPILE(, [} inline int foo() { return 0; }
|
AC_TRY_COMPILE(, [} inline int foo() { return 0; }
|
||||||
int bar() { return foo();], ljt_cv_inline="inline"))))
|
int bar() { return foo();], ljt_cv_inline="inline"))))
|
||||||
AC_MSG_RESULT($ljt_cv_inline)
|
AC_MSG_RESULT($ljt_cv_inline)
|
||||||
AC_DEFINE_UNQUOTED([INLINE],[inline $ljt_cv_inline],[How to obtain function inlining.])
|
AC_DEFINE_UNQUOTED([INLINE],[$ljt_cv_inline],[How to obtain function inlining.])
|
||||||
|
|
||||||
# Arithmetic coding support
|
# Arithmetic coding support
|
||||||
AC_MSG_CHECKING([whether to include arithmetic encoding support])
|
AC_MSG_CHECKING([whether to include arithmetic encoding support])
|
||||||
|
|||||||
@@ -360,10 +360,13 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||||||
JBLOCKARRAY buffer_dst;
|
JBLOCKARRAY buffer_dst;
|
||||||
|
|
||||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||||
|
c_derived_tbl dctbl_data;
|
||||||
|
c_derived_tbl *dctbl = &dctbl_data;
|
||||||
c_derived_tbl actbl_data;
|
c_derived_tbl actbl_data;
|
||||||
c_derived_tbl *actbl = &actbl_data;
|
c_derived_tbl *actbl = &actbl_data;
|
||||||
compptr = cinfo->cur_comp_info[ci];
|
compptr = cinfo->cur_comp_info[ci];
|
||||||
|
|
||||||
|
jpeg_make_c_derived_tbl(cinfo, TRUE, compptr->dc_tbl_no, &dctbl);
|
||||||
jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl);
|
jpeg_make_c_derived_tbl(cinfo, FALSE, compptr->ac_tbl_no, &actbl);
|
||||||
|
|
||||||
/* Align the virtual buffer for this component. */
|
/* Align the virtual buffer for this component. */
|
||||||
@@ -391,12 +394,15 @@ compress_trellis_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
|
|||||||
ndummy = (int) (blocks_across % h_samp_factor);
|
ndummy = (int) (blocks_across % h_samp_factor);
|
||||||
if (ndummy > 0)
|
if (ndummy > 0)
|
||||||
ndummy = h_samp_factor - ndummy;
|
ndummy = h_samp_factor - ndummy;
|
||||||
|
|
||||||
|
lastDC = 0;
|
||||||
|
|
||||||
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
||||||
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
||||||
*/
|
*/
|
||||||
for (block_row = 0; block_row < block_rows; block_row++) {
|
for (block_row = 0; block_row < block_rows; block_row++) {
|
||||||
thisblockrow = buffer[block_row];
|
thisblockrow = buffer[block_row];
|
||||||
quantize_trellis(cinfo, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no], cinfo->norm_src[compptr->quant_tbl_no], cinfo->norm_coef[compptr->quant_tbl_no]);
|
quantize_trellis(cinfo, dctbl, actbl, thisblockrow, buffer_dst[block_row], blocks_across, cinfo->quant_tbl_ptrs[compptr->quant_tbl_no], cinfo->norm_src[compptr->quant_tbl_no], cinfo->norm_coef[compptr->quant_tbl_no], &lastDC);
|
||||||
|
|
||||||
if (ndummy > 0) {
|
if (ndummy > 0) {
|
||||||
/* Create dummy blocks at the right edge of the image. */
|
/* Create dummy blocks at the right edge of the image. */
|
||||||
|
|||||||
108
jcdctmgr.c
108
jcdctmgr.c
@@ -614,10 +614,10 @@ static const float jpeg_lambda_weights_csf_luma[64] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
GLOBAL(void)
|
GLOBAL(void)
|
||||||
quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
||||||
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef)
|
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef, JCOEF *last_dc_val)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
int i, j, k, l;
|
||||||
float accumulated_zero_dist[DCTSIZE2];
|
float accumulated_zero_dist[DCTSIZE2];
|
||||||
float accumulated_cost[DCTSIZE2];
|
float accumulated_cost[DCTSIZE2];
|
||||||
int run_start[DCTSIZE2];
|
int run_start[DCTSIZE2];
|
||||||
@@ -627,6 +627,7 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc
|
|||||||
float norm = 0.0;
|
float norm = 0.0;
|
||||||
float lambda_base;
|
float lambda_base;
|
||||||
float lambda;
|
float lambda;
|
||||||
|
float lambda_dc;
|
||||||
const float *lambda_tbl = (cinfo->use_lambda_weight_tbl) ? jpeg_lambda_weights_csf_luma : jpeg_lambda_weights_flat;
|
const float *lambda_tbl = (cinfo->use_lambda_weight_tbl) ? jpeg_lambda_weights_csf_luma : jpeg_lambda_weights_flat;
|
||||||
int Ss, Se;
|
int Ss, Se;
|
||||||
float *accumulated_zero_block_cost = NULL;
|
float *accumulated_zero_block_cost = NULL;
|
||||||
@@ -640,6 +641,9 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc
|
|||||||
int zero_run;
|
int zero_run;
|
||||||
int run_bits;
|
int run_bits;
|
||||||
int rate;
|
int rate;
|
||||||
|
float *accumulated_dc_cost[3];
|
||||||
|
int *dc_cost_backtrack[3];
|
||||||
|
JCOEF *dc_candidate[3];
|
||||||
|
|
||||||
Ss = cinfo->Ss;
|
Ss = cinfo->Ss;
|
||||||
Se = cinfo->Se;
|
Se = cinfo->Se;
|
||||||
@@ -652,11 +656,29 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc
|
|||||||
accumulated_block_cost = (float *)malloc((num_blocks + 1) * sizeof(float));
|
accumulated_block_cost = (float *)malloc((num_blocks + 1) * sizeof(float));
|
||||||
block_run_start = (int *)malloc(num_blocks * sizeof(int));
|
block_run_start = (int *)malloc(num_blocks * sizeof(int));
|
||||||
requires_eob = (int *)malloc((num_blocks + 1) * sizeof(int));
|
requires_eob = (int *)malloc((num_blocks + 1) * sizeof(int));
|
||||||
|
if (!accumulated_zero_block_cost ||
|
||||||
|
!accumulated_block_cost ||
|
||||||
|
!block_run_start ||
|
||||||
|
!requires_eob) {
|
||||||
|
ERREXIT(cinfo, JERR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
|
||||||
accumulated_zero_block_cost[0] = 0;
|
accumulated_zero_block_cost[0] = 0;
|
||||||
accumulated_block_cost[0] = 0;
|
accumulated_block_cost[0] = 0;
|
||||||
requires_eob[0] = 0;
|
requires_eob[0] = 0;
|
||||||
}
|
}
|
||||||
|
if (cinfo->trellis_quant_dc) {
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
accumulated_dc_cost[i] = (float *)malloc(num_blocks * sizeof(float));
|
||||||
|
dc_cost_backtrack[i] = (int *)malloc(num_blocks * sizeof(int));
|
||||||
|
dc_candidate[i] = (JCOEF *)malloc(num_blocks * sizeof(JCOEF));
|
||||||
|
if (!accumulated_dc_cost[i] ||
|
||||||
|
!dc_cost_backtrack[i] ||
|
||||||
|
!dc_candidate[i]) {
|
||||||
|
ERREXIT(cinfo, JERR_OUT_OF_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
norm = 0.0;
|
norm = 0.0;
|
||||||
for (i = 1; i < DCTSIZE2; i++) {
|
for (i = 1; i < DCTSIZE2; i++) {
|
||||||
norm += qtbl->quantval[i] * qtbl->quantval[i];
|
norm += qtbl->quantval[i] * qtbl->quantval[i];
|
||||||
@@ -678,9 +700,65 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc
|
|||||||
else
|
else
|
||||||
lambda = pow(2.0, cinfo->lambda_log_scale1-12.0) * lambda_base;
|
lambda = pow(2.0, cinfo->lambda_log_scale1-12.0) * lambda_base;
|
||||||
|
|
||||||
|
lambda_dc = lambda * lambda_tbl[0];
|
||||||
|
|
||||||
accumulated_zero_dist[Ss-1] = 0.0;
|
accumulated_zero_dist[Ss-1] = 0.0;
|
||||||
accumulated_cost[Ss-1] = 0.0;
|
accumulated_cost[Ss-1] = 0.0;
|
||||||
|
|
||||||
|
// Do DC coefficient
|
||||||
|
if (cinfo->trellis_quant_dc) {
|
||||||
|
int sign = src[bi][0] >> 31;
|
||||||
|
int x = abs(src[bi][0]);
|
||||||
|
int q = 8 * qtbl->quantval[0];
|
||||||
|
int qval;
|
||||||
|
float dc_candidate_dist;
|
||||||
|
|
||||||
|
qval = (x + q/2) / q; /* quantized value (round nearest) */
|
||||||
|
for (k = 0; k < 3; k++) {
|
||||||
|
int delta;
|
||||||
|
int dc_delta;
|
||||||
|
int bits;
|
||||||
|
|
||||||
|
dc_candidate[k][bi] = qval - 1 + k;
|
||||||
|
delta = dc_candidate[k][bi] * q - x;
|
||||||
|
dc_candidate_dist = delta * delta * lambda_dc;
|
||||||
|
dc_candidate[k][bi] *= 1 + 2*sign;
|
||||||
|
|
||||||
|
if (bi == 0) {
|
||||||
|
dc_delta = dc_candidate[k][bi] - *last_dc_val;
|
||||||
|
|
||||||
|
// Derive number of suffix bits
|
||||||
|
bits = 0;
|
||||||
|
dc_delta = abs(dc_delta);
|
||||||
|
while (dc_delta) {
|
||||||
|
dc_delta >>= 1;
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
cost = bits + dctbl->ehufsi[bits] + dc_candidate_dist;
|
||||||
|
accumulated_dc_cost[k][0] = cost;
|
||||||
|
dc_cost_backtrack[k][0] = -1;
|
||||||
|
} else {
|
||||||
|
for (l = 0; l < 3; l++) {
|
||||||
|
dc_delta = dc_candidate[k][bi] - dc_candidate[l][bi-1];
|
||||||
|
|
||||||
|
// Derive number of suffix bits
|
||||||
|
bits = 0;
|
||||||
|
dc_delta = abs(dc_delta);
|
||||||
|
while (dc_delta) {
|
||||||
|
dc_delta >>= 1;
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
cost = bits + dctbl->ehufsi[bits] + dc_candidate_dist + accumulated_dc_cost[l][bi-1];
|
||||||
|
if (l == 0 || cost < accumulated_dc_cost[k][bi]) {
|
||||||
|
accumulated_dc_cost[k][bi] = cost;
|
||||||
|
dc_cost_backtrack[k][bi] = l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do AC coefficients
|
||||||
for (i = Ss; i <= Se; i++) {
|
for (i = Ss; i <= Se; i++) {
|
||||||
int z = jpeg_natural_order[i];
|
int z = jpeg_natural_order[i];
|
||||||
|
|
||||||
@@ -864,6 +942,28 @@ quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_bloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cinfo->trellis_quant_dc) {
|
||||||
|
j = 0;
|
||||||
|
for (i = 1; i < 3; i++) {
|
||||||
|
if (accumulated_dc_cost[i][num_blocks-1] < accumulated_dc_cost[j][num_blocks-1])
|
||||||
|
j = i;
|
||||||
|
}
|
||||||
|
for (bi = num_blocks-1; bi >= 0; bi--) {
|
||||||
|
coef_blocks[bi][0] = dc_candidate[j][bi];
|
||||||
|
j = dc_cost_backtrack[j][bi];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save DC predictor
|
||||||
|
*last_dc_val = coef_blocks[num_blocks-1][0];
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
free(accumulated_dc_cost[i]);
|
||||||
|
free(dc_cost_backtrack[i]);
|
||||||
|
free(dc_candidate[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
4
jchuff.h
4
jchuff.h
@@ -44,5 +44,5 @@ EXTERN(void) jpeg_gen_optimal_table
|
|||||||
(j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]);
|
(j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]);
|
||||||
|
|
||||||
EXTERN(void) quantize_trellis
|
EXTERN(void) quantize_trellis
|
||||||
(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
(j_compress_ptr cinfo, c_derived_tbl *dctbl, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
||||||
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef);
|
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef, JCOEF *last_dc_val);
|
||||||
|
|||||||
174
jcmarker.c
174
jcmarker.c
@@ -183,6 +183,69 @@ emit_dqt (j_compress_ptr cinfo, int index)
|
|||||||
return prec;
|
return prec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCAL(int)
|
||||||
|
emit_multi_dqt (j_compress_ptr cinfo)
|
||||||
|
/* Emits a DQT marker containing all quantization tables */
|
||||||
|
/* Returns number of emitted 16-bit tables, or -1 for failed for baseline checking. */
|
||||||
|
{
|
||||||
|
int prec[MAX_COMPONENTS];
|
||||||
|
int seen[MAX_COMPONENTS] = { 0 };
|
||||||
|
int fin_prec = 0;
|
||||||
|
int ci;
|
||||||
|
|
||||||
|
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||||
|
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
|
||||||
|
int i;
|
||||||
|
JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[tbl_num];
|
||||||
|
|
||||||
|
if (qtbl == NULL || qtbl->sent_table == TRUE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
prec[ci] = 0;
|
||||||
|
for (i = 0; i < DCTSIZE2; i++)
|
||||||
|
prec[ci] = !!(prec[ci] + (qtbl->quantval[i] > 255));
|
||||||
|
|
||||||
|
fin_prec += prec[ci];
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_marker(cinfo, M_DQT);
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||||
|
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
|
||||||
|
|
||||||
|
if (!seen[tbl_num]) {
|
||||||
|
size += DCTSIZE2 * (prec[ci] + 1) + 1;
|
||||||
|
seen[tbl_num] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size += 2;
|
||||||
|
|
||||||
|
emit_2bytes(cinfo, size);
|
||||||
|
|
||||||
|
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||||
|
int tbl_num = cinfo->comp_info[ci].quant_tbl_no;
|
||||||
|
int i;
|
||||||
|
JQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[tbl_num];
|
||||||
|
|
||||||
|
if (qtbl->sent_table == TRUE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
emit_byte(cinfo, tbl_num + (prec[ci] << 4));
|
||||||
|
|
||||||
|
for (i = 0; i < DCTSIZE2; i++) {
|
||||||
|
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
|
||||||
|
|
||||||
|
if (prec[ci])
|
||||||
|
emit_byte(cinfo, (int) (qval >> 8));
|
||||||
|
emit_byte(cinfo, (int) (qval & 0xFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
qtbl->sent_table = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fin_prec;
|
||||||
|
}
|
||||||
|
|
||||||
LOCAL(void)
|
LOCAL(void)
|
||||||
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
|
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
|
||||||
@@ -221,6 +284,112 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOCAL(boolean)
|
||||||
|
emit_multi_dht (j_compress_ptr cinfo)
|
||||||
|
/* Emit all DHT markers */
|
||||||
|
/* Returns FALSE on failure, TRUE otherwise. */
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int length = 2;
|
||||||
|
int dclens[NUM_HUFF_TBLS] = { 0 };
|
||||||
|
int aclens[NUM_HUFF_TBLS] = { 0 };
|
||||||
|
JHUFF_TBL *dcseen[NUM_HUFF_TBLS] = { NULL };
|
||||||
|
JHUFF_TBL *acseen[NUM_HUFF_TBLS] = { NULL };
|
||||||
|
|
||||||
|
/* Calclate the total length. */
|
||||||
|
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||||
|
jpeg_component_info *compptr = cinfo->cur_comp_info[i];
|
||||||
|
int dcidx = compptr->dc_tbl_no;
|
||||||
|
int acidx = compptr->ac_tbl_no;
|
||||||
|
JHUFF_TBL *dctbl = cinfo->dc_huff_tbl_ptrs[dcidx];
|
||||||
|
JHUFF_TBL *actbl = cinfo->ac_huff_tbl_ptrs[acidx];
|
||||||
|
int seen = 0;
|
||||||
|
|
||||||
|
/* Handle DC table lenghts */
|
||||||
|
if (cinfo->Ss == 0 && cinfo->Ah == 0) {
|
||||||
|
if (dctbl == NULL)
|
||||||
|
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dcidx);
|
||||||
|
|
||||||
|
if (dctbl->sent_table)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (j = 0; j < NUM_HUFF_TBLS; j++)
|
||||||
|
seen += (dctbl == dcseen[j]);
|
||||||
|
if (seen)
|
||||||
|
continue;
|
||||||
|
dcseen[i] = dctbl;
|
||||||
|
|
||||||
|
for (j = 1; j <= 16; j++)
|
||||||
|
dclens[i] += dctbl->bits[j];
|
||||||
|
length += dclens[i] + 16 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle AC table lengths */
|
||||||
|
if (cinfo->Se) {
|
||||||
|
if (actbl == NULL)
|
||||||
|
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, acidx + 0x10);
|
||||||
|
|
||||||
|
if (actbl->sent_table)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
seen = 0;
|
||||||
|
for (j = 0; j < NUM_HUFF_TBLS; j++)
|
||||||
|
seen += (actbl == acseen[j]);
|
||||||
|
if (seen)
|
||||||
|
continue;
|
||||||
|
acseen[i] = actbl;
|
||||||
|
|
||||||
|
for (j = 1; j <= 16; j++)
|
||||||
|
aclens[i] += actbl->bits[j];
|
||||||
|
length += aclens[i] + 16 + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we can fit it all into one DHT marker */
|
||||||
|
if (length > (1 << 16) - 1)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
emit_marker(cinfo, M_DHT);
|
||||||
|
emit_2bytes(cinfo, length);
|
||||||
|
|
||||||
|
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||||
|
jpeg_component_info *compptr = cinfo->cur_comp_info[i];
|
||||||
|
int dcidx = compptr->dc_tbl_no;
|
||||||
|
int acidx = compptr->ac_tbl_no;
|
||||||
|
JHUFF_TBL *dctbl = cinfo->dc_huff_tbl_ptrs[dcidx];
|
||||||
|
JHUFF_TBL *actbl = cinfo->ac_huff_tbl_ptrs[acidx];
|
||||||
|
|
||||||
|
acidx += 0x10;
|
||||||
|
|
||||||
|
/* DC */
|
||||||
|
if (cinfo->Ss == 0 && cinfo->Ah == 0 && !dctbl->sent_table) {
|
||||||
|
emit_byte(cinfo, dcidx);
|
||||||
|
|
||||||
|
for (j = 1; j <= 16; j++)
|
||||||
|
emit_byte(cinfo, dctbl->bits[j]);
|
||||||
|
|
||||||
|
for (j = 0; j < dclens[i]; j++)
|
||||||
|
emit_byte(cinfo, dctbl->huffval[j]);
|
||||||
|
|
||||||
|
dctbl->sent_table = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cinfo->Se && !actbl->sent_table) {
|
||||||
|
emit_byte(cinfo, acidx);
|
||||||
|
|
||||||
|
for (j = 1; j <= 16; j++)
|
||||||
|
emit_byte(cinfo, actbl->bits[j]);
|
||||||
|
|
||||||
|
for (j = 0; j < aclens[i]; j++)
|
||||||
|
emit_byte(cinfo, actbl->huffval[j]);
|
||||||
|
|
||||||
|
actbl->sent_table = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
LOCAL(void)
|
LOCAL(void)
|
||||||
emit_dac (j_compress_ptr cinfo)
|
emit_dac (j_compress_ptr cinfo)
|
||||||
@@ -504,11 +673,14 @@ write_frame_header (j_compress_ptr cinfo)
|
|||||||
/* Emit DQT for each quantization table.
|
/* Emit DQT for each quantization table.
|
||||||
* Note that emit_dqt() suppresses any duplicate tables.
|
* Note that emit_dqt() suppresses any duplicate tables.
|
||||||
*/
|
*/
|
||||||
|
prec = emit_multi_dqt(cinfo);
|
||||||
|
if (prec == -1) {
|
||||||
prec = 0;
|
prec = 0;
|
||||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||||
ci++, compptr++) {
|
ci++, compptr++) {
|
||||||
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* now prec is nonzero iff there are any 16-bit quant tables. */
|
/* now prec is nonzero iff there are any 16-bit quant tables. */
|
||||||
|
|
||||||
/* Check for a non-baseline specification.
|
/* Check for a non-baseline specification.
|
||||||
@@ -571,6 +743,7 @@ write_scan_header (j_compress_ptr cinfo)
|
|||||||
/* Emit Huffman tables.
|
/* Emit Huffman tables.
|
||||||
* Note that emit_dht() suppresses any duplicate tables.
|
* Note that emit_dht() suppresses any duplicate tables.
|
||||||
*/
|
*/
|
||||||
|
if (!emit_multi_dht(cinfo)) {
|
||||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||||
compptr = cinfo->cur_comp_info[i];
|
compptr = cinfo->cur_comp_info[i];
|
||||||
/* DC needs no table for refinement scan */
|
/* DC needs no table for refinement scan */
|
||||||
@@ -581,6 +754,7 @@ write_scan_header (j_compress_ptr cinfo)
|
|||||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Emit DRI if required --- note that DRI value could change for each scan.
|
/* Emit DRI if required --- note that DRI value could change for each scan.
|
||||||
* We avoid wasting space with unnecessary DRIs, however.
|
* We avoid wasting space with unnecessary DRIs, however.
|
||||||
|
|||||||
19
jcmaster.c
19
jcmaster.c
@@ -45,6 +45,7 @@ typedef struct {
|
|||||||
int pass_number_scan_opt_base; /* pass number where scan optimization begins */
|
int pass_number_scan_opt_base; /* pass number where scan optimization begins */
|
||||||
unsigned char * scan_buffer[64]; /* buffer for a given scan */
|
unsigned char * scan_buffer[64]; /* buffer for a given scan */
|
||||||
unsigned long scan_size[64]; /* size for a given scan */
|
unsigned long scan_size[64]; /* size for a given scan */
|
||||||
|
int actual_Al[64]; /* actual value of Al used for a scan */
|
||||||
unsigned long best_cost; /* bit count for best frequency split */
|
unsigned long best_cost; /* bit count for best frequency split */
|
||||||
int best_freq_split_idx_luma; /* index for best frequency split (luma) */
|
int best_freq_split_idx_luma; /* index for best frequency split (luma) */
|
||||||
int best_freq_split_idx_chroma; /* index for best frequency split (chroma) */
|
int best_freq_split_idx_chroma; /* index for best frequency split (chroma) */
|
||||||
@@ -364,6 +365,8 @@ select_scan_parameters (j_compress_ptr cinfo)
|
|||||||
master->scan_number < cinfo->num_scans)
|
master->scan_number < cinfo->num_scans)
|
||||||
cinfo->Al = master->best_Al_chroma;
|
cinfo->Al = master->best_Al_chroma;
|
||||||
}
|
}
|
||||||
|
/* save value for later retrieval during printout of scans */
|
||||||
|
master->actual_Al[master->scan_number] = cinfo->Al;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
@@ -613,7 +616,7 @@ copy_buffer (j_compress_ptr cinfo, int scan_idx)
|
|||||||
for (i = 0; i < cinfo->scan_info[scan_idx].comps_in_scan; i++)
|
for (i = 0; i < cinfo->scan_info[scan_idx].comps_in_scan; i++)
|
||||||
fprintf(stderr, "%s%d", (i==0)?"":",", cinfo->scan_info[scan_idx].component_index[i]);
|
fprintf(stderr, "%s%d", (i==0)?"":",", cinfo->scan_info[scan_idx].component_index[i]);
|
||||||
fprintf(stderr, ": %d %d", cinfo->scan_info[scan_idx].Ss, cinfo->scan_info[scan_idx].Se);
|
fprintf(stderr, ": %d %d", cinfo->scan_info[scan_idx].Ss, cinfo->scan_info[scan_idx].Se);
|
||||||
fprintf(stderr, " %d %d", cinfo->scan_info[scan_idx].Ah, cinfo->scan_info[scan_idx].Al);
|
fprintf(stderr, " %d %d", cinfo->scan_info[scan_idx].Ah, master->actual_Al[scan_idx]);
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -757,7 +760,7 @@ select_scans (j_compress_ptr cinfo, int next_scan_number)
|
|||||||
if (cinfo->num_scans > cinfo->num_scans_luma && !cinfo->one_dc_scan) {
|
if (cinfo->num_scans > cinfo->num_scans_luma && !cinfo->one_dc_scan) {
|
||||||
base_scan_idx = cinfo->num_scans_luma;
|
base_scan_idx = cinfo->num_scans_luma;
|
||||||
|
|
||||||
if (master->interleave_chroma_dc)
|
if (master->interleave_chroma_dc && !cinfo->sep_dc_scan)
|
||||||
copy_buffer(cinfo, base_scan_idx);
|
copy_buffer(cinfo, base_scan_idx);
|
||||||
else {
|
else {
|
||||||
copy_buffer(cinfo, base_scan_idx+1);
|
copy_buffer(cinfo, base_scan_idx+1);
|
||||||
@@ -933,8 +936,11 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
|||||||
else
|
else
|
||||||
master->total_passes = cinfo->num_scans;
|
master->total_passes = cinfo->num_scans;
|
||||||
|
|
||||||
if (cinfo->trellis_quant)
|
master->pass_number_scan_opt_base = 0;
|
||||||
master->total_passes += ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
|
if (cinfo->trellis_quant) {
|
||||||
|
master->pass_number_scan_opt_base = ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
|
||||||
|
master->total_passes += master->pass_number_scan_opt_base;
|
||||||
|
}
|
||||||
|
|
||||||
if (cinfo->optimize_scans) {
|
if (cinfo->optimize_scans) {
|
||||||
int i;
|
int i;
|
||||||
@@ -943,9 +949,4 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
|||||||
for (i = 0; i < cinfo->num_scans; i++)
|
for (i = 0; i < cinfo->num_scans; i++)
|
||||||
master->scan_buffer[i] = NULL;
|
master->scan_buffer[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cinfo->trellis_quant)
|
|
||||||
master->pass_number_scan_opt_base = ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
|
|
||||||
else
|
|
||||||
master->pass_number_scan_opt_base = 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ typedef unsigned char boolean;
|
|||||||
|
|
||||||
/* These defines indicate which image (non-JPEG) file formats are allowed. */
|
/* These defines indicate which image (non-JPEG) file formats are allowed. */
|
||||||
|
|
||||||
|
#define PNG_SUPPORTED /* PNG image file format */
|
||||||
#define BMP_SUPPORTED /* BMP image file format */
|
#define BMP_SUPPORTED /* BMP image file format */
|
||||||
#define GIF_SUPPORTED /* GIF image file format */
|
#define GIF_SUPPORTED /* GIF image file format */
|
||||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||||
|
|||||||
22
jcparam.c
22
jcparam.c
@@ -152,14 +152,20 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
|
|||||||
|
|
||||||
GLOBAL(int)
|
GLOBAL(int)
|
||||||
jpeg_quality_scaling (int quality)
|
jpeg_quality_scaling (int quality)
|
||||||
|
{
|
||||||
|
return jpeg_float_quality_scaling(quality);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLOBAL(float)
|
||||||
|
jpeg_float_quality_scaling(float quality)
|
||||||
/* Convert a user-specified quality rating to a percentage scaling factor
|
/* Convert a user-specified quality rating to a percentage scaling factor
|
||||||
* for an underlying quantization table, using our recommended scaling curve.
|
* for an underlying quantization table, using our recommended scaling curve.
|
||||||
* The input 'quality' factor should be 0 (terrible) to 100 (very good).
|
* The input 'quality' factor should be 0 (terrible) to 100 (very good).
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
|
/* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
|
||||||
if (quality <= 0) quality = 1;
|
if (quality <= 0.f) quality = 1.f;
|
||||||
if (quality > 100) quality = 100;
|
if (quality > 100.f) quality = 100.f;
|
||||||
|
|
||||||
/* The basic table is used as-is (scaling 100) for a quality of 50.
|
/* The basic table is used as-is (scaling 100) for a quality of 50.
|
||||||
* Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
|
* Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
|
||||||
@@ -167,10 +173,10 @@ jpeg_quality_scaling (int quality)
|
|||||||
* to make all the table entries 1 (hence, minimum quantization loss).
|
* to make all the table entries 1 (hence, minimum quantization loss).
|
||||||
* Qualities 1..50 are converted to scaling percentage 5000/Q.
|
* Qualities 1..50 are converted to scaling percentage 5000/Q.
|
||||||
*/
|
*/
|
||||||
if (quality < 50)
|
if (quality < 50.f)
|
||||||
quality = 5000 / quality;
|
quality = 5000.f / quality;
|
||||||
else
|
else
|
||||||
quality = 200 - quality*2;
|
quality = 200.f - quality*2.f;
|
||||||
|
|
||||||
return quality;
|
return quality;
|
||||||
}
|
}
|
||||||
@@ -335,6 +341,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
|||||||
cinfo->trellis_freq_split = 8;
|
cinfo->trellis_freq_split = 8;
|
||||||
cinfo->trellis_num_loops = 1;
|
cinfo->trellis_num_loops = 1;
|
||||||
cinfo->trellis_q_opt = FALSE;
|
cinfo->trellis_q_opt = FALSE;
|
||||||
|
cinfo->trellis_quant_dc = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -730,6 +737,11 @@ jpeg_simple_progression (j_compress_ptr cinfo)
|
|||||||
/* Initial DC scan */
|
/* Initial DC scan */
|
||||||
if (cinfo->one_dc_scan)
|
if (cinfo->one_dc_scan)
|
||||||
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
|
scanptr = fill_dc_scans(scanptr, ncomps, 0, 0);
|
||||||
|
else if (cinfo->sep_dc_scan) {
|
||||||
|
scanptr = fill_a_scan(scanptr, 0, 0, 0, 0, 0);
|
||||||
|
scanptr = fill_a_scan(scanptr, 1, 0, 0, 0, 0);
|
||||||
|
scanptr = fill_a_scan(scanptr, 2, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
|
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
|
||||||
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
|
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
|
||||||
|
|||||||
@@ -377,7 +377,9 @@ struct jpeg_compress_struct {
|
|||||||
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
|
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
|
||||||
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
|
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
|
||||||
boolean one_dc_scan; /* TRUE=use a single DC scan interleaving all components */
|
boolean one_dc_scan; /* TRUE=use a single DC scan interleaving all components */
|
||||||
|
boolean sep_dc_scan; /* TRUE=each DC scan is separate */
|
||||||
boolean trellis_quant; /* TRUE=use trellis quantization */
|
boolean trellis_quant; /* TRUE=use trellis quantization */
|
||||||
|
boolean trellis_quant_dc; /* TRUE=use trellis quant for DC coefficient */
|
||||||
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
|
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
|
||||||
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
|
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
|
||||||
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
|
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
|
||||||
@@ -960,6 +962,7 @@ EXTERN(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
|
|||||||
const unsigned int *basic_table,
|
const unsigned int *basic_table,
|
||||||
int scale_factor, boolean force_baseline);
|
int scale_factor, boolean force_baseline);
|
||||||
EXTERN(int) jpeg_quality_scaling (int quality);
|
EXTERN(int) jpeg_quality_scaling (int quality);
|
||||||
|
EXTERN(float) jpeg_float_quality_scaling (float quality);
|
||||||
EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo);
|
EXTERN(void) jpeg_simple_progression (j_compress_ptr cinfo);
|
||||||
EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress);
|
EXTERN(void) jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress);
|
||||||
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo);
|
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo);
|
||||||
|
|||||||
@@ -104,11 +104,19 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
|
yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
|
||||||
yuv_buffer = malloc(yuv_size);
|
yuv_buffer = malloc(yuv_size);
|
||||||
|
if (!yuv_buffer) {
|
||||||
|
fprintf(stderr, "Memory allocation failure!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
frame_width = (cinfo.output_width + (16 - 1)) & ~(16 - 1);
|
frame_width = (cinfo.output_width + (16 - 1)) & ~(16 - 1);
|
||||||
frame_height = (cinfo.output_height + (16 - 1)) & ~(16 - 1);
|
frame_height = (cinfo.output_height + (16 - 1)) & ~(16 - 1);
|
||||||
|
|
||||||
image_buffer = malloc(frame_width*16 + 2*(frame_width/2)*8);
|
image_buffer = malloc(frame_width*16 + 2*(frame_width/2)*8);
|
||||||
|
if (!image_buffer) {
|
||||||
|
fprintf(stderr, "Memory allocation failure!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
plane_pointer[0] = yrow_pointer;
|
plane_pointer[0] = yrow_pointer;
|
||||||
plane_pointer[1] = cbrow_pointer;
|
plane_pointer[1] = cbrow_pointer;
|
||||||
|
|||||||
116
rdpng.c
Normal file
116
rdpng.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
|
||||||
|
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
|
||||||
|
|
||||||
|
#ifdef PNG_SUPPORTED
|
||||||
|
|
||||||
|
#include <png.h> /* if this fails, you need to install libpng-devel */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct png_source_struct {
|
||||||
|
struct cjpeg_source_struct pub;
|
||||||
|
png_structp png_ptr;
|
||||||
|
png_infop info_ptr;
|
||||||
|
JDIMENSION current_row;
|
||||||
|
} png_source_struct;
|
||||||
|
|
||||||
|
|
||||||
|
METHODDEF(void)
|
||||||
|
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
|
||||||
|
|
||||||
|
METHODDEF(JDIMENSION)
|
||||||
|
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
|
||||||
|
|
||||||
|
METHODDEF(void)
|
||||||
|
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
|
||||||
|
|
||||||
|
|
||||||
|
GLOBAL(cjpeg_source_ptr)
|
||||||
|
jinit_read_png(j_compress_ptr cinfo)
|
||||||
|
{
|
||||||
|
png_source_struct *source = (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE, sizeof(png_source_struct));
|
||||||
|
|
||||||
|
memset(source, 0, sizeof(*source));
|
||||||
|
|
||||||
|
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
|
||||||
|
source->pub.start_input = start_input_png;
|
||||||
|
source->pub.finish_input = finish_input_png;
|
||||||
|
|
||||||
|
return &source->pub;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHODDEF(void) error_input_png(png_structp png_ptr, png_const_charp msg) {
|
||||||
|
j_compress_ptr cinfo = png_get_error_ptr(png_ptr);
|
||||||
|
ERREXITS(cinfo, JERR_PNG_ERROR, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHODDEF(void)
|
||||||
|
start_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||||
|
{
|
||||||
|
png_source_struct *source = (png_source_struct *)sinfo;
|
||||||
|
|
||||||
|
source->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, cinfo, error_input_png, NULL);
|
||||||
|
source->info_ptr = png_create_info_struct(source->png_ptr);
|
||||||
|
|
||||||
|
if (!source->png_ptr || !source->info_ptr) {
|
||||||
|
ERREXITS(cinfo, JERR_PNG_ERROR, "Can't create read/info_struct");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
png_set_palette_to_rgb(source->png_ptr);
|
||||||
|
png_set_expand_gray_1_2_4_to_8(source->png_ptr);
|
||||||
|
png_set_strip_alpha(source->png_ptr);
|
||||||
|
png_set_interlace_handling(source->png_ptr);
|
||||||
|
|
||||||
|
png_init_io(source->png_ptr, source->pub.input_file);
|
||||||
|
png_read_info(source->png_ptr, source->info_ptr);
|
||||||
|
|
||||||
|
png_uint_32 width, height;
|
||||||
|
int bit_depth, color_type;
|
||||||
|
png_get_IHDR(source->png_ptr, source->info_ptr, &width, &height,
|
||||||
|
&bit_depth, &color_type, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (color_type == PNG_COLOR_TYPE_GRAY) {
|
||||||
|
cinfo->in_color_space = JCS_GRAYSCALE;
|
||||||
|
cinfo->input_components = 1;
|
||||||
|
} else {
|
||||||
|
cinfo->in_color_space = JCS_RGB;
|
||||||
|
cinfo->input_components = 3;
|
||||||
|
}
|
||||||
|
cinfo->data_precision = 8;
|
||||||
|
cinfo->image_width = width;
|
||||||
|
cinfo->image_height = height;
|
||||||
|
|
||||||
|
double gamma = 0.45455;
|
||||||
|
if (!png_get_valid(source->png_ptr, source->info_ptr, PNG_INFO_sRGB)) {
|
||||||
|
png_get_gAMA(source->png_ptr, source->info_ptr, &gamma);
|
||||||
|
}
|
||||||
|
cinfo->input_gamma = gamma;
|
||||||
|
sinfo->get_pixel_rows = get_pixel_rows_png;
|
||||||
|
|
||||||
|
png_read_update_info(source->png_ptr, source->info_ptr);
|
||||||
|
|
||||||
|
png_size_t rowbytes = png_get_rowbytes(source->png_ptr, source->info_ptr);
|
||||||
|
|
||||||
|
source->pub.buffer = (*cinfo->mem->alloc_sarray)((j_common_ptr)cinfo, JPOOL_IMAGE, (JDIMENSION)rowbytes, 1);
|
||||||
|
source->pub.buffer_height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHODDEF(JDIMENSION)
|
||||||
|
get_pixel_rows_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||||
|
{
|
||||||
|
png_source_struct *source = (png_source_struct *)sinfo;
|
||||||
|
|
||||||
|
png_read_row(source->png_ptr, source->pub.buffer[0], NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHODDEF(void)
|
||||||
|
finish_input_png (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
|
||||||
|
{
|
||||||
|
png_source_struct *source = (png_source_struct *)sinfo;
|
||||||
|
|
||||||
|
png_read_end(source->png_ptr, source->info_ptr);
|
||||||
|
png_destroy_read_struct(&source->png_ptr, &source->info_ptr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
12
rdswitch.c
12
rdswitch.c
@@ -336,31 +336,31 @@ set_quality_ratings (j_compress_ptr cinfo, char *arg, boolean force_baseline)
|
|||||||
* If there are more q-table slots than parameters, the last value is replicated.
|
* If there are more q-table slots than parameters, the last value is replicated.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int val = 75; /* default value */
|
float val = 75.f; /* default value */
|
||||||
int tblno;
|
int tblno;
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
||||||
if (*arg) {
|
if (*arg) {
|
||||||
ch = ','; /* if not set by sscanf, will be ',' */
|
ch = ','; /* if not set by sscanf, will be ',' */
|
||||||
if (sscanf(arg, "%d%c", &val, &ch) < 1)
|
if (sscanf(arg, "%f%c", &val, &ch) < 1)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (ch != ',') /* syntax check */
|
if (ch != ',') /* syntax check */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
/* Convert user 0-100 rating to percentage scaling */
|
/* Convert user 0-100 rating to percentage scaling */
|
||||||
#if JPEG_LIB_VERSION >= 70
|
#if JPEG_LIB_VERSION >= 70
|
||||||
cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
cinfo->q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||||
#else
|
#else
|
||||||
q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||||
#endif
|
#endif
|
||||||
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
||||||
;
|
;
|
||||||
} else {
|
} else {
|
||||||
/* reached end of parameter, set remaining factors to last value */
|
/* reached end of parameter, set remaining factors to last value */
|
||||||
#if JPEG_LIB_VERSION >= 70
|
#if JPEG_LIB_VERSION >= 70
|
||||||
cinfo->q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
cinfo->q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||||
#else
|
#else
|
||||||
q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,11 +41,9 @@
|
|||||||
/* Supplementary macro for setting function attributes */
|
/* Supplementary macro for setting function attributes */
|
||||||
.macro asm_function fname
|
.macro asm_function fname
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
.func _\fname
|
|
||||||
.globl _\fname
|
.globl _\fname
|
||||||
_\fname:
|
_\fname:
|
||||||
#else
|
#else
|
||||||
.func \fname
|
|
||||||
.global \fname
|
.global \fname
|
||||||
#ifdef __ELF__
|
#ifdef __ELF__
|
||||||
.hidden \fname
|
.hidden \fname
|
||||||
@@ -670,7 +668,6 @@ asm_function jsimd_idct_islow_neon
|
|||||||
.unreq ROW6R
|
.unreq ROW6R
|
||||||
.unreq ROW7L
|
.unreq ROW7L
|
||||||
.unreq ROW7R
|
.unreq ROW7R
|
||||||
.endfunc
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -895,7 +892,6 @@ asm_function jsimd_idct_ifast_neon
|
|||||||
.unreq TMP2
|
.unreq TMP2
|
||||||
.unreq TMP3
|
.unreq TMP3
|
||||||
.unreq TMP4
|
.unreq TMP4
|
||||||
.endfunc
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -1108,7 +1104,6 @@ asm_function jsimd_idct_4x4_neon
|
|||||||
.unreq TMP2
|
.unreq TMP2
|
||||||
.unreq TMP3
|
.unreq TMP3
|
||||||
.unreq TMP4
|
.unreq TMP4
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.purgem idct_helper
|
.purgem idct_helper
|
||||||
|
|
||||||
@@ -1263,7 +1258,6 @@ asm_function jsimd_idct_2x2_neon
|
|||||||
.unreq OUTPUT_COL
|
.unreq OUTPUT_COL
|
||||||
.unreq TMP1
|
.unreq TMP1
|
||||||
.unreq TMP2
|
.unreq TMP2
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.purgem idct_helper
|
.purgem idct_helper
|
||||||
|
|
||||||
@@ -1547,7 +1541,6 @@ asm_function jsimd_ycc_\colorid\()_convert_neon
|
|||||||
.unreq U
|
.unreq U
|
||||||
.unreq V
|
.unreq V
|
||||||
.unreq N
|
.unreq N
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.purgem do_yuv_to_rgb
|
.purgem do_yuv_to_rgb
|
||||||
.purgem do_yuv_to_rgb_stage1
|
.purgem do_yuv_to_rgb_stage1
|
||||||
@@ -1858,7 +1851,6 @@ asm_function jsimd_\colorid\()_ycc_convert_neon
|
|||||||
.unreq U
|
.unreq U
|
||||||
.unreq V
|
.unreq V
|
||||||
.unreq N
|
.unreq N
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.purgem do_rgb_to_yuv
|
.purgem do_rgb_to_yuv
|
||||||
.purgem do_rgb_to_yuv_stage1
|
.purgem do_rgb_to_yuv_stage1
|
||||||
@@ -1940,7 +1932,6 @@ asm_function jsimd_convsamp_neon
|
|||||||
.unreq TMP2
|
.unreq TMP2
|
||||||
.unreq TMP3
|
.unreq TMP3
|
||||||
.unreq TMP4
|
.unreq TMP4
|
||||||
.endfunc
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2064,7 +2055,6 @@ asm_function jsimd_fdct_ifast_neon
|
|||||||
|
|
||||||
.unreq DATA
|
.unreq DATA
|
||||||
.unreq TMP
|
.unreq TMP
|
||||||
.endfunc
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2166,7 +2156,6 @@ asm_function jsimd_quantize_neon
|
|||||||
.unreq CORRECTION
|
.unreq CORRECTION
|
||||||
.unreq SHIFT
|
.unreq SHIFT
|
||||||
.unreq LOOP_COUNT
|
.unreq LOOP_COUNT
|
||||||
.endfunc
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -2401,7 +2390,6 @@ asm_function jsimd_h2v1_fancy_upsample_neon
|
|||||||
.unreq WIDTH
|
.unreq WIDTH
|
||||||
.unreq TMP
|
.unreq TMP
|
||||||
|
|
||||||
.endfunc
|
|
||||||
|
|
||||||
.purgem upsample16
|
.purgem upsample16
|
||||||
.purgem upsample32
|
.purgem upsample32
|
||||||
|
|||||||
10
yuvjpeg.c
10
yuvjpeg.c
@@ -179,6 +179,11 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
yuv_buffer = malloc(yuv_size);
|
yuv_buffer = malloc(yuv_size);
|
||||||
|
if (!yuv_buffer) {
|
||||||
|
fprintf(stderr, "Memory allocation failure!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (fread(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
|
if (fread(yuv_buffer, yuv_size, 1, yuv_fd) != 1) {
|
||||||
fprintf(stderr, "Error reading yuv file\n");
|
fprintf(stderr, "Error reading yuv file\n");
|
||||||
};
|
};
|
||||||
@@ -190,6 +195,10 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
image_buffer =
|
image_buffer =
|
||||||
malloc(frame_width*frame_height + 2*(frame_width/2)*(frame_height/2));
|
malloc(frame_width*frame_height + 2*(frame_width/2)*(frame_height/2));
|
||||||
|
if (!image_buffer) {
|
||||||
|
fprintf(stderr, "Memory allocation failure!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
extend_edge(image_buffer, frame_width, frame_height,
|
extend_edge(image_buffer, frame_width, frame_height,
|
||||||
yuv_buffer, luma_width, luma_height, chroma_width, chroma_height);
|
yuv_buffer, luma_width, luma_height, chroma_width, chroma_height);
|
||||||
@@ -202,6 +211,7 @@ int main(int argc, char *argv[]) {
|
|||||||
jpg_fd = fopen(jpg_path, "wb");
|
jpg_fd = fopen(jpg_path, "wb");
|
||||||
if (!jpg_fd) {
|
if (!jpg_fd) {
|
||||||
fprintf(stderr, "Invalid path to JPEG file!\n");
|
fprintf(stderr, "Invalid path to JPEG file!\n");
|
||||||
|
free(image_buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user