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.
|
||||
|
||||
|
||||
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
|
||||
---------------------------
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ if(POLICY CMP0022)
|
||||
endif()
|
||||
|
||||
project(libmozjpeg C)
|
||||
set(VERSION 2.0.1)
|
||||
set(VERSION 2.1)
|
||||
|
||||
if(CYGWIN OR NOT CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
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 \
|
||||
-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 \
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
JMSG_LASTADDONCODE
|
||||
|
||||
27
cdjpeg.h
27
cdjpeg.h
@@ -13,12 +13,12 @@
|
||||
* cjpeg and djpeg. It is NOT used by the core JPEG library.
|
||||
*/
|
||||
|
||||
#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */
|
||||
#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */
|
||||
#define JPEG_CJPEG_DJPEG /* define proper options in jconfig.h */
|
||||
#define JPEG_INTERNAL_OPTIONS /* cjpeg.c,djpeg.c need to see xxx_SUPPORTED */
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h" /* get library error codes too */
|
||||
#include "cderror.h" /* get application-specific error codes */
|
||||
#include "jerror.h" /* get library error codes too */
|
||||
#include "cderror.h" /* get application-specific error codes */
|
||||
|
||||
#define JPEG_RAW_READER 0
|
||||
|
||||
@@ -85,9 +85,9 @@ struct djpeg_dest_struct {
|
||||
*/
|
||||
|
||||
struct cdjpeg_progress_mgr {
|
||||
struct jpeg_progress_mgr pub; /* fields known to JPEG library */
|
||||
int completed_extra_passes; /* extra passes completed */
|
||||
int total_extra_passes; /* total extra */
|
||||
struct jpeg_progress_mgr pub; /* fields known to JPEG library */
|
||||
int completed_extra_passes; /* extra passes completed */
|
||||
int total_extra_passes; /* total extra */
|
||||
/* last printed percentage stored here to avoid multiple printouts */
|
||||
int percent_done;
|
||||
};
|
||||
@@ -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(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_png (j_compress_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(djpeg_dest_ptr) jinit_write_rle (j_decompress_ptr cinfo);
|
||||
@@ -136,15 +137,15 @@ EXTERN(FILE *) write_stdout (void);
|
||||
|
||||
/* miscellaneous useful macros */
|
||||
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#define WRITE_BINARY "w"
|
||||
#ifdef DONT_USE_B_MODE /* define mode parameters for fopen() */
|
||||
#define READ_BINARY "r"
|
||||
#define WRITE_BINARY "w"
|
||||
#else
|
||||
#define READ_BINARY "rb"
|
||||
#define WRITE_BINARY "wb"
|
||||
#define READ_BINARY "rb"
|
||||
#define WRITE_BINARY "wb"
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
|
||||
#ifndef EXIT_FAILURE /* define exit() codes if not provided */
|
||||
#define EXIT_FAILURE 1
|
||||
#endif
|
||||
#ifndef EXIT_SUCCESS
|
||||
|
||||
29
cjpeg.c
29
cjpeg.c
@@ -113,6 +113,10 @@ select_file_type (j_compress_ptr cinfo, FILE * infile)
|
||||
case 'P':
|
||||
return jinit_read_ppm(cinfo);
|
||||
#endif
|
||||
#ifdef PNG_SUPPORTED
|
||||
case 0x89:
|
||||
return jinit_read_png(cinfo);
|
||||
#endif
|
||||
#ifdef RLE_SUPPORTED
|
||||
case 'R':
|
||||
return jinit_read_rle(cinfo);
|
||||
@@ -168,13 +172,17 @@ usage (void)
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
fprintf(stderr, " -progressive Create progressive JPEG file (enabled by default)\n");
|
||||
#endif
|
||||
fprintf(stderr, " -baseline Create baseline JPEG file (disable progressive coding)\n");
|
||||
#ifdef TARGA_SUPPORTED
|
||||
fprintf(stderr, " -targa Input file is Targa format (usually not needed)\n");
|
||||
#endif
|
||||
fprintf(stderr, " -revert Revert to standard defaults (instead of mozjpeg defaults)\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, " -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-hvs-psnr Tune trellis optimization for PSNR-HVS (default)\n");
|
||||
fprintf(stderr, " -tune-ssim Tune trellis optimization for SSIM\n");
|
||||
@@ -206,7 +214,6 @@ usage (void)
|
||||
#endif
|
||||
fprintf(stderr, " -verbose or -debug Emit debug output\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, " -qslots N[,...] Set component quantization tables\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)) {
|
||||
/* Force baseline-compatible output (8-bit quantizer values). */
|
||||
force_baseline = TRUE;
|
||||
/* Disable multiple scans */
|
||||
simple_progressive = FALSE;
|
||||
cinfo->num_scans = 0;
|
||||
cinfo->scan_info = NULL;
|
||||
|
||||
} else if (keymatch(arg, "dct", 2)) {
|
||||
/* Select DCT algorithm. */
|
||||
@@ -349,7 +360,7 @@ parse_switches (j_compress_ptr cinfo, int argc, char **argv,
|
||||
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;
|
||||
|
||||
} 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();
|
||||
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)) {
|
||||
/* Input file is Targa format. */
|
||||
is_targa = TRUE;
|
||||
|
||||
} else if (keymatch(arg, "notrellis-dc", 11)) {
|
||||
/* disable trellis quantization */
|
||||
cinfo->trellis_quant_dc = FALSE;
|
||||
|
||||
} else if (keymatch(arg, "notrellis", 1)) {
|
||||
/* disable trellis quantization */
|
||||
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)) {
|
||||
cinfo->use_flat_quant_tbl = TRUE;
|
||||
cinfo->lambda_log_scale1 = 9.0;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.56])
|
||||
AC_INIT([libmozjpeg], [2.0.1])
|
||||
AC_INIT([libmozjpeg], [2.1])
|
||||
BUILD=`date +%Y%m%d`
|
||||
|
||||
AM_INIT_AUTOMAKE([-Wall foreign dist-bzip2])
|
||||
@@ -93,6 +93,11 @@ fi
|
||||
# Checks for libraries.
|
||||
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.
|
||||
AC_HEADER_STDC
|
||||
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; }
|
||||
int bar() { return foo();], ljt_cv_inline="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
|
||||
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;
|
||||
|
||||
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 = &actbl_data;
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
if (ndummy > 0)
|
||||
ndummy = h_samp_factor - ndummy;
|
||||
|
||||
lastDC = 0;
|
||||
|
||||
/* Perform DCT for all non-dummy blocks in this iMCU row. Each call
|
||||
* on forward_DCT processes a complete horizontal row of DCT blocks.
|
||||
*/
|
||||
for (block_row = 0; block_row < block_rows; 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) {
|
||||
/* Create dummy blocks at the right edge of the image. */
|
||||
|
||||
260
jcdctmgr.c
260
jcdctmgr.c
@@ -20,7 +20,7 @@
|
||||
#define JPEG_INTERNALS
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
#include "jdct.h" /* Private declarations for DCT subsystem */
|
||||
#include "jsimddct.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
@@ -46,7 +46,7 @@ typedef void (*float_quantize_method_ptr) (JCOEFPTR coef_block,
|
||||
METHODDEF(void) quantize (JCOEFPTR, DCTELEM *, DCTELEM *);
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
struct jpeg_forward_dct pub; /* public fields */
|
||||
|
||||
/* Pointer to the DCT routine actually in use */
|
||||
forward_DCT_method_ptr dct;
|
||||
@@ -149,7 +149,7 @@ flss (UINT16 val)
|
||||
*
|
||||
* In order to allow SIMD implementations we also tweak the values to
|
||||
* allow the same calculation to be made at all times:
|
||||
*
|
||||
*
|
||||
* dctbl[0] = f rounded to nearest integer
|
||||
* dctbl[1] = divisor / 2 (+ 1 if fractional part of f < 0.5)
|
||||
* dctbl[2] = 1 << ((word size) * 2 - r)
|
||||
@@ -223,7 +223,7 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
qtblno = compptr->quant_tbl_no;
|
||||
/* Make sure specified quantization table is present */
|
||||
if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS ||
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
cinfo->quant_tbl_ptrs[qtblno] == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno);
|
||||
qtbl = cinfo->quant_tbl_ptrs[qtblno];
|
||||
/* Compute divisors for this quant table */
|
||||
@@ -235,91 +235,91 @@ start_pass_fdctmgr (j_compress_ptr cinfo)
|
||||
* coefficients multiplied by 8 (to counteract scaling).
|
||||
*/
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(DCTSIZE2 * 4) * sizeof(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i])
|
||||
&& fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
if(!compute_reciprocal(qtbl->quantval[i] << 3, &dtbl[i])
|
||||
&& fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_IFAST_SUPPORTED
|
||||
case JDCT_IFAST:
|
||||
{
|
||||
/* For AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
*/
|
||||
/* For AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
*/
|
||||
#define CONST_BITS 14
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
static const INT16 aanscales[DCTSIZE2] = {
|
||||
/* precomputed values scaled up by 14 bits */
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
|
||||
21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
|
||||
19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
|
||||
16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
|
||||
12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
|
||||
8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
|
||||
4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
|
||||
};
|
||||
SHIFT_TEMPS
|
||||
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
if (fdct->divisors[qtblno] == NULL) {
|
||||
fdct->divisors[qtblno] = (DCTELEM *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
(DCTSIZE2 * 4) * sizeof(DCTELEM));
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if(!compute_reciprocal(
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-3), &dtbl[i])
|
||||
&& fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
}
|
||||
}
|
||||
dtbl = fdct->divisors[qtblno];
|
||||
for (i = 0; i < DCTSIZE2; i++) {
|
||||
if(!compute_reciprocal(
|
||||
DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
|
||||
(INT32) aanscales[i]),
|
||||
CONST_BITS-3), &dtbl[i])
|
||||
&& fdct->quantize == jsimd_quantize)
|
||||
fdct->quantize = quantize;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef DCT_FLOAT_SUPPORTED
|
||||
case JDCT_FLOAT:
|
||||
{
|
||||
/* For float AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
* What's actually stored is 1/divisor so that the inner loop can
|
||||
* use a multiplication rather than a division.
|
||||
*/
|
||||
FAST_FLOAT * fdtbl;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
/* For float AA&N IDCT method, divisors are equal to quantization
|
||||
* coefficients scaled by scalefactor[row]*scalefactor[col], where
|
||||
* scalefactor[0] = 1
|
||||
* scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
|
||||
* We apply a further scale factor of 8.
|
||||
* What's actually stored is 1/divisor so that the inner loop can
|
||||
* use a multiplication rather than a division.
|
||||
*/
|
||||
FAST_FLOAT * fdtbl;
|
||||
int row, col;
|
||||
static const double aanscalefactor[DCTSIZE] = {
|
||||
1.0, 1.387039845, 1.306562965, 1.175875602,
|
||||
1.0, 0.785694958, 0.541196100, 0.275899379
|
||||
};
|
||||
|
||||
if (fdct->float_divisors[qtblno] == NULL) {
|
||||
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
if (fdct->float_divisors[qtblno] == NULL) {
|
||||
fdct->float_divisors[qtblno] = (FAST_FLOAT *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
DCTSIZE2 * sizeof(FAST_FLOAT));
|
||||
}
|
||||
fdtbl = fdct->float_divisors[qtblno];
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fdtbl[i] = (FAST_FLOAT)
|
||||
(1.0 / (((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fdtbl = fdct->float_divisors[qtblno];
|
||||
i = 0;
|
||||
for (row = 0; row < DCTSIZE; row++) {
|
||||
for (col = 0; col < DCTSIZE; col++) {
|
||||
fdtbl[i] = (FAST_FLOAT)
|
||||
(1.0 / (((double) qtbl->quantval[i] *
|
||||
aanscalefactor[row] * aanscalefactor[col] * 8.0)));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@@ -346,7 +346,7 @@ convsamp (JSAMPARRAY sample_data, JDIMENSION start_col, DCTELEM * workspace)
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
*workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
|
||||
@@ -412,8 +412,8 @@ quantize (JCOEFPTR coef_block, DCTELEM * divisors, DCTELEM * workspace)
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks, JBLOCKROW dst)
|
||||
/* This version is used for integer DCT implementations. */
|
||||
{
|
||||
@@ -429,7 +429,7 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
quantize_method_ptr do_quantize = fdct->quantize;
|
||||
workspace = fdct->workspace;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
@@ -487,7 +487,7 @@ convsamp_float (JSAMPARRAY sample_data, JDIMENSION start_col, FAST_FLOAT * works
|
||||
workspaceptr = workspace;
|
||||
for (elemr = 0; elemr < DCTSIZE; elemr++) {
|
||||
elemptr = sample_data[elemr] + start_col;
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
#if DCTSIZE == 8 /* unroll the inner loop */
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
*workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
|
||||
@@ -532,8 +532,8 @@ quantize_float (JCOEFPTR coef_block, FAST_FLOAT * divisors, FAST_FLOAT * workspa
|
||||
|
||||
METHODDEF(void)
|
||||
forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
|
||||
JDIMENSION start_row, JDIMENSION start_col,
|
||||
JDIMENSION num_blocks, JBLOCKROW dst)
|
||||
/* This version is used for floating-point DCT implementations. */
|
||||
{
|
||||
@@ -552,7 +552,7 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
|
||||
float_quantize_method_ptr do_quantize = fdct->float_quantize;
|
||||
workspace = fdct->float_workspace;
|
||||
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
sample_data += start_row; /* fold in the vertical offset once */
|
||||
|
||||
for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
|
||||
/* Load data into workspace, applying unsigned->signed conversion */
|
||||
@@ -614,10 +614,10 @@ static const float jpeg_lambda_weights_csf_luma[64] = {
|
||||
};
|
||||
|
||||
GLOBAL(void)
|
||||
quantize_trellis(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
||||
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef)
|
||||
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, JCOEF *last_dc_val)
|
||||
{
|
||||
int i, j, k;
|
||||
int i, j, k, l;
|
||||
float accumulated_zero_dist[DCTSIZE2];
|
||||
float accumulated_cost[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 lambda_base;
|
||||
float lambda;
|
||||
float lambda_dc;
|
||||
const float *lambda_tbl = (cinfo->use_lambda_weight_tbl) ? jpeg_lambda_weights_csf_luma : jpeg_lambda_weights_flat;
|
||||
int Ss, Se;
|
||||
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 run_bits;
|
||||
int rate;
|
||||
float *accumulated_dc_cost[3];
|
||||
int *dc_cost_backtrack[3];
|
||||
JCOEF *dc_candidate[3];
|
||||
|
||||
Ss = cinfo->Ss;
|
||||
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));
|
||||
block_run_start = (int *)malloc(num_blocks * 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_block_cost[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;
|
||||
for (i = 1; i < DCTSIZE2; 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
|
||||
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_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++) {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
8
jchuff.h
8
jchuff.h
@@ -29,8 +29,8 @@
|
||||
/* Derived data constructed for each Huffman table */
|
||||
|
||||
typedef struct {
|
||||
unsigned int ehufco[256]; /* code for each symbol */
|
||||
char ehufsi[256]; /* length of code for each symbol */
|
||||
unsigned int ehufco[256]; /* code for each symbol */
|
||||
char ehufsi[256]; /* length of code for each symbol */
|
||||
/* If no code has been allocated for a symbol S, ehufsi[S] contains 0 */
|
||||
} c_derived_tbl;
|
||||
|
||||
@@ -44,5 +44,5 @@ EXTERN(void) jpeg_gen_optimal_table
|
||||
(j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]);
|
||||
|
||||
EXTERN(void) quantize_trellis
|
||||
(j_compress_ptr cinfo, c_derived_tbl *actbl, JBLOCKROW coef_blocks, JBLOCKROW src, JDIMENSION num_blocks,
|
||||
JQUANT_TBL * qtbl, double *norm_src, double *norm_coef);
|
||||
(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, JCOEF *last_dc_val);
|
||||
|
||||
322
jcmarker.c
322
jcmarker.c
@@ -17,7 +17,7 @@
|
||||
#include "jpegcomp.h"
|
||||
|
||||
|
||||
typedef enum { /* JPEG marker codes */
|
||||
typedef enum { /* JPEG marker codes */
|
||||
M_SOF0 = 0xc0,
|
||||
M_SOF1 = 0xc1,
|
||||
M_SOF2 = 0xc2,
|
||||
@@ -173,7 +173,7 @@ emit_dqt (j_compress_ptr cinfo, int index)
|
||||
/* The table entries must be emitted in zigzag order. */
|
||||
unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
|
||||
if (prec)
|
||||
emit_byte(cinfo, (int) (qval >> 8));
|
||||
emit_byte(cinfo, (int) (qval >> 8));
|
||||
emit_byte(cinfo, (int) (qval & 0xFF));
|
||||
}
|
||||
|
||||
@@ -183,6 +183,69 @@ emit_dqt (j_compress_ptr cinfo, int index)
|
||||
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)
|
||||
emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
|
||||
@@ -190,37 +253,143 @@ emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
|
||||
{
|
||||
JHUFF_TBL * htbl;
|
||||
int length, i;
|
||||
|
||||
|
||||
if (is_ac) {
|
||||
htbl = cinfo->ac_huff_tbl_ptrs[index];
|
||||
index += 0x10; /* output index has AC bit set */
|
||||
index += 0x10; /* output index has AC bit set */
|
||||
} else {
|
||||
htbl = cinfo->dc_huff_tbl_ptrs[index];
|
||||
}
|
||||
|
||||
if (htbl == NULL)
|
||||
ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
|
||||
|
||||
|
||||
if (! htbl->sent_table) {
|
||||
emit_marker(cinfo, M_DHT);
|
||||
|
||||
|
||||
length = 0;
|
||||
for (i = 1; i <= 16; i++)
|
||||
length += htbl->bits[i];
|
||||
|
||||
|
||||
emit_2bytes(cinfo, length + 2 + 1 + 16);
|
||||
emit_byte(cinfo, index);
|
||||
|
||||
|
||||
for (i = 1; i <= 16; i++)
|
||||
emit_byte(cinfo, htbl->bits[i]);
|
||||
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
emit_byte(cinfo, htbl->huffval[i]);
|
||||
|
||||
|
||||
htbl->sent_table = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
emit_dac (j_compress_ptr cinfo)
|
||||
@@ -258,12 +427,12 @@ emit_dac (j_compress_ptr cinfo)
|
||||
|
||||
for (i = 0; i < NUM_ARITH_TBLS; i++) {
|
||||
if (dc_in_use[i]) {
|
||||
emit_byte(cinfo, i);
|
||||
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
|
||||
emit_byte(cinfo, i);
|
||||
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
|
||||
}
|
||||
if (ac_in_use[i]) {
|
||||
emit_byte(cinfo, i + 0x10);
|
||||
emit_byte(cinfo, cinfo->arith_ac_K[i]);
|
||||
emit_byte(cinfo, i + 0x10);
|
||||
emit_byte(cinfo, cinfo->arith_ac_K[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,8 +445,8 @@ emit_dri (j_compress_ptr cinfo)
|
||||
/* Emit a DRI marker */
|
||||
{
|
||||
emit_marker(cinfo, M_DRI);
|
||||
|
||||
emit_2bytes(cinfo, 4); /* fixed length */
|
||||
|
||||
emit_2bytes(cinfo, 4); /* fixed length */
|
||||
|
||||
emit_2bytes(cinfo, (int) cinfo->restart_interval);
|
||||
}
|
||||
@@ -289,9 +458,9 @@ emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
|
||||
{
|
||||
int ci;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
|
||||
emit_marker(cinfo, code);
|
||||
|
||||
|
||||
emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
|
||||
|
||||
/* Make sure image isn't bigger than SOF field can handle */
|
||||
@@ -320,13 +489,13 @@ emit_sos (j_compress_ptr cinfo)
|
||||
{
|
||||
int i, td, ta;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
|
||||
emit_marker(cinfo, M_SOS);
|
||||
|
||||
|
||||
emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
|
||||
|
||||
|
||||
emit_byte(cinfo, cinfo->comps_in_scan);
|
||||
|
||||
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
emit_byte(cinfo, compptr->component_id);
|
||||
@@ -354,22 +523,22 @@ emit_jfif_app0 (j_compress_ptr cinfo)
|
||||
/* Emit a JFIF-compliant APP0 marker */
|
||||
{
|
||||
/*
|
||||
* Length of APP0 block (2 bytes)
|
||||
* Block ID (4 bytes - ASCII "JFIF")
|
||||
* Zero byte (1 byte to terminate the ID string)
|
||||
* Version Major, Minor (2 bytes - major first)
|
||||
* Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
|
||||
* Xdpu (2 bytes - dots per unit horizontal)
|
||||
* Ydpu (2 bytes - dots per unit vertical)
|
||||
* Thumbnail X size (1 byte)
|
||||
* Thumbnail Y size (1 byte)
|
||||
* Length of APP0 block (2 bytes)
|
||||
* Block ID (4 bytes - ASCII "JFIF")
|
||||
* Zero byte (1 byte to terminate the ID string)
|
||||
* Version Major, Minor (2 bytes - major first)
|
||||
* Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
|
||||
* Xdpu (2 bytes - dots per unit horizontal)
|
||||
* Ydpu (2 bytes - dots per unit vertical)
|
||||
* Thumbnail X size (1 byte)
|
||||
* Thumbnail Y size (1 byte)
|
||||
*/
|
||||
|
||||
|
||||
emit_marker(cinfo, M_APP0);
|
||||
|
||||
|
||||
emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
|
||||
|
||||
emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */
|
||||
emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */
|
||||
emit_byte(cinfo, 0x46);
|
||||
emit_byte(cinfo, 0x49);
|
||||
emit_byte(cinfo, 0x46);
|
||||
@@ -379,7 +548,7 @@ emit_jfif_app0 (j_compress_ptr cinfo)
|
||||
emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
|
||||
emit_2bytes(cinfo, (int) cinfo->X_density);
|
||||
emit_2bytes(cinfo, (int) cinfo->Y_density);
|
||||
emit_byte(cinfo, 0); /* No thumbnail image */
|
||||
emit_byte(cinfo, 0); /* No thumbnail image */
|
||||
emit_byte(cinfo, 0);
|
||||
}
|
||||
|
||||
@@ -389,12 +558,12 @@ emit_adobe_app14 (j_compress_ptr cinfo)
|
||||
/* Emit an Adobe APP14 marker */
|
||||
{
|
||||
/*
|
||||
* Length of APP14 block (2 bytes)
|
||||
* Block ID (5 bytes - ASCII "Adobe")
|
||||
* Version Number (2 bytes - currently 100)
|
||||
* Flags0 (2 bytes - currently 0)
|
||||
* Flags1 (2 bytes - currently 0)
|
||||
* Color transform (1 byte)
|
||||
* Length of APP14 block (2 bytes)
|
||||
* Block ID (5 bytes - ASCII "Adobe")
|
||||
* Version Number (2 bytes - currently 100)
|
||||
* Flags0 (2 bytes - currently 0)
|
||||
* Flags1 (2 bytes - currently 0)
|
||||
* Color transform (1 byte)
|
||||
*
|
||||
* Although Adobe TN 5116 mentions Version = 101, all the Adobe files
|
||||
* now in circulation seem to use Version = 100, so that's what we write.
|
||||
@@ -403,28 +572,28 @@ emit_adobe_app14 (j_compress_ptr cinfo)
|
||||
* YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with
|
||||
* whether the encoder performed a transformation, which is pretty useless.
|
||||
*/
|
||||
|
||||
|
||||
emit_marker(cinfo, M_APP14);
|
||||
|
||||
|
||||
emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
|
||||
|
||||
emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */
|
||||
emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */
|
||||
emit_byte(cinfo, 0x64);
|
||||
emit_byte(cinfo, 0x6F);
|
||||
emit_byte(cinfo, 0x62);
|
||||
emit_byte(cinfo, 0x65);
|
||||
emit_2bytes(cinfo, 100); /* Version */
|
||||
emit_2bytes(cinfo, 0); /* Flags0 */
|
||||
emit_2bytes(cinfo, 0); /* Flags1 */
|
||||
emit_2bytes(cinfo, 100); /* Version */
|
||||
emit_2bytes(cinfo, 0); /* Flags0 */
|
||||
emit_2bytes(cinfo, 0); /* Flags1 */
|
||||
switch (cinfo->jpeg_color_space) {
|
||||
case JCS_YCbCr:
|
||||
emit_byte(cinfo, 1); /* Color transform = 1 */
|
||||
emit_byte(cinfo, 1); /* Color transform = 1 */
|
||||
break;
|
||||
case JCS_YCCK:
|
||||
emit_byte(cinfo, 2); /* Color transform = 2 */
|
||||
emit_byte(cinfo, 2); /* Color transform = 2 */
|
||||
break;
|
||||
default:
|
||||
emit_byte(cinfo, 0); /* Color transform = 0 */
|
||||
emit_byte(cinfo, 0); /* Color transform = 0 */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -442,12 +611,12 @@ METHODDEF(void)
|
||||
write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
|
||||
/* Emit an arbitrary marker header */
|
||||
{
|
||||
if (datalen > (unsigned int) 65533) /* safety check */
|
||||
if (datalen > (unsigned int) 65533) /* safety check */
|
||||
ERREXIT(cinfo, JERR_BAD_LENGTH);
|
||||
|
||||
emit_marker(cinfo, (JPEG_MARKER) marker);
|
||||
|
||||
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
|
||||
emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
|
||||
}
|
||||
|
||||
METHODDEF(void)
|
||||
@@ -474,12 +643,12 @@ write_file_header (j_compress_ptr cinfo)
|
||||
{
|
||||
my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
|
||||
|
||||
emit_marker(cinfo, M_SOI); /* first the SOI */
|
||||
emit_marker(cinfo, M_SOI); /* first the SOI */
|
||||
|
||||
/* SOI is defined to reset restart interval to 0 */
|
||||
marker->last_restart_interval = 0;
|
||||
|
||||
if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
|
||||
if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
|
||||
emit_jfif_app0(cinfo);
|
||||
if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
|
||||
emit_adobe_app14(cinfo);
|
||||
@@ -500,14 +669,17 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
int ci, prec;
|
||||
boolean is_baseline;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
|
||||
/* Emit DQT for each quantization table.
|
||||
* Note that emit_dqt() suppresses any duplicate tables.
|
||||
*/
|
||||
prec = 0;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
||||
prec = emit_multi_dqt(cinfo);
|
||||
if (prec == -1) {
|
||||
prec = 0;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
prec += emit_dqt(cinfo, compptr->quant_tbl_no);
|
||||
}
|
||||
}
|
||||
/* now prec is nonzero iff there are any 16-bit quant tables. */
|
||||
|
||||
@@ -520,9 +692,9 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
} else {
|
||||
is_baseline = TRUE;
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
ci++, compptr++) {
|
||||
if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
|
||||
is_baseline = FALSE;
|
||||
is_baseline = FALSE;
|
||||
}
|
||||
if (prec && is_baseline) {
|
||||
is_baseline = FALSE;
|
||||
@@ -539,11 +711,11 @@ write_frame_header (j_compress_ptr cinfo)
|
||||
emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */
|
||||
} else {
|
||||
if (cinfo->progressive_mode)
|
||||
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
|
||||
emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
|
||||
else if (is_baseline)
|
||||
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
|
||||
emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
|
||||
else
|
||||
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
|
||||
emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,14 +743,16 @@ write_scan_header (j_compress_ptr cinfo)
|
||||
/* Emit Huffman tables.
|
||||
* Note that emit_dht() suppresses any duplicate tables.
|
||||
*/
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0)
|
||||
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se)
|
||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||
if (!emit_multi_dht(cinfo)) {
|
||||
for (i = 0; i < cinfo->comps_in_scan; i++) {
|
||||
compptr = cinfo->cur_comp_info[i];
|
||||
/* DC needs no table for refinement scan */
|
||||
if (cinfo->Ss == 0 && cinfo->Ah == 0)
|
||||
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
|
||||
/* AC needs no table when not present */
|
||||
if (cinfo->Se)
|
||||
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,9 +801,9 @@ write_tables_only (j_compress_ptr cinfo)
|
||||
if (! cinfo->arith_code) {
|
||||
for (i = 0; i < NUM_HUFF_TBLS; i++) {
|
||||
if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
|
||||
emit_dht(cinfo, i, FALSE);
|
||||
emit_dht(cinfo, i, FALSE);
|
||||
if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
|
||||
emit_dht(cinfo, i, TRUE);
|
||||
emit_dht(cinfo, i, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
173
jcmaster.c
173
jcmaster.c
@@ -12,7 +12,7 @@
|
||||
*
|
||||
* This file contains master control logic for the JPEG compressor.
|
||||
* These routines are concerned with parameter validation, initial setup,
|
||||
* and inter-pass control (determining the number of passes and the work
|
||||
* and inter-pass control (determining the number of passes and the work
|
||||
* to be done in each pass).
|
||||
*/
|
||||
|
||||
@@ -25,26 +25,27 @@
|
||||
/* Private state */
|
||||
|
||||
typedef enum {
|
||||
main_pass, /* input data, also do first output step */
|
||||
huff_opt_pass, /* Huffman code optimization pass */
|
||||
main_pass, /* input data, also do first output step */
|
||||
huff_opt_pass, /* Huffman code optimization pass */
|
||||
output_pass, /* data output pass */
|
||||
trellis_pass /* trellis quantization pass */
|
||||
} c_pass_type;
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_comp_master pub; /* public fields */
|
||||
struct jpeg_comp_master pub; /* public fields */
|
||||
|
||||
c_pass_type pass_type; /* the type of the current pass */
|
||||
c_pass_type pass_type; /* the type of the current pass */
|
||||
|
||||
int pass_number; /* # of passes completed */
|
||||
int total_passes; /* total # of passes needed */
|
||||
int pass_number; /* # of passes completed */
|
||||
int total_passes; /* total # of passes needed */
|
||||
|
||||
int scan_number; /* current index in scan_info[] */
|
||||
int scan_number; /* current index in scan_info[] */
|
||||
|
||||
/* fields for scan optimisation */
|
||||
int pass_number_scan_opt_base; /* pass number where scan optimization begins */
|
||||
unsigned char * scan_buffer[64]; /* buffer 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 */
|
||||
int best_freq_split_idx_luma; /* index for best frequency split (luma) */
|
||||
int best_freq_split_idx_chroma; /* index for best frequency split (chroma) */
|
||||
@@ -120,7 +121,7 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
|
||||
/* Check that number of components won't exceed internal array sizes */
|
||||
if (cinfo->num_components > MAX_COMPONENTS)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
|
||||
MAX_COMPONENTS);
|
||||
MAX_COMPONENTS);
|
||||
|
||||
/* Compute maximum sampling factors; check factor validity */
|
||||
cinfo->max_h_samp_factor = 1;
|
||||
@@ -128,12 +129,12 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
|
||||
for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
|
||||
ci++, compptr++) {
|
||||
if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
|
||||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
|
||||
compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
|
||||
ERREXIT(cinfo, JERR_BAD_SAMPLING);
|
||||
cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
|
||||
compptr->h_samp_factor);
|
||||
compptr->h_samp_factor);
|
||||
cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
|
||||
compptr->v_samp_factor);
|
||||
compptr->v_samp_factor);
|
||||
}
|
||||
|
||||
/* Compute dimensions of components */
|
||||
@@ -150,17 +151,17 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
|
||||
/* Size in DCT blocks */
|
||||
compptr->width_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
(long) (cinfo->max_h_samp_factor * DCTSIZE));
|
||||
compptr->height_in_blocks = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
(long) (cinfo->max_v_samp_factor * DCTSIZE));
|
||||
/* Size in samples */
|
||||
compptr->downsampled_width = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_width * (long) compptr->h_samp_factor,
|
||||
(long) cinfo->max_h_samp_factor);
|
||||
(long) cinfo->max_h_samp_factor);
|
||||
compptr->downsampled_height = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_height * (long) compptr->v_samp_factor,
|
||||
(long) cinfo->max_v_samp_factor);
|
||||
(long) cinfo->max_v_samp_factor);
|
||||
/* Mark component needed (this flag isn't actually used for compression) */
|
||||
compptr->component_needed = TRUE;
|
||||
}
|
||||
@@ -170,7 +171,7 @@ initial_setup (j_compress_ptr cinfo, boolean transcode_only)
|
||||
*/
|
||||
cinfo->total_iMCU_rows = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
}
|
||||
|
||||
|
||||
@@ -211,15 +212,15 @@ validate_script (j_compress_ptr cinfo)
|
||||
#ifdef C_PROGRESSIVE_SUPPORTED
|
||||
cinfo->progressive_mode = TRUE;
|
||||
last_bitpos_ptr = & last_bitpos[0][0];
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (coefi = 0; coefi < DCTSIZE2; coefi++)
|
||||
*last_bitpos_ptr++ = -1;
|
||||
*last_bitpos_ptr++ = -1;
|
||||
#else
|
||||
ERREXIT(cinfo, JERR_NOT_COMPILED);
|
||||
#endif
|
||||
} else {
|
||||
cinfo->progressive_mode = FALSE;
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
for (ci = 0; ci < cinfo->num_components; ci++)
|
||||
component_sent[ci] = FALSE;
|
||||
}
|
||||
|
||||
@@ -231,10 +232,10 @@ validate_script (j_compress_ptr cinfo)
|
||||
for (ci = 0; ci < ncomps; ci++) {
|
||||
thisi = scanptr->component_index[ci];
|
||||
if (thisi < 0 || thisi >= cinfo->num_components)
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
/* Components must appear in SOF order within each scan */
|
||||
if (ci > 0 && thisi <= scanptr->component_index[ci-1])
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
}
|
||||
/* Validate progression parameters */
|
||||
Ss = scanptr->Ss;
|
||||
@@ -256,43 +257,43 @@ validate_script (j_compress_ptr cinfo)
|
||||
#define MAX_AH_AL 13
|
||||
#endif
|
||||
if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
|
||||
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
if (Ss == 0) {
|
||||
if (Se != 0) /* DC and AC together not OK */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
if (Se != 0) /* DC and AC together not OK */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
} else {
|
||||
if (ncomps != 1) /* AC scans must be for only one component */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
if (ncomps != 1) /* AC scans must be for only one component */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
}
|
||||
for (ci = 0; ci < ncomps; ci++) {
|
||||
last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
|
||||
if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
for (coefi = Ss; coefi <= Se; coefi++) {
|
||||
if (last_bitpos_ptr[coefi] < 0) {
|
||||
/* first scan of this coefficient */
|
||||
if (Ah != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
} else {
|
||||
/* not first scan */
|
||||
if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
}
|
||||
last_bitpos_ptr[coefi] = Al;
|
||||
}
|
||||
last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
|
||||
if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
for (coefi = Ss; coefi <= Se; coefi++) {
|
||||
if (last_bitpos_ptr[coefi] < 0) {
|
||||
/* first scan of this coefficient */
|
||||
if (Ah != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
} else {
|
||||
/* not first scan */
|
||||
if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
}
|
||||
last_bitpos_ptr[coefi] = Al;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* For sequential JPEG, all progression parameters must be these: */
|
||||
if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
|
||||
/* Make sure components are not sent twice */
|
||||
for (ci = 0; ci < ncomps; ci++) {
|
||||
thisi = scanptr->component_index[ci];
|
||||
if (component_sent[thisi])
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
component_sent[thisi] = TRUE;
|
||||
thisi = scanptr->component_index[ci];
|
||||
if (component_sent[thisi])
|
||||
ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
|
||||
component_sent[thisi] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,13 +308,13 @@ validate_script (j_compress_ptr cinfo)
|
||||
*/
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
if (last_bitpos[ci][0] < 0)
|
||||
ERREXIT(cinfo, JERR_MISSING_DATA);
|
||||
ERREXIT(cinfo, JERR_MISSING_DATA);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
if (! component_sent[ci])
|
||||
ERREXIT(cinfo, JERR_MISSING_DATA);
|
||||
ERREXIT(cinfo, JERR_MISSING_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -348,7 +349,7 @@ select_scan_parameters (j_compress_ptr cinfo)
|
||||
cinfo->comps_in_scan = scanptr->comps_in_scan;
|
||||
for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
|
||||
cinfo->cur_comp_info[ci] =
|
||||
&cinfo->comp_info[scanptr->component_index[ci]];
|
||||
&cinfo->comp_info[scanptr->component_index[ci]];
|
||||
}
|
||||
cinfo->Ss = scanptr->Ss;
|
||||
cinfo->Se = scanptr->Se;
|
||||
@@ -363,7 +364,9 @@ select_scan_parameters (j_compress_ptr cinfo)
|
||||
if (master->scan_number >= cinfo->num_scans_luma+cinfo->num_scans_chroma_dc+(6*cinfo->Al_max_chroma+4) &&
|
||||
master->scan_number < cinfo->num_scans)
|
||||
cinfo->Al = master->best_Al_chroma;
|
||||
}
|
||||
}
|
||||
/* save value for later retrieval during printout of scans */
|
||||
master->actual_Al[master->scan_number] = cinfo->Al;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
@@ -371,7 +374,7 @@ select_scan_parameters (j_compress_ptr cinfo)
|
||||
/* Prepare for single sequential-JPEG scan containing all components */
|
||||
if (cinfo->num_components > MAX_COMPS_IN_SCAN)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
|
||||
MAX_COMPS_IN_SCAN);
|
||||
MAX_COMPS_IN_SCAN);
|
||||
cinfo->comps_in_scan = cinfo->num_components;
|
||||
for (ci = 0; ci < cinfo->num_components; ci++) {
|
||||
cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
|
||||
@@ -391,16 +394,16 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
{
|
||||
int ci, mcublks, tmp;
|
||||
jpeg_component_info *compptr;
|
||||
|
||||
|
||||
if (cinfo->comps_in_scan == 1) {
|
||||
|
||||
|
||||
/* Noninterleaved (single-component) scan */
|
||||
compptr = cinfo->cur_comp_info[0];
|
||||
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = compptr->width_in_blocks;
|
||||
cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
|
||||
|
||||
|
||||
/* For noninterleaved scan, always one block per MCU */
|
||||
compptr->MCU_width = 1;
|
||||
compptr->MCU_height = 1;
|
||||
@@ -413,28 +416,28 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
|
||||
if (tmp == 0) tmp = compptr->v_samp_factor;
|
||||
compptr->last_row_height = tmp;
|
||||
|
||||
|
||||
/* Prepare array describing MCU composition */
|
||||
cinfo->blocks_in_MCU = 1;
|
||||
cinfo->MCU_membership[0] = 0;
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
/* Interleaved (multi-component) scan */
|
||||
if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
|
||||
ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
|
||||
MAX_COMPS_IN_SCAN);
|
||||
|
||||
MAX_COMPS_IN_SCAN);
|
||||
|
||||
/* Overall image size in MCUs */
|
||||
cinfo->MCUs_per_row = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_width,
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
(long) (cinfo->max_h_samp_factor*DCTSIZE));
|
||||
cinfo->MCU_rows_in_scan = (JDIMENSION)
|
||||
jdiv_round_up((long) cinfo->_jpeg_height,
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
(long) (cinfo->max_v_samp_factor*DCTSIZE));
|
||||
|
||||
cinfo->blocks_in_MCU = 0;
|
||||
|
||||
|
||||
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
|
||||
compptr = cinfo->cur_comp_info[ci];
|
||||
/* Sampling factors give # of blocks of component in each MCU */
|
||||
@@ -452,12 +455,12 @@ per_scan_setup (j_compress_ptr cinfo)
|
||||
/* Prepare array describing MCU composition */
|
||||
mcublks = compptr->MCU_blocks;
|
||||
if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
|
||||
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
|
||||
ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
|
||||
while (mcublks-- > 0) {
|
||||
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
|
||||
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* Convert restart specified in rows to actual MCU count. */
|
||||
@@ -498,8 +501,8 @@ prepare_for_pass (j_compress_ptr cinfo)
|
||||
(*cinfo->fdct->start_pass) (cinfo);
|
||||
(*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
|
||||
(*cinfo->coef->start_pass) (cinfo,
|
||||
(master->total_passes > 1 ?
|
||||
JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
|
||||
(master->total_passes > 1 ?
|
||||
JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
|
||||
(*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
|
||||
if (cinfo->optimize_coding) {
|
||||
/* No immediate data output; postpone writing frame/scan headers */
|
||||
@@ -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++)
|
||||
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].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");
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
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);
|
||||
else {
|
||||
copy_buffer(cinfo, base_scan_idx+1);
|
||||
@@ -835,9 +838,9 @@ finish_pass_master (j_compress_ptr cinfo)
|
||||
if (cinfo->trellis_quant)
|
||||
master->pass_type = trellis_pass;
|
||||
else {
|
||||
master->pass_type = output_pass;
|
||||
if (! cinfo->optimize_coding)
|
||||
master->scan_number++;
|
||||
master->pass_type = output_pass;
|
||||
if (! cinfo->optimize_coding)
|
||||
master->scan_number++;
|
||||
}
|
||||
break;
|
||||
case huff_opt_pass:
|
||||
@@ -869,7 +872,7 @@ finish_pass_master (j_compress_ptr cinfo)
|
||||
if (q > 254) q = 254;
|
||||
if (q < 1) q = 1;
|
||||
cinfo->quant_tbl_ptrs[i]->quantval[j] = q;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -912,7 +915,7 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
cinfo->num_scans = 1;
|
||||
}
|
||||
|
||||
if (cinfo->progressive_mode && !cinfo->arith_code) /* TEMPORARY HACK ??? */
|
||||
if (cinfo->progressive_mode && !cinfo->arith_code) /* TEMPORARY HACK ??? */
|
||||
cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
|
||||
|
||||
/* Initialize my private state */
|
||||
@@ -933,8 +936,11 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
else
|
||||
master->total_passes = cinfo->num_scans;
|
||||
|
||||
if (cinfo->trellis_quant)
|
||||
master->total_passes += ((cinfo->use_scans_in_trellis) ? 4 : 2) * cinfo->num_components * cinfo->trellis_num_loops;
|
||||
master->pass_number_scan_opt_base = 0;
|
||||
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) {
|
||||
int i;
|
||||
@@ -942,10 +948,5 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
|
||||
|
||||
for (i = 0; i < cinfo->num_scans; i++)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
15
jconfig.txt
15
jconfig.txt
@@ -78,10 +78,10 @@
|
||||
/* Define "boolean" as unsigned char, not int, on Windows systems.
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
|
||||
typedef unsigned char boolean;
|
||||
#endif
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -114,11 +114,12 @@ typedef unsigned char boolean;
|
||||
|
||||
/* These defines indicate which image (non-JPEG) file formats are allowed. */
|
||||
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
#define PNG_SUPPORTED /* PNG image file format */
|
||||
#define BMP_SUPPORTED /* BMP image file format */
|
||||
#define GIF_SUPPORTED /* GIF image file format */
|
||||
#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
|
||||
#undef RLE_SUPPORTED /* Utah RLE image file format */
|
||||
#define TARGA_SUPPORTED /* Targa image file format */
|
||||
|
||||
/* Define this if you want to name both input and output files on the command
|
||||
* line, rather than using stdout and optionally stdin. You MUST do this if
|
||||
|
||||
22
jcparam.c
22
jcparam.c
@@ -152,14 +152,20 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
|
||||
|
||||
GLOBAL(int)
|
||||
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
|
||||
* for an underlying quantization table, using our recommended scaling curve.
|
||||
* 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. */
|
||||
if (quality <= 0) quality = 1;
|
||||
if (quality > 100) quality = 100;
|
||||
if (quality <= 0.f) quality = 1.f;
|
||||
if (quality > 100.f) quality = 100.f;
|
||||
|
||||
/* 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;
|
||||
@@ -167,10 +173,10 @@ jpeg_quality_scaling (int quality)
|
||||
* to make all the table entries 1 (hence, minimum quantization loss).
|
||||
* Qualities 1..50 are converted to scaling percentage 5000/Q.
|
||||
*/
|
||||
if (quality < 50)
|
||||
quality = 5000 / quality;
|
||||
if (quality < 50.f)
|
||||
quality = 5000.f / quality;
|
||||
else
|
||||
quality = 200 - quality*2;
|
||||
quality = 200.f - quality*2.f;
|
||||
|
||||
return quality;
|
||||
}
|
||||
@@ -335,6 +341,7 @@ jpeg_set_defaults (j_compress_ptr cinfo)
|
||||
cinfo->trellis_freq_split = 8;
|
||||
cinfo->trellis_num_loops = 1;
|
||||
cinfo->trellis_q_opt = FALSE;
|
||||
cinfo->trellis_quant_dc = TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -730,6 +737,11 @@ jpeg_simple_progression (j_compress_ptr cinfo)
|
||||
/* Initial DC scan */
|
||||
if (cinfo->one_dc_scan)
|
||||
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 {
|
||||
scanptr = fill_dc_scans(scanptr, 1, 0, 0);
|
||||
scanptr = fill_a_scan_pair(scanptr, 1, 0, 0, 0, 0);
|
||||
|
||||
433
jpeglib.h
433
jpeglib.h
@@ -25,10 +25,10 @@
|
||||
* manual configuration options that most people need not worry about.
|
||||
*/
|
||||
|
||||
#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
|
||||
#include "jconfig.h" /* widely used configuration options */
|
||||
#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
|
||||
#include "jconfig.h" /* widely used configuration options */
|
||||
#endif
|
||||
#include "jmorecfg.h" /* seldom changed options */
|
||||
#include "jmorecfg.h" /* seldom changed options */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -43,13 +43,13 @@ extern "C" {
|
||||
* if you want to be compatible.
|
||||
*/
|
||||
|
||||
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
|
||||
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
|
||||
#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
|
||||
#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
|
||||
#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
|
||||
#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
|
||||
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
|
||||
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
|
||||
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
|
||||
#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
|
||||
#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
|
||||
#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
|
||||
#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
|
||||
/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
|
||||
* the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
|
||||
* If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
|
||||
@@ -67,13 +67,13 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef JSAMPLE *JSAMPROW; /* ptr to one image row of pixel samples. */
|
||||
typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
|
||||
typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
|
||||
typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
|
||||
|
||||
typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
|
||||
typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
|
||||
typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
|
||||
typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
|
||||
typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
|
||||
typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
|
||||
|
||||
typedef JCOEF *JCOEFPTR; /* useful in a couple of places */
|
||||
|
||||
@@ -88,13 +88,13 @@ typedef struct {
|
||||
* (not the zigzag order in which they are stored in a JPEG DQT marker).
|
||||
* CAUTION: IJG versions prior to v6a kept this array in zigzag order.
|
||||
*/
|
||||
UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
|
||||
UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
|
||||
/* This field is used only during compression. It's initialized FALSE when
|
||||
* the table is created, and set TRUE when it's been output to the file.
|
||||
* You could suppress output of a table by setting this to TRUE.
|
||||
* (See jpeg_suppress_tables for an example.)
|
||||
*/
|
||||
boolean sent_table; /* TRUE when table has been output */
|
||||
boolean sent_table; /* TRUE when table has been output */
|
||||
} JQUANT_TBL;
|
||||
|
||||
|
||||
@@ -102,15 +102,15 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
/* These two fields directly represent the contents of a JPEG DHT marker */
|
||||
UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
|
||||
/* length k bits; bits[0] is unused */
|
||||
UINT8 huffval[256]; /* The symbols, in order of incr code length */
|
||||
UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
|
||||
/* length k bits; bits[0] is unused */
|
||||
UINT8 huffval[256]; /* The symbols, in order of incr code length */
|
||||
/* This field is used only during compression. It's initialized FALSE when
|
||||
* the table is created, and set TRUE when it's been output to the file.
|
||||
* You could suppress output of a table by setting this to TRUE.
|
||||
* (See jpeg_suppress_tables for an example.)
|
||||
*/
|
||||
boolean sent_table; /* TRUE when table has been output */
|
||||
boolean sent_table; /* TRUE when table has been output */
|
||||
} JHUFF_TBL;
|
||||
|
||||
|
||||
@@ -120,20 +120,20 @@ typedef struct {
|
||||
/* These values are fixed over the whole image. */
|
||||
/* For compression, they must be supplied by parameter setup; */
|
||||
/* for decompression, they are read from the SOF marker. */
|
||||
int component_id; /* identifier for this component (0..255) */
|
||||
int component_index; /* its index in SOF or cinfo->comp_info[] */
|
||||
int h_samp_factor; /* horizontal sampling factor (1..4) */
|
||||
int v_samp_factor; /* vertical sampling factor (1..4) */
|
||||
int quant_tbl_no; /* quantization table selector (0..3) */
|
||||
int component_id; /* identifier for this component (0..255) */
|
||||
int component_index; /* its index in SOF or cinfo->comp_info[] */
|
||||
int h_samp_factor; /* horizontal sampling factor (1..4) */
|
||||
int v_samp_factor; /* vertical sampling factor (1..4) */
|
||||
int quant_tbl_no; /* quantization table selector (0..3) */
|
||||
/* These values may vary between scans. */
|
||||
/* For compression, they must be supplied by parameter setup; */
|
||||
/* for decompression, they are read from the SOS marker. */
|
||||
/* The decompressor output side may not use these variables. */
|
||||
int dc_tbl_no; /* DC entropy table selector (0..3) */
|
||||
int ac_tbl_no; /* AC entropy table selector (0..3) */
|
||||
|
||||
int dc_tbl_no; /* DC entropy table selector (0..3) */
|
||||
int ac_tbl_no; /* AC entropy table selector (0..3) */
|
||||
|
||||
/* Remaining fields should be treated as private by applications. */
|
||||
|
||||
|
||||
/* These values are computed during compression or decompression startup: */
|
||||
/* Component's size in DCT blocks.
|
||||
* Any dummy blocks added to complete an MCU are not counted; therefore
|
||||
@@ -159,22 +159,22 @@ typedef struct {
|
||||
* and similarly for height. For decompression, IDCT scaling is included, so
|
||||
* downsampled_width = ceil(image_width * Hi/Hmax * DCT_[h_]scaled_size/DCTSIZE)
|
||||
*/
|
||||
JDIMENSION downsampled_width; /* actual width in samples */
|
||||
JDIMENSION downsampled_width; /* actual width in samples */
|
||||
JDIMENSION downsampled_height; /* actual height in samples */
|
||||
/* This flag is used only for decompression. In cases where some of the
|
||||
* components will be ignored (eg grayscale output from YCbCr image),
|
||||
* we can skip most computations for the unused components.
|
||||
*/
|
||||
boolean component_needed; /* do we need the value of this component? */
|
||||
boolean component_needed; /* do we need the value of this component? */
|
||||
|
||||
/* These values are computed before starting a scan of the component. */
|
||||
/* The decompressor output side may not use these variables. */
|
||||
int MCU_width; /* number of blocks per MCU, horizontally */
|
||||
int MCU_height; /* number of blocks per MCU, vertically */
|
||||
int MCU_blocks; /* MCU_width * MCU_height */
|
||||
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
|
||||
int last_col_width; /* # of non-dummy blocks across in last MCU */
|
||||
int last_row_height; /* # of non-dummy blocks down in last MCU */
|
||||
int MCU_width; /* number of blocks per MCU, horizontally */
|
||||
int MCU_height; /* number of blocks per MCU, vertically */
|
||||
int MCU_blocks; /* MCU_width * MCU_height */
|
||||
int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_[h_]scaled_size */
|
||||
int last_col_width; /* # of non-dummy blocks across in last MCU */
|
||||
int last_row_height; /* # of non-dummy blocks down in last MCU */
|
||||
|
||||
/* Saved quantization table for component; NULL if none yet saved.
|
||||
* See jdinput.c comments about the need for this information.
|
||||
@@ -190,10 +190,10 @@ typedef struct {
|
||||
/* The script for encoding a multiple-scan file is an array of these: */
|
||||
|
||||
typedef struct {
|
||||
int comps_in_scan; /* number of components encoded in this scan */
|
||||
int comps_in_scan; /* number of components encoded in this scan */
|
||||
int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
|
||||
int Ss, Se; /* progressive JPEG spectral selection parms */
|
||||
int Ah, Al; /* progressive JPEG successive approx. parms */
|
||||
int Ss, Se; /* progressive JPEG spectral selection parms */
|
||||
int Ah, Al; /* progressive JPEG successive approx. parms */
|
||||
} jpeg_scan_info;
|
||||
|
||||
/* The decompressor can save APPn and COM markers in a list of these: */
|
||||
@@ -201,10 +201,10 @@ typedef struct {
|
||||
typedef struct jpeg_marker_struct * jpeg_saved_marker_ptr;
|
||||
|
||||
struct jpeg_marker_struct {
|
||||
jpeg_saved_marker_ptr next; /* next in list, or NULL */
|
||||
UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
|
||||
unsigned int original_length; /* # bytes of data in the file */
|
||||
unsigned int data_length; /* # bytes of data saved at data[] */
|
||||
jpeg_saved_marker_ptr next; /* next in list, or NULL */
|
||||
UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
|
||||
unsigned int original_length; /* # bytes of data in the file */
|
||||
unsigned int data_length; /* # bytes of data saved at data[] */
|
||||
JOCTET * data; /* the data contained in the marker */
|
||||
/* the marker length word is not counted in data_length or original_length */
|
||||
};
|
||||
@@ -215,28 +215,28 @@ struct jpeg_marker_struct {
|
||||
#define JCS_ALPHA_EXTENSIONS 1
|
||||
|
||||
typedef enum {
|
||||
JCS_UNKNOWN, /* error/unspecified */
|
||||
JCS_GRAYSCALE, /* monochrome */
|
||||
JCS_UNKNOWN, /* error/unspecified */
|
||||
JCS_GRAYSCALE, /* monochrome */
|
||||
JCS_RGB, /* red/green/blue as specified by the RGB_RED,
|
||||
RGB_GREEN, RGB_BLUE, and RGB_PIXELSIZE macros */
|
||||
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_CMYK, /* C/M/Y/K */
|
||||
JCS_YCCK, /* Y/Cb/Cr/K */
|
||||
JCS_EXT_RGB, /* red/green/blue */
|
||||
JCS_EXT_RGBX, /* red/green/blue/x */
|
||||
JCS_EXT_BGR, /* blue/green/red */
|
||||
JCS_EXT_BGRX, /* blue/green/red/x */
|
||||
JCS_EXT_XBGR, /* x/blue/green/red */
|
||||
JCS_EXT_XRGB, /* x/red/green/blue */
|
||||
JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
|
||||
JCS_CMYK, /* C/M/Y/K */
|
||||
JCS_YCCK, /* Y/Cb/Cr/K */
|
||||
JCS_EXT_RGB, /* red/green/blue */
|
||||
JCS_EXT_RGBX, /* red/green/blue/x */
|
||||
JCS_EXT_BGR, /* blue/green/red */
|
||||
JCS_EXT_BGRX, /* blue/green/red/x */
|
||||
JCS_EXT_XBGR, /* x/blue/green/red */
|
||||
JCS_EXT_XRGB, /* x/red/green/blue */
|
||||
/* When out_color_space it set to JCS_EXT_RGBX, JCS_EXT_BGRX, JCS_EXT_XBGR,
|
||||
or JCS_EXT_XRGB during decompression, the X byte is undefined, and in
|
||||
order to ensure the best performance, libjpeg-turbo can set that byte to
|
||||
whatever value it wishes. Use the following colorspace constants to
|
||||
ensure that the X byte is set to 0xFF, so that it can be interpreted as an
|
||||
opaque alpha channel. */
|
||||
JCS_EXT_RGBA, /* red/green/blue/alpha */
|
||||
JCS_EXT_BGRA, /* blue/green/red/alpha */
|
||||
JCS_EXT_ABGR, /* alpha/blue/green/red */
|
||||
JCS_EXT_RGBA, /* red/green/blue/alpha */
|
||||
JCS_EXT_BGRA, /* blue/green/red/alpha */
|
||||
JCS_EXT_ABGR, /* alpha/blue/green/red */
|
||||
JCS_EXT_ARGB, /* alpha/red/green/blue */
|
||||
JCS_RGB565 /* 5-bit red/6-bit green/5-bit blue */
|
||||
} J_COLOR_SPACE;
|
||||
@@ -244,43 +244,43 @@ typedef enum {
|
||||
/* DCT/IDCT algorithm options. */
|
||||
|
||||
typedef enum {
|
||||
JDCT_ISLOW, /* slow but accurate integer algorithm */
|
||||
JDCT_IFAST, /* faster, less accurate integer method */
|
||||
JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
|
||||
JDCT_ISLOW, /* slow but accurate integer algorithm */
|
||||
JDCT_IFAST, /* faster, less accurate integer method */
|
||||
JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
|
||||
} J_DCT_METHOD;
|
||||
|
||||
#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
|
||||
#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
|
||||
#define JDCT_DEFAULT JDCT_ISLOW
|
||||
#endif
|
||||
#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
|
||||
#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
|
||||
#define JDCT_FASTEST JDCT_IFAST
|
||||
#endif
|
||||
|
||||
/* Dithering options for decompression. */
|
||||
|
||||
typedef enum {
|
||||
JDITHER_NONE, /* no dithering */
|
||||
JDITHER_ORDERED, /* simple ordered dither */
|
||||
JDITHER_FS /* Floyd-Steinberg error diffusion dither */
|
||||
JDITHER_NONE, /* no dithering */
|
||||
JDITHER_ORDERED, /* simple ordered dither */
|
||||
JDITHER_FS /* Floyd-Steinberg error diffusion dither */
|
||||
} J_DITHER_MODE;
|
||||
|
||||
|
||||
/* Common fields between JPEG compression and decompression master structs. */
|
||||
|
||||
#define jpeg_common_fields \
|
||||
struct jpeg_error_mgr * err; /* Error handler module */\
|
||||
struct jpeg_memory_mgr * mem; /* Memory manager module */\
|
||||
struct jpeg_error_mgr * err; /* Error handler module */\
|
||||
struct jpeg_memory_mgr * mem; /* Memory manager module */\
|
||||
struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
|
||||
void * client_data; /* Available for use by application */\
|
||||
boolean is_decompressor; /* So common code can tell which is which */\
|
||||
int global_state /* For checking call sequence validity */
|
||||
void * client_data; /* Available for use by application */\
|
||||
boolean is_decompressor; /* So common code can tell which is which */\
|
||||
int global_state /* For checking call sequence validity */
|
||||
|
||||
/* Routines that are to be used by both halves of the library are declared
|
||||
* to receive a pointer to this structure. There are no actual instances of
|
||||
* jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
|
||||
*/
|
||||
struct jpeg_common_struct {
|
||||
jpeg_common_fields; /* Fields common to both master struct types */
|
||||
jpeg_common_fields; /* Fields common to both master struct types */
|
||||
/* Additional fields follow in an actual jpeg_compress_struct or
|
||||
* jpeg_decompress_struct. All three structs must agree on these
|
||||
* initial fields! (This would be a lot cleaner in C++.)
|
||||
@@ -295,7 +295,7 @@ typedef struct jpeg_decompress_struct * j_decompress_ptr;
|
||||
/* Master record for a compression instance */
|
||||
|
||||
struct jpeg_compress_struct {
|
||||
jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
|
||||
jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
|
||||
|
||||
/* Destination for compressed data */
|
||||
struct jpeg_destination_mgr * dest;
|
||||
@@ -305,12 +305,12 @@ struct jpeg_compress_struct {
|
||||
* be correct before you can even call jpeg_set_defaults().
|
||||
*/
|
||||
|
||||
JDIMENSION image_width; /* input image width */
|
||||
JDIMENSION image_height; /* input image height */
|
||||
int input_components; /* # of color components in input image */
|
||||
J_COLOR_SPACE in_color_space; /* colorspace of input image */
|
||||
JDIMENSION image_width; /* input image width */
|
||||
JDIMENSION image_height; /* input image height */
|
||||
int input_components; /* # of color components in input image */
|
||||
J_COLOR_SPACE in_color_space; /* colorspace of input image */
|
||||
|
||||
double input_gamma; /* image gamma of input image */
|
||||
double input_gamma; /* image gamma of input image */
|
||||
|
||||
/* Compression parameters --- these fields must be set before calling
|
||||
* jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
|
||||
@@ -323,8 +323,8 @@ struct jpeg_compress_struct {
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
|
||||
|
||||
JDIMENSION jpeg_width; /* scaled JPEG image width */
|
||||
JDIMENSION jpeg_height; /* scaled JPEG image height */
|
||||
JDIMENSION jpeg_width; /* scaled JPEG image width */
|
||||
JDIMENSION jpeg_height; /* scaled JPEG image height */
|
||||
/* Dimensions of actual JPEG image that will be written to file,
|
||||
* derived from input dimensions by scaling factors above.
|
||||
* These fields are computed by jpeg_start_compress().
|
||||
@@ -333,9 +333,9 @@ struct jpeg_compress_struct {
|
||||
*/
|
||||
#endif
|
||||
|
||||
int data_precision; /* bits of precision in image data */
|
||||
int data_precision; /* bits of precision in image data */
|
||||
|
||||
int num_components; /* # of color components in JPEG image */
|
||||
int num_components; /* # of color components in JPEG image */
|
||||
J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
|
||||
|
||||
jpeg_component_info * comp_info;
|
||||
@@ -357,27 +357,29 @@ struct jpeg_compress_struct {
|
||||
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
|
||||
UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
|
||||
|
||||
int num_scans; /* # of entries in scan_info array */
|
||||
int num_scans; /* # of entries in scan_info array */
|
||||
const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
|
||||
/* The default value of scan_info is NULL, which causes a single-scan
|
||||
* sequential JPEG file to be emitted. To create a multi-scan file,
|
||||
* set num_scans and scan_info to point to an array of scan definitions.
|
||||
*/
|
||||
|
||||
boolean raw_data_in; /* TRUE=caller supplies downsampled data */
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
|
||||
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
|
||||
boolean raw_data_in; /* TRUE=caller supplies downsampled data */
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
|
||||
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
|
||||
#endif
|
||||
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
|
||||
J_DCT_METHOD dct_method; /* DCT algorithm selector */
|
||||
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
|
||||
J_DCT_METHOD dct_method; /* DCT algorithm selector */
|
||||
|
||||
boolean use_moz_defaults; /* TRUE=use Mozilla defaults */
|
||||
boolean optimize_scans; /* TRUE=optimize progressive coding scans */
|
||||
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_dc; /* TRUE=use trellis quant for DC coefficient */
|
||||
boolean trellis_eob_opt; /* TRUE=optimize for sequences of EOB */
|
||||
boolean use_flat_quant_tbl; /* TRUE=use flat quantization table */
|
||||
boolean use_lambda_weight_tbl; /* TRUE=use lambda weighting table */
|
||||
@@ -408,28 +410,28 @@ struct jpeg_compress_struct {
|
||||
* for each scan).
|
||||
*/
|
||||
unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
|
||||
int restart_in_rows; /* if > 0, MCU rows per restart interval */
|
||||
int restart_in_rows; /* if > 0, MCU rows per restart interval */
|
||||
|
||||
/* Parameters controlling emission of special markers. */
|
||||
|
||||
boolean write_JFIF_header; /* should a JFIF marker be written? */
|
||||
UINT8 JFIF_major_version; /* What to write for the JFIF version number */
|
||||
boolean write_JFIF_header; /* should a JFIF marker be written? */
|
||||
UINT8 JFIF_major_version; /* What to write for the JFIF version number */
|
||||
UINT8 JFIF_minor_version;
|
||||
/* These three values are not used by the JPEG code, merely copied */
|
||||
/* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
|
||||
/* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
|
||||
/* ratio is defined by X_density/Y_density even when density_unit=0. */
|
||||
UINT8 density_unit; /* JFIF code for pixel size units */
|
||||
UINT16 X_density; /* Horizontal pixel density */
|
||||
UINT16 Y_density; /* Vertical pixel density */
|
||||
boolean write_Adobe_marker; /* should an Adobe marker be written? */
|
||||
|
||||
UINT8 density_unit; /* JFIF code for pixel size units */
|
||||
UINT16 X_density; /* Horizontal pixel density */
|
||||
UINT16 Y_density; /* Vertical pixel density */
|
||||
boolean write_Adobe_marker; /* should an Adobe marker be written? */
|
||||
|
||||
/* State variable: index of next scanline to be written to
|
||||
* jpeg_write_scanlines(). Application may use this to control its
|
||||
* processing loop, e.g., "while (next_scanline < image_height)".
|
||||
*/
|
||||
|
||||
JDIMENSION next_scanline; /* 0 .. image_height-1 */
|
||||
JDIMENSION next_scanline; /* 0 .. image_height-1 */
|
||||
|
||||
/* Remaining fields are known throughout compressor, but generally
|
||||
* should not be touched by a surrounding application.
|
||||
@@ -438,44 +440,44 @@ struct jpeg_compress_struct {
|
||||
/*
|
||||
* These fields are computed during compression startup
|
||||
*/
|
||||
boolean progressive_mode; /* TRUE if scan script uses progressive mode */
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
boolean progressive_mode; /* TRUE if scan script uses progressive mode */
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
#endif
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
|
||||
/* The coefficient controller receives data in units of MCU rows as defined
|
||||
* for fully interleaved scans (whether the JPEG file is interleaved or not).
|
||||
* There are v_samp_factor * DCTSIZE sample rows of each component in an
|
||||
* "iMCU" (interleaved MCU) row.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* These fields are valid during any one scan.
|
||||
* They describe the components and MCUs actually appearing in the scan.
|
||||
*/
|
||||
int comps_in_scan; /* # of JPEG components in this scan */
|
||||
int comps_in_scan; /* # of JPEG components in this scan */
|
||||
jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
|
||||
/* *cur_comp_info[i] describes component that appears i'th in SOS */
|
||||
|
||||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
|
||||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
int MCU_membership[C_MAX_BLOCKS_IN_MCU];
|
||||
/* MCU_membership[i] is index in cur_comp_info of component owning */
|
||||
/* i'th block in an MCU */
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
const int * natural_order; /* natural-order position array */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) */
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
const int * natural_order; /* natural-order position array */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) */
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -498,7 +500,7 @@ struct jpeg_compress_struct {
|
||||
/* Master record for a decompression instance */
|
||||
|
||||
struct jpeg_decompress_struct {
|
||||
jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
|
||||
jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
|
||||
|
||||
/* Source of compressed data */
|
||||
struct jpeg_source_mgr * src;
|
||||
@@ -506,9 +508,9 @@ struct jpeg_decompress_struct {
|
||||
/* Basic description of image --- filled in by jpeg_read_header(). */
|
||||
/* Application may inspect these values to decide how to process image. */
|
||||
|
||||
JDIMENSION image_width; /* nominal image width (from SOF marker) */
|
||||
JDIMENSION image_height; /* nominal image height */
|
||||
int num_components; /* # of color components in JPEG image */
|
||||
JDIMENSION image_width; /* nominal image width (from SOF marker) */
|
||||
JDIMENSION image_height; /* nominal image height */
|
||||
int num_components; /* # of color components in JPEG image */
|
||||
J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
|
||||
|
||||
/* Decompression processing parameters --- these fields must be set before
|
||||
@@ -520,24 +522,24 @@ struct jpeg_decompress_struct {
|
||||
|
||||
unsigned int scale_num, scale_denom; /* fraction by which to scale image */
|
||||
|
||||
double output_gamma; /* image gamma wanted in output */
|
||||
double output_gamma; /* image gamma wanted in output */
|
||||
|
||||
boolean buffered_image; /* TRUE=multiple output passes */
|
||||
boolean raw_data_out; /* TRUE=downsampled data wanted */
|
||||
boolean buffered_image; /* TRUE=multiple output passes */
|
||||
boolean raw_data_out; /* TRUE=downsampled data wanted */
|
||||
|
||||
J_DCT_METHOD dct_method; /* IDCT algorithm selector */
|
||||
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
|
||||
boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
|
||||
J_DCT_METHOD dct_method; /* IDCT algorithm selector */
|
||||
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
|
||||
boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
|
||||
|
||||
boolean quantize_colors; /* TRUE=colormapped output wanted */
|
||||
boolean quantize_colors; /* TRUE=colormapped output wanted */
|
||||
/* the following are ignored if not quantize_colors: */
|
||||
J_DITHER_MODE dither_mode; /* type of color dithering to use */
|
||||
boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
|
||||
int desired_number_of_colors; /* max # colors to use in created colormap */
|
||||
J_DITHER_MODE dither_mode; /* type of color dithering to use */
|
||||
boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
|
||||
int desired_number_of_colors; /* max # colors to use in created colormap */
|
||||
/* these are significant only in buffered-image mode: */
|
||||
boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
|
||||
boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
|
||||
boolean enable_external_quant;/* enable future use of external colormap */
|
||||
boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
|
||||
boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
|
||||
|
||||
/* Description of actual output image that will be returned to application.
|
||||
* These fields are computed by jpeg_start_decompress().
|
||||
@@ -545,14 +547,14 @@ struct jpeg_decompress_struct {
|
||||
* in advance of calling jpeg_start_decompress().
|
||||
*/
|
||||
|
||||
JDIMENSION output_width; /* scaled image width */
|
||||
JDIMENSION output_height; /* scaled image height */
|
||||
int out_color_components; /* # of color components in out_color_space */
|
||||
int output_components; /* # of color components returned */
|
||||
JDIMENSION output_width; /* scaled image width */
|
||||
JDIMENSION output_height; /* scaled image height */
|
||||
int out_color_components; /* # of color components in out_color_space */
|
||||
int output_components; /* # of color components returned */
|
||||
/* output_components is 1 (a colormap index) when quantizing colors;
|
||||
* otherwise it equals out_color_components.
|
||||
*/
|
||||
int rec_outbuf_height; /* min recommended height of scanline buffer */
|
||||
int rec_outbuf_height; /* min recommended height of scanline buffer */
|
||||
/* If the buffer passed to jpeg_read_scanlines() is less than this many rows
|
||||
* high, space and time will be wasted due to unnecessary data copying.
|
||||
* Usually rec_outbuf_height will be 1 or 2, at most 4.
|
||||
@@ -564,8 +566,8 @@ struct jpeg_decompress_struct {
|
||||
* jpeg_start_decompress or jpeg_start_output.
|
||||
* The map has out_color_components rows and actual_number_of_colors columns.
|
||||
*/
|
||||
int actual_number_of_colors; /* number of entries in use */
|
||||
JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
|
||||
int actual_number_of_colors; /* number of entries in use */
|
||||
JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
|
||||
|
||||
/* State variables: these variables indicate the progress of decompression.
|
||||
* The application may examine these but must not modify them.
|
||||
@@ -575,20 +577,20 @@ struct jpeg_decompress_struct {
|
||||
* Application may use this to control its processing loop, e.g.,
|
||||
* "while (output_scanline < output_height)".
|
||||
*/
|
||||
JDIMENSION output_scanline; /* 0 .. output_height-1 */
|
||||
JDIMENSION output_scanline; /* 0 .. output_height-1 */
|
||||
|
||||
/* Current input scan number and number of iMCU rows completed in scan.
|
||||
* These indicate the progress of the decompressor input side.
|
||||
*/
|
||||
int input_scan_number; /* Number of SOS markers seen so far */
|
||||
JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
|
||||
int input_scan_number; /* Number of SOS markers seen so far */
|
||||
JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
|
||||
|
||||
/* The "output scan number" is the notional scan being displayed by the
|
||||
* output side. The decompressor will not allow output scan/row number
|
||||
* to get ahead of input scan/row, but it can fall arbitrarily far behind.
|
||||
*/
|
||||
int output_scan_number; /* Nominal scan number being displayed */
|
||||
JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
|
||||
int output_scan_number; /* Nominal scan number being displayed */
|
||||
JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
|
||||
|
||||
/* Current progression status. coef_bits[c][i] indicates the precision
|
||||
* with which component c's DCT coefficient i (in zigzag order) is known.
|
||||
@@ -597,7 +599,7 @@ struct jpeg_decompress_struct {
|
||||
* (thus, 0 at completion of the progression).
|
||||
* This pointer is NULL when reading a non-progressive file.
|
||||
*/
|
||||
int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
|
||||
int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
|
||||
|
||||
/* Internal JPEG parameters --- the application usually need not look at
|
||||
* these fields. Note that the decompressor output side may not use
|
||||
@@ -619,16 +621,16 @@ struct jpeg_decompress_struct {
|
||||
* are given in SOF/SOS markers or defined to be reset by SOI.
|
||||
*/
|
||||
|
||||
int data_precision; /* bits of precision in image data */
|
||||
int data_precision; /* bits of precision in image data */
|
||||
|
||||
jpeg_component_info * comp_info;
|
||||
/* comp_info[i] describes component that appears i'th in SOF */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
|
||||
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
|
||||
#endif
|
||||
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
|
||||
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
|
||||
|
||||
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
|
||||
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
|
||||
@@ -639,17 +641,17 @@ struct jpeg_decompress_struct {
|
||||
/* These fields record data obtained from optional markers recognized by
|
||||
* the JPEG library.
|
||||
*/
|
||||
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
|
||||
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
|
||||
/* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
|
||||
UINT8 JFIF_major_version; /* JFIF version number */
|
||||
UINT8 JFIF_major_version; /* JFIF version number */
|
||||
UINT8 JFIF_minor_version;
|
||||
UINT8 density_unit; /* JFIF code for pixel size units */
|
||||
UINT16 X_density; /* Horizontal pixel density */
|
||||
UINT16 Y_density; /* Vertical pixel density */
|
||||
boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
|
||||
UINT8 Adobe_transform; /* Color transform code from Adobe marker */
|
||||
UINT8 density_unit; /* JFIF code for pixel size units */
|
||||
UINT16 X_density; /* Horizontal pixel density */
|
||||
UINT16 Y_density; /* Vertical pixel density */
|
||||
boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
|
||||
UINT8 Adobe_transform; /* Color transform code from Adobe marker */
|
||||
|
||||
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
|
||||
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
|
||||
|
||||
/* Aside from the specific data retained from APPn markers known to the
|
||||
* library, the uninterpreted contents of any or all APPn and COM markers
|
||||
@@ -664,17 +666,17 @@ struct jpeg_decompress_struct {
|
||||
/*
|
||||
* These fields are computed during decompression startup
|
||||
*/
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
int max_h_samp_factor; /* largest h_samp_factor */
|
||||
int max_v_samp_factor; /* largest v_samp_factor */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
int min_DCT_h_scaled_size; /* smallest DCT_h_scaled_size of any component */
|
||||
int min_DCT_v_scaled_size; /* smallest DCT_v_scaled_size of any component */
|
||||
#else
|
||||
int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
|
||||
int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
|
||||
#endif
|
||||
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
|
||||
JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
|
||||
/* The coefficient controller's input and output progress is measured in
|
||||
* units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
|
||||
* in fully interleaved JPEG scans, but are used whether the scan is
|
||||
@@ -690,26 +692,26 @@ struct jpeg_decompress_struct {
|
||||
* They describe the components and MCUs actually appearing in the scan.
|
||||
* Note that the decompressor output side must not use these fields.
|
||||
*/
|
||||
int comps_in_scan; /* # of JPEG components in this scan */
|
||||
int comps_in_scan; /* # of JPEG components in this scan */
|
||||
jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
|
||||
/* *cur_comp_info[i] describes component that appears i'th in SOS */
|
||||
|
||||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
JDIMENSION MCUs_per_row; /* # of MCUs across the image */
|
||||
JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
|
||||
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
int blocks_in_MCU; /* # of DCT blocks per MCU */
|
||||
int MCU_membership[D_MAX_BLOCKS_IN_MCU];
|
||||
/* MCU_membership[i] is index in cur_comp_info of component owning */
|
||||
/* i'th block in an MCU */
|
||||
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
|
||||
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
/* These fields are derived from Se of first SOS marker.
|
||||
*/
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
int block_size; /* the basic DCT block size: 1..16 */
|
||||
const int * natural_order; /* natural-order position array for entropy decode */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
|
||||
int lim_Se; /* min( Se, DCTSIZE2-1 ) for entropy decode */
|
||||
#endif
|
||||
|
||||
/* This field is shared between entropy decoder and marker parser.
|
||||
@@ -754,10 +756,10 @@ struct jpeg_error_mgr {
|
||||
void (*output_message) (j_common_ptr cinfo);
|
||||
/* Format a message string for the most recent JPEG error or message */
|
||||
void (*format_message) (j_common_ptr cinfo, char * buffer);
|
||||
#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
|
||||
#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
|
||||
/* Reset error state variables at start of a new image */
|
||||
void (*reset_error_mgr) (j_common_ptr cinfo);
|
||||
|
||||
|
||||
/* The message ID code and any parameters are saved here.
|
||||
* A message can have one string parameter or up to 8 int parameters.
|
||||
*/
|
||||
@@ -767,18 +769,18 @@ struct jpeg_error_mgr {
|
||||
int i[8];
|
||||
char s[JMSG_STR_PARM_MAX];
|
||||
} msg_parm;
|
||||
|
||||
|
||||
/* Standard state variables for error facility */
|
||||
|
||||
int trace_level; /* max msg_level that will be displayed */
|
||||
|
||||
|
||||
int trace_level; /* max msg_level that will be displayed */
|
||||
|
||||
/* For recoverable corrupt-data errors, we emit a warning message,
|
||||
* but keep going unless emit_message chooses to abort. emit_message
|
||||
* should count warnings in num_warnings. The surrounding application
|
||||
* can check for bad data by seeing if num_warnings is nonzero at the
|
||||
* end of processing.
|
||||
*/
|
||||
long num_warnings; /* number of corrupt-data warnings */
|
||||
long num_warnings; /* number of corrupt-data warnings */
|
||||
|
||||
/* These fields point to the table(s) of error message strings.
|
||||
* An application can change the table pointer to switch to a different
|
||||
@@ -796,8 +798,8 @@ struct jpeg_error_mgr {
|
||||
* It contains strings numbered first_addon_message..last_addon_message.
|
||||
*/
|
||||
const char * const * addon_message_table; /* Non-library errors */
|
||||
int first_addon_message; /* code for first string in addon table */
|
||||
int last_addon_message; /* code for last string in addon table */
|
||||
int first_addon_message; /* code for first string in addon table */
|
||||
int last_addon_message; /* code for last string in addon table */
|
||||
};
|
||||
|
||||
|
||||
@@ -806,18 +808,18 @@ struct jpeg_error_mgr {
|
||||
struct jpeg_progress_mgr {
|
||||
void (*progress_monitor) (j_common_ptr cinfo);
|
||||
|
||||
long pass_counter; /* work units completed in this pass */
|
||||
long pass_limit; /* total number of work units in this pass */
|
||||
int completed_passes; /* passes completed so far */
|
||||
int total_passes; /* total number of passes expected */
|
||||
long pass_counter; /* work units completed in this pass */
|
||||
long pass_limit; /* total number of work units in this pass */
|
||||
int completed_passes; /* passes completed so far */
|
||||
int total_passes; /* total number of passes expected */
|
||||
};
|
||||
|
||||
|
||||
/* Data destination object for compression */
|
||||
|
||||
struct jpeg_destination_mgr {
|
||||
JOCTET * next_output_byte; /* => next byte to write in buffer */
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
JOCTET * next_output_byte; /* => next byte to write in buffer */
|
||||
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
|
||||
|
||||
void (*init_destination) (j_compress_ptr cinfo);
|
||||
boolean (*empty_output_buffer) (j_compress_ptr cinfo);
|
||||
@@ -829,7 +831,7 @@ struct jpeg_destination_mgr {
|
||||
|
||||
struct jpeg_source_mgr {
|
||||
const JOCTET * next_input_byte; /* => next byte to read from buffer */
|
||||
size_t bytes_in_buffer; /* # of bytes remaining in buffer */
|
||||
size_t bytes_in_buffer; /* # of bytes remaining in buffer */
|
||||
|
||||
void (*init_source) (j_decompress_ptr cinfo);
|
||||
boolean (*fill_input_buffer) (j_decompress_ptr cinfo);
|
||||
@@ -850,9 +852,9 @@ struct jpeg_source_mgr {
|
||||
* successful.
|
||||
*/
|
||||
|
||||
#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
|
||||
#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
|
||||
#define JPOOL_NUMPOOLS 2
|
||||
#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
|
||||
#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
|
||||
#define JPOOL_NUMPOOLS 2
|
||||
|
||||
typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
|
||||
typedef struct jvirt_barray_control * jvirt_barray_ptr;
|
||||
@@ -868,14 +870,14 @@ struct jpeg_memory_mgr {
|
||||
JBLOCKARRAY (*alloc_barray) (j_common_ptr cinfo, int pool_id,
|
||||
JDIMENSION blocksperrow, JDIMENSION numrows);
|
||||
jvirt_sarray_ptr (*request_virt_sarray) (j_common_ptr cinfo, int pool_id,
|
||||
boolean pre_zero,
|
||||
JDIMENSION samplesperrow,
|
||||
JDIMENSION numrows,
|
||||
boolean pre_zero,
|
||||
JDIMENSION samplesperrow,
|
||||
JDIMENSION numrows,
|
||||
JDIMENSION maxaccess);
|
||||
jvirt_barray_ptr (*request_virt_barray) (j_common_ptr cinfo, int pool_id,
|
||||
boolean pre_zero,
|
||||
JDIMENSION blocksperrow,
|
||||
JDIMENSION numrows,
|
||||
boolean pre_zero,
|
||||
JDIMENSION blocksperrow,
|
||||
JDIMENSION numrows,
|
||||
JDIMENSION maxaccess);
|
||||
void (*realize_virt_arrays) (j_common_ptr cinfo);
|
||||
JSAMPARRAY (*access_virt_sarray) (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
|
||||
@@ -917,10 +919,10 @@ EXTERN(struct jpeg_error_mgr *) jpeg_std_error (struct jpeg_error_mgr * err);
|
||||
*/
|
||||
#define jpeg_create_compress(cinfo) \
|
||||
jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
|
||||
(size_t) sizeof(struct jpeg_compress_struct))
|
||||
(size_t) sizeof(struct jpeg_compress_struct))
|
||||
#define jpeg_create_decompress(cinfo) \
|
||||
jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
|
||||
(size_t) sizeof(struct jpeg_decompress_struct))
|
||||
(size_t) sizeof(struct jpeg_decompress_struct))
|
||||
EXTERN(void) jpeg_CreateCompress (j_compress_ptr cinfo, int version,
|
||||
size_t structsize);
|
||||
EXTERN(void) jpeg_CreateDecompress (j_decompress_ptr cinfo, int version,
|
||||
@@ -957,9 +959,10 @@ EXTERN(void) jpeg_default_qtables (j_compress_ptr cinfo,
|
||||
boolean force_baseline);
|
||||
#endif
|
||||
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);
|
||||
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_suppress_tables (j_compress_ptr cinfo, boolean suppress);
|
||||
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table (j_common_ptr cinfo);
|
||||
@@ -969,7 +972,7 @@ EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table (j_common_ptr cinfo);
|
||||
EXTERN(void) jpeg_start_compress (j_compress_ptr cinfo,
|
||||
boolean write_all_tables);
|
||||
EXTERN(JDIMENSION) jpeg_write_scanlines (j_compress_ptr cinfo,
|
||||
JSAMPARRAY scanlines,
|
||||
JSAMPARRAY scanlines,
|
||||
JDIMENSION num_lines);
|
||||
EXTERN(void) jpeg_finish_compress (j_compress_ptr cinfo);
|
||||
|
||||
@@ -996,9 +999,9 @@ EXTERN(void) jpeg_write_tables (j_compress_ptr cinfo);
|
||||
/* Decompression startup: read start of JPEG datastream to see what's there */
|
||||
EXTERN(int) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image);
|
||||
/* Return value is one of: */
|
||||
#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
|
||||
#define JPEG_HEADER_OK 1 /* Found valid image datastream */
|
||||
#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
|
||||
#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
|
||||
#define JPEG_HEADER_OK 1 /* Found valid image datastream */
|
||||
#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
|
||||
/* If you pass require_image = TRUE (normal case), you need not check for
|
||||
* a TABLES_ONLY return code; an abbreviated file will cause an error exit.
|
||||
* JPEG_SUSPENDED is only possible if you use a data source module that can
|
||||
@@ -1008,7 +1011,7 @@ EXTERN(int) jpeg_read_header (j_decompress_ptr cinfo, boolean require_image);
|
||||
/* Main entry points for decompression */
|
||||
EXTERN(boolean) jpeg_start_decompress (j_decompress_ptr cinfo);
|
||||
EXTERN(JDIMENSION) jpeg_read_scanlines (j_decompress_ptr cinfo,
|
||||
JSAMPARRAY scanlines,
|
||||
JSAMPARRAY scanlines,
|
||||
JDIMENSION max_lines);
|
||||
EXTERN(boolean) jpeg_finish_decompress (j_decompress_ptr cinfo);
|
||||
|
||||
@@ -1024,11 +1027,11 @@ EXTERN(boolean) jpeg_input_complete (j_decompress_ptr cinfo);
|
||||
EXTERN(void) jpeg_new_colormap (j_decompress_ptr cinfo);
|
||||
EXTERN(int) jpeg_consume_input (j_decompress_ptr cinfo);
|
||||
/* Return value is one of: */
|
||||
/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
|
||||
#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
|
||||
#define JPEG_REACHED_EOI 2 /* Reached end of image */
|
||||
#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
|
||||
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
|
||||
/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
|
||||
#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
|
||||
#define JPEG_REACHED_EOI 2 /* Reached end of image */
|
||||
#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
|
||||
#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
|
||||
|
||||
/* Precalculate output dimensions for current decompression parameters. */
|
||||
#if JPEG_LIB_VERSION >= 80
|
||||
@@ -1075,10 +1078,10 @@ EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired);
|
||||
* are likely to want to use them.
|
||||
*/
|
||||
|
||||
#define JPEG_RST0 0xD0 /* RST0 marker code */
|
||||
#define JPEG_EOI 0xD9 /* EOI marker code */
|
||||
#define JPEG_APP0 0xE0 /* APP0 marker code */
|
||||
#define JPEG_COM 0xFE /* COM marker code */
|
||||
#define JPEG_RST0 0xD0 /* RST0 marker code */
|
||||
#define JPEG_EOI 0xD9 /* EOI marker code */
|
||||
#define JPEG_APP0 0xE0 /* APP0 marker code */
|
||||
#define JPEG_COM 0xFE /* COM marker code */
|
||||
|
||||
|
||||
/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
|
||||
@@ -1087,7 +1090,7 @@ EXTERN(boolean) jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired);
|
||||
*/
|
||||
|
||||
#ifdef INCOMPLETE_TYPES_BROKEN
|
||||
#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
|
||||
#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
|
||||
struct jvirt_sarray_control { long dummy; };
|
||||
struct jvirt_barray_control { long dummy; };
|
||||
struct jpeg_comp_master { long dummy; };
|
||||
@@ -1122,8 +1125,8 @@ struct jpeg_color_quantizer { long dummy; };
|
||||
*/
|
||||
|
||||
#ifdef JPEG_INTERNALS
|
||||
#include "jpegint.h" /* fetch private declarations */
|
||||
#include "jerror.h" /* fetch error codes too */
|
||||
#include "jpegint.h" /* fetch private declarations */
|
||||
#include "jerror.h" /* fetch error codes too */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -104,11 +104,19 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
yuv_size = luma_width*luma_height + 2*chroma_width*chroma_height;
|
||||
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_height = (cinfo.output_height + (16 - 1)) & ~(16 - 1);
|
||||
|
||||
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[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
|
||||
104
rdswitch.c
104
rdswitch.c
@@ -9,15 +9,15 @@
|
||||
*
|
||||
* This file contains routines to process some of cjpeg's more complicated
|
||||
* command-line switches. Switches processed here are:
|
||||
* -qtables file Read quantization tables from text file
|
||||
* -scans file Read scan script from text file
|
||||
* -quality N[,N,...] Set quality ratings
|
||||
* -qslots N[,N,...] Set component quantization table selectors
|
||||
* -sample HxV[,HxV,...] Set component sampling factors
|
||||
* -qtables file Read quantization tables from text file
|
||||
* -scans file Read scan script from text file
|
||||
* -quality N[,N,...] Set quality ratings
|
||||
* -qslots N[,N,...] Set component quantization table selectors
|
||||
* -sample HxV[,HxV,...] Set component sampling factors
|
||||
*/
|
||||
|
||||
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
|
||||
#include <ctype.h> /* to declare isdigit(), isspace() */
|
||||
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
|
||||
#include <ctype.h> /* to declare isdigit(), isspace() */
|
||||
|
||||
|
||||
LOCAL(int)
|
||||
@@ -26,7 +26,7 @@ text_getc (FILE * file)
|
||||
/* A comment/newline sequence is returned as a newline */
|
||||
{
|
||||
register int ch;
|
||||
|
||||
|
||||
ch = getc(file);
|
||||
if (ch == '#') {
|
||||
do {
|
||||
@@ -44,7 +44,7 @@ read_text_integer (FILE * file, long * result, int * termchar)
|
||||
{
|
||||
register int ch;
|
||||
register long val;
|
||||
|
||||
|
||||
/* Skip any leading whitespace, detect EOF */
|
||||
do {
|
||||
ch = text_getc(file);
|
||||
@@ -53,7 +53,7 @@ read_text_integer (FILE * file, long * result, int * termchar)
|
||||
return FALSE;
|
||||
}
|
||||
} while (isspace(ch));
|
||||
|
||||
|
||||
if (! isdigit(ch)) {
|
||||
*termchar = ch;
|
||||
return FALSE;
|
||||
@@ -108,15 +108,15 @@ read_quant_tables (j_compress_ptr cinfo, char * filename, boolean force_baseline
|
||||
table[0] = (unsigned int) val;
|
||||
for (i = 1; i < DCTSIZE2; i++) {
|
||||
if (! read_text_integer(fp, &val, &termchar)) {
|
||||
fprintf(stderr, "Invalid table data in file %s\n", filename);
|
||||
fclose(fp);
|
||||
return FALSE;
|
||||
fprintf(stderr, "Invalid table data in file %s\n", filename);
|
||||
fclose(fp);
|
||||
return FALSE;
|
||||
}
|
||||
table[i] = (unsigned int) val;
|
||||
}
|
||||
#if JPEG_LIB_VERSION >= 70
|
||||
jpeg_add_quant_table(cinfo, tblno, table, cinfo->q_scale_factor[tblno],
|
||||
force_baseline);
|
||||
force_baseline);
|
||||
#else
|
||||
jpeg_add_quant_table(cinfo, tblno, table, q_scale_factor[tblno],
|
||||
force_baseline);
|
||||
@@ -150,7 +150,7 @@ read_scan_integer (FILE * file, long * result, int * termchar)
|
||||
ch = *termchar;
|
||||
while (ch != EOF && isspace(ch))
|
||||
ch = text_getc(file);
|
||||
if (isdigit(ch)) { /* oops, put it back */
|
||||
if (isdigit(ch)) { /* oops, put it back */
|
||||
if (ungetc(ch, file) == EOF)
|
||||
return FALSE;
|
||||
ch = ' ';
|
||||
@@ -188,7 +188,7 @@ read_scan_script (j_compress_ptr cinfo, char * filename)
|
||||
int scanno, ncomps, termchar;
|
||||
long val;
|
||||
jpeg_scan_info * scanptr;
|
||||
#define MAX_SCANS 100 /* quite arbitrary limit */
|
||||
#define MAX_SCANS 100 /* quite arbitrary limit */
|
||||
jpeg_scan_info scans[MAX_SCANS];
|
||||
|
||||
if ((fp = fopen(filename, "r")) == NULL) {
|
||||
@@ -208,29 +208,29 @@ read_scan_script (j_compress_ptr cinfo, char * filename)
|
||||
ncomps = 1;
|
||||
while (termchar == ' ') {
|
||||
if (ncomps >= MAX_COMPS_IN_SCAN) {
|
||||
fprintf(stderr, "Too many components in one scan in file %s\n",
|
||||
filename);
|
||||
fclose(fp);
|
||||
return FALSE;
|
||||
fprintf(stderr, "Too many components in one scan in file %s\n",
|
||||
filename);
|
||||
fclose(fp);
|
||||
return FALSE;
|
||||
}
|
||||
if (! read_scan_integer(fp, &val, &termchar))
|
||||
goto bogus;
|
||||
goto bogus;
|
||||
scanptr->component_index[ncomps] = (int) val;
|
||||
ncomps++;
|
||||
}
|
||||
scanptr->comps_in_scan = ncomps;
|
||||
if (termchar == ':') {
|
||||
if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
|
||||
goto bogus;
|
||||
goto bogus;
|
||||
scanptr->Ss = (int) val;
|
||||
if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
|
||||
goto bogus;
|
||||
goto bogus;
|
||||
scanptr->Se = (int) val;
|
||||
if (! read_scan_integer(fp, &val, &termchar) || termchar != ' ')
|
||||
goto bogus;
|
||||
goto bogus;
|
||||
scanptr->Ah = (int) val;
|
||||
if (! read_scan_integer(fp, &val, &termchar))
|
||||
goto bogus;
|
||||
goto bogus;
|
||||
scanptr->Al = (int) val;
|
||||
} else {
|
||||
/* set non-progressive parameters */
|
||||
@@ -320,11 +320,11 @@ jpeg_default_qtables (j_compress_ptr cinfo, boolean force_baseline)
|
||||
jpeg_add_quant_table(cinfo, 1, flat_quant_tbl,
|
||||
q_scale_factor[1], force_baseline);
|
||||
} else {
|
||||
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
|
||||
q_scale_factor[0], force_baseline);
|
||||
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
|
||||
q_scale_factor[1], force_baseline);
|
||||
}
|
||||
jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
|
||||
q_scale_factor[0], force_baseline);
|
||||
jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
|
||||
q_scale_factor[1], force_baseline);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
{
|
||||
int val = 75; /* default value */
|
||||
float val = 75.f; /* default value */
|
||||
int tblno;
|
||||
char ch;
|
||||
|
||||
for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
|
||||
if (*arg) {
|
||||
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;
|
||||
if (ch != ',') /* syntax check */
|
||||
return FALSE;
|
||||
/* Convert user 0-100 rating to percentage scaling */
|
||||
#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
|
||||
q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
||||
q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||
#endif
|
||||
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
||||
;
|
||||
;
|
||||
} else {
|
||||
/* reached end of parameter, set remaining factors to last value */
|
||||
#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
|
||||
q_scale_factor[tblno] = jpeg_quality_scaling(val);
|
||||
q_scale_factor[tblno] = jpeg_float_quality_scaling(val);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -376,25 +376,25 @@ set_quant_slots (j_compress_ptr cinfo, char *arg)
|
||||
* If there are more components than parameters, the last value is replicated.
|
||||
*/
|
||||
{
|
||||
int val = 0; /* default table # */
|
||||
int val = 0; /* default table # */
|
||||
int ci;
|
||||
char ch;
|
||||
|
||||
for (ci = 0; ci < MAX_COMPONENTS; ci++) {
|
||||
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)
|
||||
return FALSE;
|
||||
if (ch != ',') /* syntax check */
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
if (ch != ',') /* syntax check */
|
||||
return FALSE;
|
||||
if (val < 0 || val >= NUM_QUANT_TBLS) {
|
||||
fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
|
||||
NUM_QUANT_TBLS-1);
|
||||
return FALSE;
|
||||
fprintf(stderr, "JPEG quantization tables are numbered 0..%d\n",
|
||||
NUM_QUANT_TBLS-1);
|
||||
return FALSE;
|
||||
}
|
||||
cinfo->comp_info[ci].quant_tbl_no = val;
|
||||
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
||||
;
|
||||
;
|
||||
} else {
|
||||
/* reached end of parameter, set remaining components to last table */
|
||||
cinfo->comp_info[ci].quant_tbl_no = val;
|
||||
@@ -416,19 +416,19 @@ set_sample_factors (j_compress_ptr cinfo, char *arg)
|
||||
|
||||
for (ci = 0; ci < MAX_COMPONENTS; ci++) {
|
||||
if (*arg) {
|
||||
ch2 = ','; /* if not set by sscanf, will be ',' */
|
||||
ch2 = ','; /* if not set by sscanf, will be ',' */
|
||||
if (sscanf(arg, "%d%c%d%c", &val1, &ch1, &val2, &ch2) < 3)
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
if ((ch1 != 'x' && ch1 != 'X') || ch2 != ',') /* syntax check */
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
if (val1 <= 0 || val1 > 4 || val2 <= 0 || val2 > 4) {
|
||||
fprintf(stderr, "JPEG sampling factors must be 1..4\n");
|
||||
return FALSE;
|
||||
fprintf(stderr, "JPEG sampling factors must be 1..4\n");
|
||||
return FALSE;
|
||||
}
|
||||
cinfo->comp_info[ci].h_samp_factor = val1;
|
||||
cinfo->comp_info[ci].v_samp_factor = val2;
|
||||
while (*arg && *arg++ != ',') /* advance to next segment of arg string */
|
||||
;
|
||||
;
|
||||
} else {
|
||||
/* reached end of parameter, set remaining components to 1x1 sampling */
|
||||
cinfo->comp_info[ci].h_samp_factor = 1;
|
||||
|
||||
@@ -41,11 +41,9 @@
|
||||
/* Supplementary macro for setting function attributes */
|
||||
.macro asm_function fname
|
||||
#ifdef __APPLE__
|
||||
.func _\fname
|
||||
.globl _\fname
|
||||
_\fname:
|
||||
#else
|
||||
.func \fname
|
||||
.global \fname
|
||||
#ifdef __ELF__
|
||||
.hidden \fname
|
||||
@@ -670,7 +668,6 @@ asm_function jsimd_idct_islow_neon
|
||||
.unreq ROW6R
|
||||
.unreq ROW7L
|
||||
.unreq ROW7R
|
||||
.endfunc
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -895,7 +892,6 @@ asm_function jsimd_idct_ifast_neon
|
||||
.unreq TMP2
|
||||
.unreq TMP3
|
||||
.unreq TMP4
|
||||
.endfunc
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -1108,7 +1104,6 @@ asm_function jsimd_idct_4x4_neon
|
||||
.unreq TMP2
|
||||
.unreq TMP3
|
||||
.unreq TMP4
|
||||
.endfunc
|
||||
|
||||
.purgem idct_helper
|
||||
|
||||
@@ -1263,7 +1258,6 @@ asm_function jsimd_idct_2x2_neon
|
||||
.unreq OUTPUT_COL
|
||||
.unreq TMP1
|
||||
.unreq TMP2
|
||||
.endfunc
|
||||
|
||||
.purgem idct_helper
|
||||
|
||||
@@ -1547,7 +1541,6 @@ asm_function jsimd_ycc_\colorid\()_convert_neon
|
||||
.unreq U
|
||||
.unreq V
|
||||
.unreq N
|
||||
.endfunc
|
||||
|
||||
.purgem do_yuv_to_rgb
|
||||
.purgem do_yuv_to_rgb_stage1
|
||||
@@ -1858,7 +1851,6 @@ asm_function jsimd_\colorid\()_ycc_convert_neon
|
||||
.unreq U
|
||||
.unreq V
|
||||
.unreq N
|
||||
.endfunc
|
||||
|
||||
.purgem do_rgb_to_yuv
|
||||
.purgem do_rgb_to_yuv_stage1
|
||||
@@ -1940,7 +1932,6 @@ asm_function jsimd_convsamp_neon
|
||||
.unreq TMP2
|
||||
.unreq TMP3
|
||||
.unreq TMP4
|
||||
.endfunc
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2064,7 +2055,6 @@ asm_function jsimd_fdct_ifast_neon
|
||||
|
||||
.unreq DATA
|
||||
.unreq TMP
|
||||
.endfunc
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2166,7 +2156,6 @@ asm_function jsimd_quantize_neon
|
||||
.unreq CORRECTION
|
||||
.unreq SHIFT
|
||||
.unreq LOOP_COUNT
|
||||
.endfunc
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -2401,7 +2390,6 @@ asm_function jsimd_h2v1_fancy_upsample_neon
|
||||
.unreq WIDTH
|
||||
.unreq TMP
|
||||
|
||||
.endfunc
|
||||
|
||||
.purgem upsample16
|
||||
.purgem upsample32
|
||||
|
||||
10
yuvjpeg.c
10
yuvjpeg.c
@@ -179,6 +179,11 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
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) {
|
||||
fprintf(stderr, "Error reading yuv file\n");
|
||||
};
|
||||
@@ -190,6 +195,10 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
image_buffer =
|
||||
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,
|
||||
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");
|
||||
if (!jpg_fd) {
|
||||
fprintf(stderr, "Invalid path to JPEG file!\n");
|
||||
free(image_buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user