From: malaterre Date: Thu, 14 Oct 2004 02:45:31 +0000 (+0000) Subject: ENH: Update the jpeg library. This patch is the result of the ijg lib + ls-patch... X-Git-Tag: Version0.6.bp~76 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=93b600547ab55d2b7b3903c561a06d191d7764d9;p=gdcm.git ENH: Update the jpeg library. This patch is the result of the ijg lib + ls-patch freely available on the web under a BSD like license (aka Standford implementation) + 2 home-made patchs (one based on dcmtk bug-fixes and one from previous ijg bug-fixes in gdcm) - Also removed all tabs using sed -i 's/\t/ /g' *.c *.h --- diff --git a/src/jpeg/libijg/README b/src/jpeg/libijg/README index 86cc2066..24235947 100644 --- a/src/jpeg/libijg/README +++ b/src/jpeg/libijg/README @@ -74,12 +74,12 @@ remarkably high compression levels are possible if you can tolerate a low-quality image. For more details, see the references, or just experiment with various compression settings. -This software implements JPEG baseline, extended-sequential, and progressive -compression processes. Provision is made for supporting all variants of these -processes, although some uncommon parameter settings aren't implemented yet. -For legal reasons, we are not distributing code for the arithmetic-coding -variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting -the hierarchical or lossless processes defined in the standard. +This software implements JPEG baseline, extended-sequential, progressive +and lossless compression processes. Provision is made for supporting all +variants of these processes, although some uncommon parameter settings aren't +implemented yet. For legal reasons, we are not distributing code for the +arithmetic-coding variants of JPEG; see LEGAL ISSUES. We have made no +provision for supporting the hierarchical processes defined in the standard. We provide a set of library routines for reading and writing JPEG image files, plus two sample applications "cjpeg" and "djpeg", which use the library to diff --git a/src/jpeg/libijg/README.GDCM.txt b/src/jpeg/libijg/README.GDCM.txt index 13fcdb04..b1c44238 100644 --- a/src/jpeg/libijg/README.GDCM.txt +++ b/src/jpeg/libijg/README.GDCM.txt @@ -75,3 +75,9 @@ generated using: nm libgdcmijpeg8.a | grep " T " | colrm 1 11 | sort + +5. +In order to read lossless images, we had to apply the ls-patch to jpeg-6b ... to be continued + + +(shoud we disalbe getenv just as dcmtk ? diff --git a/src/jpeg/libijg/filelist.doc b/src/jpeg/libijg/filelist.doc index e14982ca..9ba88e00 100644 --- a/src/jpeg/libijg/filelist.doc +++ b/src/jpeg/libijg/filelist.doc @@ -1,6 +1,6 @@ IJG JPEG LIBRARY: FILE LIST -Copyright (C) 1994-1998, Thomas G. Lane. +Copyright (C) 1994-1997, Thomas G. Lane. This file is part of the Independent JPEG Group's software. For conditions of distribution and use, see the accompanying README file. @@ -28,6 +28,8 @@ jerror.h Declares JPEG library's error and trace message codes. jinclude.h Central include file used by all IJG .c files to reference system include files. jpegint.h JPEG library's internal data structures. +jlossls.h JPEG library's lossless codec data structures. +jlossy.h JPEG library's lossy codec structures. jchuff.h Private declarations for Huffman encoder modules. jdhuff.h Private declarations for Huffman decoder modules. jdct.h Private declarations for forward & reverse DCT subsystems. @@ -64,34 +66,40 @@ Compression side of the library: jcinit.c Initialization: determines which other modules to use. jcmaster.c Master control: setup and inter-pass sequencing logic. jcmainct.c Main buffer controller (preprocessor => JPEG compressor). +jchuff.c Codec-independent Huffman entropy encoding routines. jcprepct.c Preprocessor buffer controller. -jccoefct.c Buffer controller for DCT coefficient buffer. jccolor.c Color space conversion. jcsample.c Downsampling. +jcmarker.c JPEG marker writing. +jdatadst.c Data destination manager for stdio output. + +Lossy (DCT) codec: + +jlossy.c Lossy compressor proper. +jccoefct.c Buffer controller for DCT coefficient buffer. jcdctmgr.c DCT manager (DCT implementation selection & control). jfdctint.c Forward DCT using slow-but-accurate integer method. jfdctfst.c Forward DCT using faster, less accurate integer method. jfdctflt.c Forward DCT using floating-point arithmetic. -jchuff.c Huffman entropy coding for sequential JPEG. +jcshuff.c Huffman entropy coding for sequential JPEG. jcphuff.c Huffman entropy coding for progressive JPEG. -jcmarker.c JPEG marker writing. -jdatadst.c Data destination manager for stdio output. + +Lossless (spatial) codec: + +jclossls.c Lossless compressor proper. +jcdiffct.c Buffer controller for difference buffer. +jcscale.c Point transformation. +jcpred.c Sample predictor and differencer. +jclhuff.c Huffman entropy encoding for lossless JPEG. Decompression side of the library: jdmaster.c Master control: determines which other modules to use. jdinput.c Input controller: controls input processing modules. jdmainct.c Main buffer controller (JPEG decompressor => postprocessor). -jdcoefct.c Buffer controller for DCT coefficient buffer. +jdhuff.c Codec-independent Huffman entropy decoding routines. jdpostct.c Postprocessor buffer controller. jdmarker.c JPEG marker reading. -jdhuff.c Huffman entropy decoding for sequential JPEG. -jdphuff.c Huffman entropy decoding for progressive JPEG. -jddctmgr.c IDCT manager (IDCT implementation selection & control). -jidctint.c Inverse DCT using slow-but-accurate integer method. -jidctfst.c Inverse DCT using faster, less accurate integer method. -jidctflt.c Inverse DCT using floating-point arithmetic. -jidctred.c Inverse DCTs with reduced-size outputs. jdsample.c Upsampling. jdcolor.c Color space conversion. jdmerge.c Merged upsampling/color conversion (faster, lower quality). @@ -100,10 +108,31 @@ jquant2.c Two-pass color quantization using a custom-generated colormap. Also handles one-pass quantization to an externally given map. jdatasrc.c Data source manager for stdio input. +Lossy (DCT) codec: + +jdlossy.c Lossy decompressor proper. +jdcoefct.c Buffer controller for DCT coefficient buffer. +jdshuff.c Huffman entropy decoding for sequential JPEG. +jdphuff.c Huffman entropy decoding for progressive JPEG. +jddctmgr.c IDCT manager (IDCT implementation selection & control). +jidctint.c Inverse DCT using slow-but-accurate integer method. +jidctfst.c Inverse DCT using faster, less accurate integer method. +jidctflt.c Inverse DCT using floating-point arithmetic. +jidctred.c Inverse DCTs with reduced-size outputs. + +Lossless (spatial) codec: + +jdlossls.c Lossless decompressor proper. +jddiffct.c Buffer controller for difference buffers. +jdlhuff.c Huffman entropy decoding for lossless JPEG. +jdpred.c Sample predictor and undifferencer. +jdscale.c Point transformation, sample size scaling. + Support files for both compression and decompression: jerror.c Standard error handling routines (application replaceable). jmemmgr.c System-independent (more or less) memory management code. +jcodec.c Codec-independent utility routines. jutils.c Miscellaneous utility routines. jmemmgr.c relies on a system-dependent memory management module. The IJG diff --git a/src/jpeg/libijg/gdcm_mangle_12bits.h b/src/jpeg/libijg/gdcm_mangle_12bits.h index b65b040a..b0b47fed 100644 --- a/src/jpeg/libijg/gdcm_mangle_12bits.h +++ b/src/jpeg/libijg/gdcm_mangle_12bits.h @@ -15,27 +15,42 @@ nm libgdcmijpeg12.a | grep " T " | colrm 1 11 | sort (actually copy/paste from gdcm_jpeg8bits) */ + + #define jcopy_block_row gdcm_jpeg12_jcopy_block_row #define jcopy_sample_rows gdcm_jpeg12_jcopy_sample_rows #define jdiv_round_up gdcm_jpeg12_jdiv_round_up #define jinit_1pass_quantizer gdcm_jpeg12_jinit_1pass_quantizer #define jinit_2pass_quantizer gdcm_jpeg12_jinit_2pass_quantizer +#define jinit_arith_decoder gdcm_jpeg12_jinit_arith_decoder +#define jinit_arith_encoder gdcm_jpeg12_jinit_arith_encoder +#define jinit_c_codec gdcm_jpeg12_jinit_c_codec #define jinit_c_coef_controller gdcm_jpeg12_jinit_c_coef_controller +#define jinit_c_diff_controller gdcm_jpeg12_jinit_c_diff_controller #define jinit_c_main_controller gdcm_jpeg12_jinit_c_main_controller #define jinit_c_master_control gdcm_jpeg12_jinit_c_master_control #define jinit_c_prep_controller gdcm_jpeg12_jinit_c_prep_controller +#define jinit_c_scaler gdcm_jpeg12_jinit_c_scaler #define jinit_color_converter gdcm_jpeg12_jinit_color_converter #define jinit_color_deconverter gdcm_jpeg12_jinit_color_deconverter #define jinit_compress_master gdcm_jpeg12_jinit_compress_master +#define jinit_d_codec gdcm_jpeg12_jinit_d_codec #define jinit_d_coef_controller gdcm_jpeg12_jinit_d_coef_controller +#define jinit_d_diff_controller gdcm_jpeg12_jinit_d_diff_controller #define jinit_d_main_controller gdcm_jpeg12_jinit_d_main_controller #define jinit_d_post_controller gdcm_jpeg12_jinit_d_post_controller +#define jinit_d_scaler gdcm_jpeg12_jinit_d_scaler +#define jinit_differencer gdcm_jpeg12_jinit_differencer #define jinit_downsampler gdcm_jpeg12_jinit_downsampler #define jinit_forward_dct gdcm_jpeg12_jinit_forward_dct -#define jinit_huff_decoder gdcm_jpeg12_jinit_huff_decoder -#define jinit_huff_encoder gdcm_jpeg12_jinit_huff_encoder #define jinit_input_controller gdcm_jpeg12_jinit_input_controller #define jinit_inverse_dct gdcm_jpeg12_jinit_inverse_dct +#define jinit_lhuff_decoder gdcm_jpeg12_jinit_lhuff_decoder +#define jinit_lhuff_encoder gdcm_jpeg12_jinit_lhuff_encoder +#define jinit_lossless_c_codec gdcm_jpeg12_jinit_lossless_c_codec +#define jinit_lossless_d_codec gdcm_jpeg12_jinit_lossless_d_codec +#define jinit_lossy_c_codec gdcm_jpeg12_jinit_lossy_c_codec +#define jinit_lossy_d_codec gdcm_jpeg12_jinit_lossy_d_codec #define jinit_marker_reader gdcm_jpeg12_jinit_marker_reader #define jinit_marker_writer gdcm_jpeg12_jinit_marker_writer #define jinit_master_decompress gdcm_jpeg12_jinit_master_decompress @@ -43,6 +58,9 @@ nm libgdcmijpeg12.a | grep " T " | colrm 1 11 | sort #define jinit_merged_upsampler gdcm_jpeg12_jinit_merged_upsampler #define jinit_phuff_decoder gdcm_jpeg12_jinit_phuff_decoder #define jinit_phuff_encoder gdcm_jpeg12_jinit_phuff_encoder +#define jinit_shuff_decoder gdcm_jpeg12_jinit_shuff_decoder +#define jinit_shuff_encoder gdcm_jpeg12_jinit_shuff_encoder +#define jinit_undifferencer gdcm_jpeg12_jinit_undifferencer #define jinit_upsampler gdcm_jpeg12_jinit_upsampler #define jpeg_CreateCompress gdcm_jpeg12_jpeg_CreateCompress #define jpeg_CreateDecompress gdcm_jpeg12_jpeg_CreateDecompress @@ -100,6 +118,7 @@ nm libgdcmijpeg12.a | grep " T " | colrm 1 11 | sort #define jpeg_set_linear_quality gdcm_jpeg12_jpeg_set_linear_quality #define jpeg_set_marker_processor gdcm_jpeg12_jpeg_set_marker_processor #define jpeg_set_quality gdcm_jpeg12_jpeg_set_quality +#define jpeg_simple_lossless gdcm_jpeg12_jpeg_simple_lossless #define jpeg_simple_progression gdcm_jpeg12_jpeg_simple_progression #define jpeg_start_compress gdcm_jpeg12_jpeg_start_compress #define jpeg_start_decompress gdcm_jpeg12_jpeg_start_decompress diff --git a/src/jpeg/libijg/gdcm_mangle_8bits.h b/src/jpeg/libijg/gdcm_mangle_8bits.h index 56b48f35..4cda2d4f 100644 --- a/src/jpeg/libijg/gdcm_mangle_8bits.h +++ b/src/jpeg/libijg/gdcm_mangle_8bits.h @@ -13,27 +13,41 @@ The following command was used to obtain the symbol list: nm libgdcmijpeg8.a | grep " [R|T] " | colrm 1 11 | sort */ + #define jcopy_block_row gdcm_jpeg8_jcopy_block_row #define jcopy_sample_rows gdcm_jpeg8_jcopy_sample_rows #define jdiv_round_up gdcm_jpeg8_jdiv_round_up #define jinit_1pass_quantizer gdcm_jpeg8_jinit_1pass_quantizer #define jinit_2pass_quantizer gdcm_jpeg8_jinit_2pass_quantizer +#define jinit_arith_decoder gdcm_jpeg8_jinit_arith_decoder +#define jinit_arith_encoder gdcm_jpeg8_jinit_arith_encoder +#define jinit_c_codec gdcm_jpeg8_jinit_c_codec #define jinit_c_coef_controller gdcm_jpeg8_jinit_c_coef_controller +#define jinit_c_diff_controller gdcm_jpeg8_jinit_c_diff_controller #define jinit_c_main_controller gdcm_jpeg8_jinit_c_main_controller #define jinit_c_master_control gdcm_jpeg8_jinit_c_master_control #define jinit_c_prep_controller gdcm_jpeg8_jinit_c_prep_controller +#define jinit_c_scaler gdcm_jpeg8_jinit_c_scaler #define jinit_color_converter gdcm_jpeg8_jinit_color_converter #define jinit_color_deconverter gdcm_jpeg8_jinit_color_deconverter #define jinit_compress_master gdcm_jpeg8_jinit_compress_master +#define jinit_d_codec gdcm_jpeg8_jinit_d_codec #define jinit_d_coef_controller gdcm_jpeg8_jinit_d_coef_controller +#define jinit_d_diff_controller gdcm_jpeg8_jinit_d_diff_controller #define jinit_d_main_controller gdcm_jpeg8_jinit_d_main_controller #define jinit_d_post_controller gdcm_jpeg8_jinit_d_post_controller +#define jinit_d_scaler gdcm_jpeg8_jinit_d_scaler +#define jinit_differencer gdcm_jpeg8_jinit_differencer #define jinit_downsampler gdcm_jpeg8_jinit_downsampler #define jinit_forward_dct gdcm_jpeg8_jinit_forward_dct -#define jinit_huff_decoder gdcm_jpeg8_jinit_huff_decoder -#define jinit_huff_encoder gdcm_jpeg8_jinit_huff_encoder #define jinit_input_controller gdcm_jpeg8_jinit_input_controller #define jinit_inverse_dct gdcm_jpeg8_jinit_inverse_dct +#define jinit_lhuff_decoder gdcm_jpeg8_jinit_lhuff_decoder +#define jinit_lhuff_encoder gdcm_jpeg8_jinit_lhuff_encoder +#define jinit_lossless_c_codec gdcm_jpeg8_jinit_lossless_c_codec +#define jinit_lossless_d_codec gdcm_jpeg8_jinit_lossless_d_codec +#define jinit_lossy_c_codec gdcm_jpeg8_jinit_lossy_c_codec +#define jinit_lossy_d_codec gdcm_jpeg8_jinit_lossy_d_codec #define jinit_marker_reader gdcm_jpeg8_jinit_marker_reader #define jinit_marker_writer gdcm_jpeg8_jinit_marker_writer #define jinit_master_decompress gdcm_jpeg8_jinit_master_decompress @@ -41,6 +55,9 @@ nm libgdcmijpeg8.a | grep " [R|T] " | colrm 1 11 | sort #define jinit_merged_upsampler gdcm_jpeg8_jinit_merged_upsampler #define jinit_phuff_decoder gdcm_jpeg8_jinit_phuff_decoder #define jinit_phuff_encoder gdcm_jpeg8_jinit_phuff_encoder +#define jinit_shuff_decoder gdcm_jpeg8_jinit_shuff_decoder +#define jinit_shuff_encoder gdcm_jpeg8_jinit_shuff_encoder +#define jinit_undifferencer gdcm_jpeg8_jinit_undifferencer #define jinit_upsampler gdcm_jpeg8_jinit_upsampler #define jpeg_CreateCompress gdcm_jpeg8_jpeg_CreateCompress #define jpeg_CreateDecompress gdcm_jpeg8_jpeg_CreateDecompress @@ -98,6 +115,7 @@ nm libgdcmijpeg8.a | grep " [R|T] " | colrm 1 11 | sort #define jpeg_set_linear_quality gdcm_jpeg8_jpeg_set_linear_quality #define jpeg_set_marker_processor gdcm_jpeg8_jpeg_set_marker_processor #define jpeg_set_quality gdcm_jpeg8_jpeg_set_quality +#define jpeg_simple_lossless gdcm_jpeg8_jpeg_simple_lossless #define jpeg_simple_progression gdcm_jpeg8_jpeg_simple_progression #define jpeg_start_compress gdcm_jpeg8_jpeg_start_compress #define jpeg_start_decompress gdcm_jpeg8_jpeg_start_decompress @@ -117,4 +135,5 @@ nm libgdcmijpeg8.a | grep " [R|T] " | colrm 1 11 | sort #define jround_up gdcm_jpeg8_jround_up #define jzero_far gdcm_jpeg8_jzero_far + #endif diff --git a/src/jpeg/libijg/jaricom.c b/src/jpeg/libijg/jaricom.c new file mode 100644 index 00000000..fac05180 --- /dev/null +++ b/src/jpeg/libijg/jaricom.c @@ -0,0 +1,15 @@ +/* + * jaricom.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file holds place for arithmetic entropy codec tables. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + +INT32 jaritab[1]; /* dummy table */ diff --git a/src/jpeg/libijg/jcapimin.c b/src/jpeg/libijg/jcapimin.c index 54fb8c58..7bb6e7b4 100644 --- a/src/jpeg/libijg/jcapimin.c +++ b/src/jpeg/libijg/jcapimin.c @@ -32,12 +32,12 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) int i; /* Guard against version mismatches between library and caller. */ - cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ if (version != JPEG_LIB_VERSION) ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); if (structsize != SIZEOF(struct jpeg_compress_struct)) ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, - (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); + (int) SIZEOF(struct jpeg_compress_struct), (int) structsize); /* For debugging purposes, we zero the whole master structure. * But the application has already set the err pointer, and may have set @@ -73,7 +73,7 @@ jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize) cinfo->script_space = NULL; - cinfo->input_gamma = 1.0; /* in case application forgets */ + cinfo->input_gamma = 1.0; /* in case application forgets */ /* OK, I'm ready */ cinfo->global_state = CSTATE_START; @@ -161,15 +161,15 @@ jpeg_finish_compress (j_compress_ptr cinfo) (*cinfo->master->prepare_for_pass) (cinfo); for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) { if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) iMCU_row; - cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + cinfo->progress->pass_counter = (long) iMCU_row; + cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); } /* We bypass the main controller and invoke coef controller directly; * all work is being done from the coefficient buffer. */ - if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); + if (! (*cinfo->codec->compress_data) (cinfo, (JSAMPIMAGE) NULL)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); } (*cinfo->master->finish_pass) (cinfo); } @@ -190,7 +190,7 @@ jpeg_finish_compress (j_compress_ptr cinfo) GLOBAL(void) jpeg_write_marker (j_compress_ptr cinfo, int marker, - const JOCTET *dataptr, unsigned int datalen) + const JOCTET *dataptr, unsigned int datalen) { JMETHOD(void, write_marker_byte, (j_compress_ptr info, int val)); @@ -201,7 +201,7 @@ jpeg_write_marker (j_compress_ptr cinfo, int marker, ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); (*cinfo->marker->write_marker_header) (cinfo, marker, datalen); - write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ + write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */ while (datalen--) { (*write_marker_byte) (cinfo, *dataptr); dataptr++; @@ -236,14 +236,14 @@ jpeg_write_m_byte (j_compress_ptr cinfo, int val) * To produce a pair of files containing abbreviated tables and abbreviated * image data, one would proceed as follows: * - * initialize JPEG object - * set JPEG parameters - * set destination to table file - * jpeg_write_tables(cinfo); - * set destination to image file - * jpeg_start_compress(cinfo, FALSE); - * write data... - * jpeg_finish_compress(cinfo); + * initialize JPEG object + * set JPEG parameters + * set destination to table file + * jpeg_write_tables(cinfo); + * set destination to image file + * jpeg_start_compress(cinfo, FALSE); + * write data... + * jpeg_finish_compress(cinfo); * * jpeg_write_tables has the side effect of marking all tables written * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress diff --git a/src/jpeg/libijg/jcapistd.c b/src/jpeg/libijg/jcapistd.c index c0320b1b..ee2a8496 100644 --- a/src/jpeg/libijg/jcapistd.c +++ b/src/jpeg/libijg/jcapistd.c @@ -41,7 +41,7 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); if (write_all_tables) - jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ + jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */ /* (Re)initialize error mgr and destination modules */ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); @@ -75,7 +75,7 @@ jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables) GLOBAL(JDIMENSION) jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, - JDIMENSION num_lines) + JDIMENSION num_lines) { JDIMENSION row_ctr, rows_left; @@ -118,7 +118,7 @@ jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines, GLOBAL(JDIMENSION) jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, - JDIMENSION num_lines) + JDIMENSION num_lines) { JDIMENSION lines_per_iMCU_row; @@ -145,12 +145,12 @@ jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data, (*cinfo->master->pass_startup) (cinfo); /* Verify that at least one iMCU row has been passed. */ - lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->data_unit; if (num_lines < lines_per_iMCU_row) ERREXIT(cinfo, JERR_BUFFER_SIZE); /* Directly compress the row. */ - if (! (*cinfo->coef->compress_data) (cinfo, data)) { + if (! (*cinfo->codec->compress_data) (cinfo, data)) { /* If compressor did not consume the whole row, suspend processing. */ return 0; } diff --git a/src/jpeg/libijg/jcarith.c b/src/jpeg/libijg/jcarith.c new file mode 100644 index 00000000..7a179361 --- /dev/null +++ b/src/jpeg/libijg/jcarith.c @@ -0,0 +1,24 @@ +/* + * jcarith.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file holds place for arithmetic entropy encoding routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Module initialization routine for arithmetic entropy encoding. + */ + +GLOBAL(void) +jinit_arith_encoder (j_compress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); +} diff --git a/src/jpeg/libijg/jccoefct.c b/src/jpeg/libijg/jccoefct.c index fe7cfc31..453df1ae 100644 --- a/src/jpeg/libijg/jccoefct.c +++ b/src/jpeg/libijg/jccoefct.c @@ -1,7 +1,7 @@ /* * jccoefct.c * - * Copyright (C) 1994-1997, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -13,6 +13,7 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" +#include "jlossy.h" /* Private declarations for lossy codec */ /* We use a full-image coefficient buffer when doing Huffman optimization, @@ -32,8 +33,6 @@ /* Private buffer controller object */ typedef struct { - struct jpeg_c_coef_controller pub; /* public fields */ - JDIMENSION iMCU_row_num; /* iMCU row # within image */ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ int MCU_vert_offset; /* counts MCU rows within iMCU row */ @@ -41,20 +40,20 @@ typedef struct { /* For single-pass compression, it's sufficient to buffer just one MCU * (although this may prove a bit slow in practice). We allocate a - * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each - * MCU constructed and sent. (On 80x86, the workspace is FAR even though - * it's not really very big; this is to keep the module interfaces unchanged - * when a large coefficient buffer is necessary.) + * workspace of C_MAX_DATA_UNITS_IN_MCU coefficient blocks, and reuse it for + * each MCU constructed and sent. (On 80x86, the workspace is FAR even + * though it's not really very big; this is to keep the module interfaces + * unchanged when a large coefficient buffer is necessary.) * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays. */ - JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW MCU_buffer[C_MAX_DATA_UNITS_IN_MCU]; /* In multi-pass modes, we need a virtual block array for each component. */ jvirt_barray_ptr whole_image[MAX_COMPONENTS]; -} my_coef_controller; +} c_coef_controller; -typedef my_coef_controller * my_coef_ptr; +typedef c_coef_controller * c_coef_ptr; /* Forward declarations */ @@ -72,7 +71,8 @@ LOCAL(void) start_iMCU_row (j_compress_ptr cinfo) /* Reset within-iMCU-row counters for a new row */ { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; /* In an interleaved scan, an MCU row is the same as an iMCU row. * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. @@ -99,7 +99,8 @@ start_iMCU_row (j_compress_ptr cinfo) METHODDEF(void) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; coef->iMCU_row_num = 0; start_iMCU_row(cinfo); @@ -108,18 +109,18 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) case JBUF_PASS_THRU: if (coef->whole_image[0] != NULL) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_data; + lossyc->pub.compress_data = compress_data; break; #ifdef FULL_COEF_BUFFER_SUPPORTED case JBUF_SAVE_AND_PASS: if (coef->whole_image[0] == NULL) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_first_pass; + lossyc->pub.compress_data = compress_first_pass; break; case JBUF_CRANK_DEST: if (coef->whole_image[0] == NULL) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - coef->pub.compress_data = compress_output; + lossyc->pub.compress_data = compress_output; break; #endif default: @@ -142,7 +143,8 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) METHODDEF(boolean) compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; @@ -174,10 +176,10 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (coef->iMCU_row_num < last_iMCU_row || yoffset+yindex < compptr->last_row_height) { - (*cinfo->fdct->forward_DCT) (cinfo, compptr, - input_buf[compptr->component_index], - coef->MCU_buffer[blkn], - ypos, xpos, (JDIMENSION) blockcnt); + (*lossyc->fdct_forward_DCT) (cinfo, compptr, + input_buf[compptr->component_index], + coef->MCU_buffer[blkn], + ypos, xpos, (JDIMENSION) blockcnt); if (blockcnt < compptr->MCU_width) { /* Create some dummy blocks at the right edge of the image. */ jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt], @@ -201,7 +203,7 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) /* Try to write the MCU. In event of a suspension failure, we will * re-DCT the MCU on restart (a bit inefficient, could be fixed...) */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + if (! (*lossyc->entropy_encode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; coef->mcu_ctr = MCU_col_num; @@ -244,7 +246,8 @@ compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) METHODDEF(boolean) compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION blocks_across, MCUs_across, MCUindex; int bi, ci, h_samp_factor, block_row, block_rows, ndummy; @@ -265,10 +268,10 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) block_rows = compptr->v_samp_factor; else { /* NB: can't use last_row_height here, since may not be set! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + block_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); if (block_rows == 0) block_rows = compptr->v_samp_factor; } - blocks_across = compptr->width_in_blocks; + blocks_across = compptr->width_in_data_units; h_samp_factor = compptr->h_samp_factor; /* Count number of dummy blocks to be added at the right margin. */ ndummy = (int) (blocks_across % h_samp_factor); @@ -279,7 +282,7 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) */ for (block_row = 0; block_row < block_rows; block_row++) { thisblockrow = buffer[block_row]; - (*cinfo->fdct->forward_DCT) (cinfo, compptr, + (*lossyc->fdct_forward_DCT) (cinfo, compptr, input_buf[ci], thisblockrow, (JDIMENSION) (block_row * DCTSIZE), (JDIMENSION) 0, blocks_across); @@ -340,7 +343,8 @@ compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) METHODDEF(boolean) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; JDIMENSION MCU_col_num; /* index of current MCU within row */ int blkn, ci, xindex, yindex, yoffset; JDIMENSION start_col; @@ -348,7 +352,6 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) JBLOCKROW buffer_ptr; jpeg_component_info *compptr; - input_buf = 0; /* Align the virtual buffers for the components used in this scan. * NB: during first pass, this is safe only because the buffers will * already be aligned properly, so jmemmgr.c won't need to do any I/O. @@ -379,7 +382,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) } } /* Try to write the MCU. */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) { + if (! (*lossyc->entropy_encode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; coef->mcu_ctr = MCU_col_num; @@ -405,13 +408,14 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) GLOBAL(void) jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) { - my_coef_ptr coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef; - coef = (my_coef_ptr) + coef = (c_coef_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_c_coef_controller *) coef; - coef->pub.start_pass = start_pass_coef; + SIZEOF(c_coef_controller)); + lossyc->coef_private = (struct jpeg_c_coef_controller *) coef; + lossyc->coef_start_pass = start_pass_coef; /* Create the coefficient buffer. */ if (need_full_buffer) { @@ -425,9 +429,9 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) ci++, compptr++) { coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (JDIMENSION) jround_up((long) compptr->height_in_data_units, (long) compptr->v_samp_factor), (JDIMENSION) compptr->v_samp_factor); } @@ -441,8 +445,8 @@ jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer) buffer = (JBLOCKROW) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + C_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_DATA_UNITS_IN_MCU; i++) { coef->MCU_buffer[i] = buffer + i; } coef->whole_image[0] = NULL; /* flag for no virtual arrays */ diff --git a/src/jpeg/libijg/jccolor.c b/src/jpeg/libijg/jccolor.c index 33a80d76..e448d547 100644 --- a/src/jpeg/libijg/jccolor.c +++ b/src/jpeg/libijg/jccolor.c @@ -340,7 +340,6 @@ null_convert (j_compress_ptr cinfo, METHODDEF(void) null_method (j_compress_ptr cinfo) { - cinfo = 0; /* no work needed */ } diff --git a/src/jpeg/libijg/jcdctmgr.c b/src/jpeg/libijg/jcdctmgr.c index 61fa79b9..5b217990 100644 --- a/src/jpeg/libijg/jcdctmgr.c +++ b/src/jpeg/libijg/jcdctmgr.c @@ -1,7 +1,7 @@ /* * jcdctmgr.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -14,14 +14,13 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ +#include "jlossy.h" /* Private declarations for lossy codec */ +#include "jdct.h" /* Private declarations for DCT subsystem */ /* Private subobject for this module */ typedef struct { - struct jpeg_forward_dct pub; /* public fields */ - /* Pointer to the DCT routine actually in use */ forward_DCT_method_ptr do_dct; @@ -36,9 +35,9 @@ typedef struct { float_DCT_method_ptr do_float_dct; FAST_FLOAT * float_divisors[NUM_QUANT_TBLS]; #endif -} my_fdct_controller; +} fdct_controller; -typedef my_fdct_controller * my_fdct_ptr; +typedef fdct_controller * fdct_ptr; /* @@ -53,7 +52,8 @@ typedef my_fdct_controller * my_fdct_ptr; METHODDEF(void) start_pass_fdctmgr (j_compress_ptr cinfo) { - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + fdct_ptr fdct = (fdct_ptr) lossyc->fdct_private; int ci, qtblno, i; jpeg_component_info *compptr; JQUANT_TBL * qtbl; @@ -64,7 +64,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 */ @@ -76,87 +76,87 @@ 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, - DCTSIZE2 * SIZEOF(DCTELEM)); + fdct->divisors[qtblno] = (DCTELEM *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + DCTSIZE2 * SIZEOF(DCTELEM)); } dtbl = fdct->divisors[qtblno]; for (i = 0; i < DCTSIZE2; i++) { - dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; + dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3; } 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 - - if (fdct->divisors[qtblno] == NULL) { - fdct->divisors[qtblno] = (DCTELEM *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - DCTSIZE2 * SIZEOF(DCTELEM)); - } - dtbl = fdct->divisors[qtblno]; - for (i = 0; i < DCTSIZE2; i++) { - dtbl[i] = (DCTELEM) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], - (INT32) aanscales[i]), - CONST_BITS-3); - } + 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, + DCTSIZE2 * SIZEOF(DCTELEM)); + } + dtbl = fdct->divisors[qtblno]; + for (i = 0; i < DCTSIZE2; i++) { + dtbl[i] = (DCTELEM) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-3); + } } 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 - }; - - 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++; - } - } + /* 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, + 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++; + } + } } break; #endif @@ -178,19 +178,20 @@ start_pass_fdctmgr (j_compress_ptr cinfo) METHODDEF(void) forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks) + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) /* This version is used for integer DCT implementations. */ { /* This routine is heavily used, so it's worth coding it tightly. */ - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + fdct_ptr fdct = (fdct_ptr) lossyc->fdct_private; forward_DCT_method_ptr do_dct = fdct->do_dct; DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no]; - DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ + DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */ JDIMENSION bi; - 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 */ @@ -200,22 +201,22 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, workspaceptr = workspace; for (elemr = 0; elemr < DCTSIZE; elemr++) { - elemptr = sample_data[elemr] + start_col; -#if DCTSIZE == 8 /* unroll the inner loop */ - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + elemptr = sample_data[elemr] + start_col; +#if DCTSIZE == 8 /* unroll the inner loop */ + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; #else - { register int elemc; - for (elemc = DCTSIZE; elemc > 0; elemc--) { - *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; - } - } + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE; + } + } #endif } } @@ -229,35 +230,35 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, register JCOEFPTR output_ptr = coef_blocks[bi]; for (i = 0; i < DCTSIZE2; i++) { - qval = divisors[i]; - temp = workspace[i]; - /* Divide the coefficient value by qval, ensuring proper rounding. - * Since C does not specify the direction of rounding for negative - * quotients, we have to force the dividend positive for portability. - * - * In most files, at least half of the output values will be zero - * (at default quantization settings, more like three-quarters...) - * so we should ensure that this case is fast. On many machines, - * a comparison is enough cheaper than a divide to make a special test - * a win. Since both inputs will be nonnegative, we need only test - * for a < b to discover whether a/b is 0. - * If your machine's division is fast enough, define FAST_DIVIDE. - */ + qval = divisors[i]; + temp = workspace[i]; + /* Divide the coefficient value by qval, ensuring proper rounding. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * + * In most files, at least half of the output values will be zero + * (at default quantization settings, more like three-quarters...) + * so we should ensure that this case is fast. On many machines, + * a comparison is enough cheaper than a divide to make a special test + * a win. Since both inputs will be nonnegative, we need only test + * for a < b to discover whether a/b is 0. + * If your machine's division is fast enough, define FAST_DIVIDE. + */ #ifdef FAST_DIVIDE -#define DIVIDE_BY(a,b) a /= b +#define DIVIDE_BY(a,b) a /= b #else -#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 +#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0 #endif - if (temp < 0) { - temp = -temp; - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - temp = -temp; - } else { - temp += qval>>1; /* for rounding */ - DIVIDE_BY(temp, qval); - } - output_ptr[i] = (JCOEF) temp; + if (temp < 0) { + temp = -temp; + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + temp = -temp; + } else { + temp += qval>>1; /* for rounding */ + DIVIDE_BY(temp, qval); + } + output_ptr[i] = (JCOEF) temp; } } } @@ -268,19 +269,20 @@ forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr, 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, - JDIMENSION num_blocks) + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks) /* This version is used for floating-point DCT implementations. */ { /* This routine is heavily used, so it's worth coding it tightly. */ - my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + fdct_ptr fdct = (fdct_ptr) lossyc->fdct_private; float_DCT_method_ptr do_dct = fdct->do_float_dct; FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no]; FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */ JDIMENSION bi; - 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 */ @@ -290,23 +292,23 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, workspaceptr = workspace; for (elemr = 0; elemr < DCTSIZE; elemr++) { - elemptr = sample_data[elemr] + start_col; -#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); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + elemptr = sample_data[elemr] + start_col; +#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); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); #else - { register int elemc; - for (elemc = DCTSIZE; elemc > 0; elemc--) { - *workspaceptr++ = (FAST_FLOAT) - (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); - } - } + { register int elemc; + for (elemc = DCTSIZE; elemc > 0; elemc--) { + *workspaceptr++ = (FAST_FLOAT) + (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE); + } + } #endif } } @@ -320,15 +322,15 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, register JCOEFPTR output_ptr = coef_blocks[bi]; for (i = 0; i < DCTSIZE2; i++) { - /* Apply the quantization and scaling factor */ - temp = workspace[i] * divisors[i]; - /* Round to nearest integer. - * Since C does not specify the direction of rounding for negative - * quotients, we have to force the dividend positive for portability. - * The maximum coefficient size is +-16K (for 12-bit data), so this - * code should work for either 16-bit or 32-bit ints. - */ - output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); + /* Apply the quantization and scaling factor */ + temp = workspace[i] * divisors[i]; + /* Round to nearest integer. + * Since C does not specify the direction of rounding for negative + * quotients, we have to force the dividend positive for portability. + * The maximum coefficient size is +-16K (for 12-bit data), so this + * code should work for either 16-bit or 32-bit ints. + */ + output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384); } } } @@ -344,31 +346,32 @@ forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr, GLOBAL(void) jinit_forward_dct (j_compress_ptr cinfo) { - my_fdct_ptr fdct; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + fdct_ptr fdct; int i; - fdct = (my_fdct_ptr) + fdct = (fdct_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_fdct_controller)); - cinfo->fdct = (struct jpeg_forward_dct *) fdct; - fdct->pub.start_pass = start_pass_fdctmgr; + SIZEOF(fdct_controller)); + lossyc->fdct_private = (struct jpeg_forward_dct *) fdct; + lossyc->fdct_start_pass = start_pass_fdctmgr; switch (cinfo->dct_method) { #ifdef DCT_ISLOW_SUPPORTED case JDCT_ISLOW: - fdct->pub.forward_DCT = forward_DCT; + lossyc->fdct_forward_DCT = forward_DCT; fdct->do_dct = jpeg_fdct_islow; break; #endif #ifdef DCT_IFAST_SUPPORTED case JDCT_IFAST: - fdct->pub.forward_DCT = forward_DCT; + lossyc->fdct_forward_DCT = forward_DCT; fdct->do_dct = jpeg_fdct_ifast; break; #endif #ifdef DCT_FLOAT_SUPPORTED case JDCT_FLOAT: - fdct->pub.forward_DCT = forward_DCT_float; + lossyc->fdct_forward_DCT = forward_DCT_float; fdct->do_float_dct = jpeg_fdct_float; break; #endif diff --git a/src/jpeg/libijg/jcdiffct.c b/src/jpeg/libijg/jcdiffct.c new file mode 100644 index 00000000..4505f495 --- /dev/null +++ b/src/jpeg/libijg/jcdiffct.c @@ -0,0 +1,409 @@ +/* + * jcdiffct.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the difference buffer controller for compression. + * This controller is the top level of the lossless JPEG compressor proper. + * The difference buffer lies between prediction/differencing and entropy + * encoding. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ + + +#ifdef C_LOSSLESS_SUPPORTED + +/* We use a full-image sample buffer when doing Huffman optimization, + * and also for writing multiple-scan JPEG files. In all cases, the + * full-image buffer is filled during the first pass, and the scaling, + * prediction and differencing steps are run during subsequent passes. + */ +#ifdef ENTROPY_OPT_SUPPORTED +#define FULL_SAMP_BUFFER_SUPPORTED +#else +#ifdef C_MULTISCAN_FILES_SUPPORTED +#define FULL_SAMP_BUFFER_SUPPORTED +#endif +#endif + + +/* Private buffer controller object */ + +typedef struct { + JDIMENSION iMCU_row_num; /* iMCU row # within image */ + JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ + int MCU_vert_offset; /* counts MCU rows within iMCU row */ + int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + JSAMPROW cur_row[MAX_COMPONENTS]; /* row of point transformed samples */ + JSAMPROW prev_row[MAX_COMPONENTS]; /* previous row of Pt'd samples */ + JDIFFARRAY diff_buf[MAX_COMPONENTS]; /* iMCU row of differences */ + + /* In multi-pass modes, we need a virtual sample array for each component. */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +} c_diff_controller; + +typedef c_diff_controller * c_diff_ptr; + + +/* Forward declarations */ +METHODDEF(boolean) compress_data + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#ifdef FULL_SAMP_BUFFER_SUPPORTED +METHODDEF(boolean) compress_first_pass + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +METHODDEF(boolean) compress_output + JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_compress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row */ +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff = (c_diff_ptr) losslsc->diff_private; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + diff->MCU_rows_per_iMCU_row = 1; + } else { + if (diff->iMCU_row_num < (cinfo->total_iMCU_rows-1)) + diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + diff->mcu_ctr = 0; + diff->MCU_vert_offset = 0; +} + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass_diff (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff = (c_diff_ptr) losslsc->diff_private; + + diff->iMCU_row_num = 0; + start_iMCU_row(cinfo); + + switch (pass_mode) { + case JBUF_PASS_THRU: + if (diff->whole_image[0] != NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + losslsc->pub.compress_data = compress_data; + break; +#ifdef FULL_SAMP_BUFFER_SUPPORTED + case JBUF_SAVE_AND_PASS: + if (diff->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + losslsc->pub.compress_data = compress_first_pass; + break; + case JBUF_CRANK_DEST: + if (diff->whole_image[0] == NULL) + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + losslsc->pub.compress_data = compress_output; + break; +#endif + default: + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); + break; + } +} + + +#define SWAP_ROWS(rowa,rowb) {JSAMPROW temp; temp=rowa; rowa=rowb; rowb=temp;} + +/* + * Process some data in the single-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor rows for each component in the image. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(boolean) +compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff = (c_diff_ptr) losslsc->diff_private; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION MCU_count; /* number of MCUs encoded */ + /* JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; */ + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int comp, ci, yoffset, samp_row, samp_rows, samps_across; + jpeg_component_info *compptr; + + /* Loop to write as much as one whole iMCU row */ + for (yoffset = diff->MCU_vert_offset; yoffset < diff->MCU_rows_per_iMCU_row; + yoffset++) { + + MCU_col_num = diff->mcu_ctr; + + /* Scale and predict each scanline of the MCU-row separately. + * + * Note: We only do this if we are at the start of a MCU-row, ie, + * we don't want to reprocess a row suspended by the output. + */ + if (MCU_col_num == 0) { + for (comp = 0; comp < cinfo->comps_in_scan; comp++) { + compptr = cinfo->cur_comp_info[comp]; + ci = compptr->component_index; + if (diff->iMCU_row_num < last_iMCU_row) + samp_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + samp_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); + if (samp_rows == 0) samp_rows = compptr->v_samp_factor; + else { + /* Fill dummy difference rows at the bottom edge with zeros, which + * will encode to the smallest amount of data. + */ + for (samp_row = samp_rows; samp_row < compptr->v_samp_factor; + samp_row++) + MEMZERO(diff->diff_buf[ci][samp_row], + jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor) * SIZEOF(JDIFF)); + } + } + samps_across = compptr->width_in_data_units; + + for (samp_row = 0; samp_row < samp_rows; samp_row++) { + (*losslsc->scaler_scale) (cinfo, + input_buf[ci][samp_row], + diff->cur_row[ci], samps_across); + (*losslsc->predict_difference[ci]) (cinfo, ci, + diff->cur_row[ci], + diff->prev_row[ci], + diff->diff_buf[ci][samp_row], + samps_across); + SWAP_ROWS(diff->cur_row[ci], diff->prev_row[ci]); + } + } + } + + /* Try to write the MCU-row (or remaining portion of suspended MCU-row). */ + MCU_count = + (*losslsc->entropy_encode_mcus) (cinfo, + diff->diff_buf, yoffset, MCU_col_num, + cinfo->MCUs_per_row - MCU_col_num); + if (MCU_count != cinfo->MCUs_per_row - MCU_col_num) { + /* Suspension forced; update state counters and exit */ + diff->MCU_vert_offset = yoffset; + diff->mcu_ctr += MCU_col_num; + return FALSE; + } + + /* Completed an MCU row, but perhaps not an iMCU row */ + diff->mcu_ctr = 0; + } + + /* Completed the iMCU row, advance counters for next one */ + diff->iMCU_row_num++; + start_iMCU_row(cinfo); + return TRUE; +} + + +#ifdef FULL_SAMP_BUFFER_SUPPORTED + +/* + * Process some data in the first pass of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor rows for each component in the image. + * This amount of data is read from the source buffer and saved into the + * virtual arrays. + * + * We must also emit the data to the compressor. This is conveniently + * done by calling compress_output() after we've loaded the current strip + * of the virtual arrays. + * + * NB: input_buf contains a plane for each component in image. All components + * are loaded into the virtual arrays in this pass. However, it may be that + * only a subset of the components are emitted to the compressor during + * this first pass; be careful about looking at the scan-dependent variables + * (MCU dimensions, etc). + */ + +METHODDEF(boolean) +compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff = (c_diff_ptr) losslsc->diff_private; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + JDIMENSION samps_across; + int ci, samp_row, samp_rows; + JSAMPARRAY buffer[MAX_COMPONENTS]; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffers for this component. */ + buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, diff->whole_image[ci], + diff->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + + /* Count non-dummy sample rows in this iMCU row. */ + if (diff->iMCU_row_num < last_iMCU_row) + samp_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here, since may not be set! */ + samp_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); + if (samp_rows == 0) samp_rows = compptr->v_samp_factor; + } + samps_across = compptr->width_in_data_units; + + /* Perform point transform scaling and prediction/differencing for all + * non-dummy rows in this iMCU row. Each call on these functions + * process a complete row of samples. + */ + for (samp_row = 0; samp_row < samp_rows; samp_row++) { + MEMCOPY(buffer[ci][samp_row], input_buf[ci][samp_row], + samps_across * SIZEOF(JSAMPLE)); + } + } + + /* NB: compress_output will increment iMCU_row_num if successful. + * A suspension return will result in redoing all the work above next time. + */ + + /* Emit data to the compressor, sharing code with subsequent passes */ + return compress_output(cinfo, input_buf); +} + + +/* + * Process some data in subsequent passes of a multi-pass case. + * We process the equivalent of one fully interleaved MCU row ("iMCU" row) + * per call, ie, v_samp_factor rows for each component in the scan. + * The data is obtained from the virtual arrays and fed to the compressor. + * Returns TRUE if the iMCU row is completed, FALSE if suspended. + * + * NB: input_buf is ignored; it is likely to be a NULL pointer. + */ + +METHODDEF(boolean) +compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff = (c_diff_ptr) losslsc->diff_private; + /* JDIMENSION MCU_col_num; */ /* index of current MCU within row */ + /* JDIMENSION MCU_count; */ /* number of MCUs encoded */ + int comp, ci /* , yoffset */ ; + JSAMPARRAY buffer[MAX_COMPONENTS]; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. + * NB: during first pass, this is safe only because the buffers will + * already be aligned properly, so jmemmgr.c won't need to do any I/O. + */ + for (comp = 0; comp < cinfo->comps_in_scan; comp++) { + compptr = cinfo->cur_comp_info[comp]; + ci = compptr->component_index; + buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, diff->whole_image[ci], + diff->iMCU_row_num * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + } + + return compress_data(cinfo, buffer); +} + +#endif /* FULL_SAMP_BUFFER_SUPPORTED */ + + +/* + * Initialize difference buffer controller. + */ + +GLOBAL(void) +jinit_c_diff_controller (j_compress_ptr cinfo, boolean need_full_buffer) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_diff_ptr diff; + int ci, row; + jpeg_component_info *compptr; + + diff = (c_diff_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_diff_controller)); + losslsc->diff_private = (void *) diff; + losslsc->diff_start_pass = start_pass_diff; + + /* Create the prediction row buffers. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + diff->cur_row[ci] = *(*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) 1); + diff->prev_row[ci] = *(*cinfo->mem->alloc_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) 1); + } + + /* Create the difference buffer. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + diff->diff_buf[ci] = (*cinfo->mem->alloc_darray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + /* Prefill difference rows with zeros. We do this because only actual + * data is placed in the buffers during prediction/differencing, leaving + * any dummy differences at the right edge as zeros, which will encode + * to the smallest amount of data. + */ + for (row = 0; row < compptr->v_samp_factor; row++) + MEMZERO(diff->diff_buf[ci][row], + jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor) * SIZEOF(JDIFF)); + } + + /* Create the sample buffer. */ + if (need_full_buffer) { +#ifdef FULL_SAMP_BUFFER_SUPPORTED + /* Allocate a full-image virtual array for each component, */ + /* padded to a multiple of samp_factor differences in each direction. */ + int ci; + jpeg_component_info *compptr; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + diff->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_data_units, + (long) compptr->v_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } +#else + ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); +#endif + } else + diff->whole_image[0] = NULL; /* flag for no virtual arrays */ +} + +#endif /* C_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jchuff.c b/src/jpeg/libijg/jchuff.c index f2352505..86683b14 100644 --- a/src/jpeg/libijg/jchuff.c +++ b/src/jpeg/libijg/jchuff.c @@ -1,183 +1,28 @@ /* * jchuff.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * - * This file contains Huffman entropy encoding routines. - * - * Much of the complexity here has to do with supporting output suspension. - * If the data destination module demands suspension, we want to be able to - * back up to the start of the current MCU. To do this, we copy state - * variables into local working storage, and update them back to the - * permanent JPEG objects only upon successful completion of an MCU. + * This file contains Huffman entropy decoding routines which are shared + * by the sequential, progressive and lossless decoders. */ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jchuff.h" /* Declarations shared with jcphuff.c */ - - -/* Expanded entropy encoder object for Huffman encoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - INT32 put_buffer; /* current bit-accumulation buffer */ - int put_bits; /* # of bits now in it */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).put_buffer = (src).put_buffer, \ - (dest).put_bits = (src).put_bits, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_encoder pub; /* public fields */ - - savable_state saved; /* Bit buffer & DC state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - int next_restart_num; /* next restart number to write (0-7) */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; - c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; - -#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ - long * dc_count_ptrs[NUM_HUFF_TBLS]; - long * ac_count_ptrs[NUM_HUFF_TBLS]; -#endif -} huff_entropy_encoder; - -typedef huff_entropy_encoder * huff_entropy_ptr; - -/* Working state while writing an MCU. - * This struct contains all the fields that are needed by subroutines. - */ - -typedef struct { - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - savable_state cur; /* Current bit buffer & DC state */ - j_compress_ptr cinfo; /* dump_buffer needs access to this */ -} working_state; - - -/* Forward declarations */ -METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); -#ifdef ENTROPY_OPT_SUPPORTED -METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); -METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); -#endif - - -/* - * Initialize for a Huffman-compressed scan. - * If gather_statistics is TRUE, we do not output anything during the scan, - * just count the Huffman symbols used and generate Huffman code tables. - */ - -METHODDEF(void) -start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; - jpeg_component_info * compptr; - - if (gather_statistics) { -#ifdef ENTROPY_OPT_SUPPORTED - entropy->pub.encode_mcu = encode_mcu_gather; - entropy->pub.finish_pass = finish_pass_gather; -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else { - entropy->pub.encode_mcu = encode_mcu_huff; - entropy->pub.finish_pass = finish_pass_huff; - } - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - if (gather_statistics) { -#ifdef ENTROPY_OPT_SUPPORTED - /* Check for invalid table indexes */ - /* (make_c_derived_tbl does this in the other path) */ - if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); - if (actbl < 0 || actbl >= NUM_HUFF_TBLS) - ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); - /* Allocate and zero the statistics tables */ - /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ - if (entropy->dc_count_ptrs[dctbl] == NULL) - entropy->dc_count_ptrs[dctbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); - MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); - if (entropy->ac_count_ptrs[actbl] == NULL) - entropy->ac_count_ptrs[actbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); - MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); -#endif - } else { - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, - & entropy->dc_derived_tbls[dctbl]); - jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, - & entropy->ac_derived_tbls[actbl]); - } - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Initialize bit buffer to empty */ - entropy->saved.put_buffer = 0; - entropy->saved.put_bits = 0; - - /* Initialize restart stuff */ - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num = 0; -} +#include "jchuff.h" /* Declarations shared with jc*huff.c */ /* * Compute the derived values for a Huffman table. * This routine also performs some validation checks on the table. - * - * Note this is also used by jcphuff.c. */ GLOBAL(void) jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, - c_derived_tbl ** pdtbl) + c_derived_tbl ** pdtbl) { JHUFF_TBL *htbl; c_derived_tbl *dtbl; @@ -202,7 +47,7 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, if (*pdtbl == NULL) *pdtbl = (c_derived_tbl *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(c_derived_tbl)); + SIZEOF(c_derived_tbl)); dtbl = *pdtbl; /* Figure C.1: make table of Huffman code length for each symbol */ @@ -210,7 +55,7 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, p = 0; for (l = 1; l <= 16; l++) { i = (int) htbl->bits[l]; - if (i < 0 || p + i > 256) /* protect against table overrun */ + if (i < 0 || p + i > 256) /* protect against table overrun */ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); while (i--) huffsize[p++] = (char) l; @@ -231,8 +76,9 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, } /* code is now 1 more than the last code used for codelength si; but * it must still fit in si bits, since no code is allowed to be all ones. + * BUG FIX 2001-09-03: Comparison must be >, not >= */ - if (((INT32) code) >= (((INT32) 1) << si)) + if (((INT32) code) > (((INT32) 1) << si)) ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); code <<= 1; si++; @@ -249,10 +95,10 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, /* This is also a convenient place to check for out-of-range * and duplicated VAL entries. We allow 0..255 for AC symbols - * but only 0..15 for DC. (We could constrain them further + * but only 0..16 for DC. (We could constrain them further * based on data depth and mode, but this seems enough.) */ - maxsymbol = isDC ? 15 : 255; + maxsymbol = isDC ? 16 : 255; for (p = 0; p < lastp; p++) { i = htbl->huffval[p]; @@ -264,418 +110,8 @@ jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno, } -/* Outputting bytes to the file */ - -/* Emit a byte, taking 'action' if must suspend. */ -#define emit_byte(state,val,action) \ - { *(state)->next_output_byte++ = (JOCTET) (val); \ - if (--(state)->free_in_buffer == 0) \ - if (! dump_buffer(state)) \ - { action; } } - - -LOCAL(boolean) -dump_buffer (working_state * state) -/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ -{ - struct jpeg_destination_mgr * dest = state->cinfo->dest; - - if (! (*dest->empty_output_buffer) (state->cinfo)) - return FALSE; - /* After a successful buffer dump, must reset buffer pointers */ - state->next_output_byte = dest->next_output_byte; - state->free_in_buffer = dest->free_in_buffer; - return TRUE; -} - - -/* Outputting bits to the file */ - -/* Only the right 24 bits of put_buffer are used; the valid bits are - * left-justified in this part. At most 16 bits can be passed to emit_bits - * in one call, and we never retain more than 7 bits in put_buffer - * between calls, so 24 bits are sufficient. - */ - -INLINE -LOCAL(boolean) -emit_bits (working_state * state, unsigned int code, int size) -/* Emit some bits; return TRUE if successful, FALSE if must suspend */ -{ - /* This routine is heavily used, so it's worth coding tightly. */ - register INT32 put_buffer = (INT32) code; - register int put_bits = state->cur.put_bits; - - /* if size is 0, caller used an invalid Huffman table entry */ - if (size == 0) - ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); - - put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ - - while (put_bits >= 8) { - int c = (int) ((put_buffer >> 16) & 0xFF); - - emit_byte(state, c, return FALSE); - if (c == 0xFF) { /* need to stuff a zero byte? */ - emit_byte(state, 0, return FALSE); - } - put_buffer <<= 8; - put_bits -= 8; - } - - state->cur.put_buffer = put_buffer; /* update state variables */ - state->cur.put_bits = put_bits; - - return TRUE; -} - - -LOCAL(boolean) -flush_bits (working_state * state) -{ - if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ - return FALSE; - state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ - state->cur.put_bits = 0; - return TRUE; -} - - -/* Encode a single block's worth of coefficients */ - -LOCAL(boolean) -encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, - c_derived_tbl *dctbl, c_derived_tbl *actbl) -{ - register int temp, temp2; - register int nbits; - register int k, r, i; - - /* Encode the DC coefficient difference per section F.1.2.1 */ - - temp = temp2 = block[0] - last_dc_val; - - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* For a negative input, want temp2 = bitwise complement of abs(input) */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - - /* Emit the Huffman-coded symbol for the number of bits */ - if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ - if (! emit_bits(state, (unsigned int) temp2, nbits)) - return FALSE; - - /* Encode the AC coefficients per section F.1.2.2 */ - - r = 0; /* r = run length of zeros */ - - for (k = 1; k < DCTSIZE2; k++) { - if ((temp = block[jpeg_natural_order[k]]) == 0) { - r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) - return FALSE; - r -= 16; - } - - temp2 = temp; - if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - /* This code assumes we are on a two's complement machine */ - temp2--; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); - - /* Emit Huffman symbol for run length / number of bits */ - i = (r << 4) + nbits; - if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) - return FALSE; - - /* Emit that number of bits of the value, if positive, */ - /* or the complement of its magnitude, if negative. */ - if (! emit_bits(state, (unsigned int) temp2, nbits)) - return FALSE; - - r = 0; - } - } - - /* If the last coef(s) were zero, emit an end-of-block code */ - if (r > 0) - if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) - return FALSE; - - return TRUE; -} - - -/* - * Emit a restart marker & resynchronize predictions. - */ - -LOCAL(boolean) -emit_restart (working_state * state, int restart_num) -{ - int ci; - - if (! flush_bits(state)) - return FALSE; - - emit_byte(state, 0xFF, return FALSE); - emit_byte(state, JPEG_RST0 + restart_num, return FALSE); - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) - state->cur.last_dc_val[ci] = 0; - - /* The restart counter is not updated until we successfully write the MCU. */ - - return TRUE; -} - - -/* - * Encode and output one MCU's worth of Huffman-compressed coefficients. - */ - -METHODDEF(boolean) -encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - working_state state; - int blkn, ci; - jpeg_component_info * compptr; - - /* Load up working state */ - state.next_output_byte = cinfo->dest->next_output_byte; - state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); - state.cinfo = cinfo; - - /* Emit restart marker if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! emit_restart(&state, entropy->next_restart_num)) - return FALSE; - } - - /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - if (! encode_one_block(&state, - MCU_data[blkn][0], state.cur.last_dc_val[ci], - entropy->dc_derived_tbls[compptr->dc_tbl_no], - entropy->ac_derived_tbls[compptr->ac_tbl_no])) - return FALSE; - /* Update last_dc_val */ - state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; - } - - /* Completed MCU, so update state */ - cinfo->dest->next_output_byte = state.next_output_byte; - cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); - - /* Update restart-interval state too */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - entropy->restarts_to_go = cinfo->restart_interval; - entropy->next_restart_num++; - entropy->next_restart_num &= 7; - } - entropy->restarts_to_go--; - } - - return TRUE; -} - - -/* - * Finish up at the end of a Huffman-compressed scan. - */ - -METHODDEF(void) -finish_pass_huff (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - working_state state; - - /* Load up working state ... flush_bits needs it */ - state.next_output_byte = cinfo->dest->next_output_byte; - state.free_in_buffer = cinfo->dest->free_in_buffer; - ASSIGN_STATE(state.cur, entropy->saved); - state.cinfo = cinfo; - - /* Flush out the last data */ - if (! flush_bits(&state)) - ERREXIT(cinfo, JERR_CANT_SUSPEND); - - /* Update state */ - cinfo->dest->next_output_byte = state.next_output_byte; - cinfo->dest->free_in_buffer = state.free_in_buffer; - ASSIGN_STATE(entropy->saved, state.cur); -} - - -/* - * Huffman coding optimization. - * - * We first scan the supplied data and count the number of uses of each symbol - * that is to be Huffman-coded. (This process MUST agree with the code above.) - * Then we build a Huffman coding tree for the observed counts. - * Symbols which are not needed at all for the particular image are not - * assigned any code, which saves space in the DHT marker as well as in - * the compressed data. - */ - -#ifdef ENTROPY_OPT_SUPPORTED - - -/* Process a single block's worth of coefficients */ - -LOCAL(void) -htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, - long dc_counts[], long ac_counts[]) -{ - register int temp; - register int nbits; - register int k, r; - - /* Encode the DC coefficient difference per section F.1.2.1 */ - - temp = block[0] - last_dc_val; - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 0; - while (temp) { - nbits++; - temp >>= 1; - } - /* Check for out-of-range coefficient values. - * Since we're encoding a difference, the range limit is twice as much. - */ - if (nbits > MAX_COEF_BITS+1) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count the Huffman symbol for the number of bits */ - dc_counts[nbits]++; - - /* Encode the AC coefficients per section F.1.2.2 */ - - r = 0; /* r = run length of zeros */ - - for (k = 1; k < DCTSIZE2; k++) { - if ((temp = block[jpeg_natural_order[k]]) == 0) { - r++; - } else { - /* if run length > 15, must emit special run-length-16 codes (0xF0) */ - while (r > 15) { - ac_counts[0xF0]++; - r -= 16; - } - - /* Find the number of bits needed for the magnitude of the coefficient */ - if (temp < 0) - temp = -temp; - - /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ - while ((temp >>= 1)) - nbits++; - /* Check for out-of-range coefficient values */ - if (nbits > MAX_COEF_BITS) - ERREXIT(cinfo, JERR_BAD_DCT_COEF); - - /* Count Huffman symbol for run length / number of bits */ - ac_counts[(r << 4) + nbits]++; - - r = 0; - } - } - - /* If the last coef(s) were zero, emit an end-of-block code */ - if (r > 0) - ac_counts[0]++; -} - - -/* - * Trial-encode one MCU's worth of Huffman-compressed coefficients. - * No data is actually output, so no suspension return is possible. - */ - -METHODDEF(boolean) -encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int blkn, ci; - jpeg_component_info * compptr; - - /* Take care of restart intervals if needed */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) { - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - /* Update restart state */ - entropy->restarts_to_go = cinfo->restart_interval; - } - entropy->restarts_to_go--; - } - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], - entropy->dc_count_ptrs[compptr->dc_tbl_no], - entropy->ac_count_ptrs[compptr->ac_tbl_no]); - entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; - } - - return TRUE; -} - - /* * Generate the best Huffman code table for the given counts, fill htbl. - * Note this is also used by jcphuff.c. * * The JPEG standard requires that no symbol be assigned a codeword of all * one bits (so that padding bits added at the end of a compressed segment @@ -704,10 +140,10 @@ encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) GLOBAL(void) jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) { -#define MAX_CLEN 32 /* assumed maximum initial code length */ - UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ - int codesize[257]; /* codesize[k] = code length of symbol k */ - int others[257]; /* next symbol in current branch of tree */ +#define MAX_CLEN 32 /* assumed maximum initial code length */ + UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */ + int codesize[257]; /* codesize[k] = code length of symbol k */ + int others[257]; /* next symbol in current branch of tree */ int c1, c2; int p, i, j; long v; @@ -717,9 +153,9 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) MEMZERO(bits, SIZEOF(bits)); MEMZERO(codesize, SIZEOF(codesize)); for (i = 0; i < 257; i++) - others[i] = -1; /* init links to empty */ + others[i] = -1; /* init links to empty */ - freq[256] = 1; /* make sure 256 has a nonzero count */ + freq[256] = 1; /* make sure 256 has a nonzero count */ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees * that no real symbol is given code-value of all ones, because 256 * will be placed last in the largest codeword category. @@ -734,8 +170,8 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] && freq[i] <= v) { - v = freq[i]; - c1 = i; + v = freq[i]; + c1 = i; } } @@ -745,8 +181,8 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) v = 1000000000L; for (i = 0; i <= 256; i++) { if (freq[i] && freq[i] <= v && i != c1) { - v = freq[i]; - c2 = i; + v = freq[i]; + c2 = i; } } @@ -765,7 +201,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) codesize[c1]++; } - others[c1] = c2; /* chain c2 onto c1's tree branch */ + others[c1] = c2; /* chain c2 onto c1's tree branch */ /* Increment the codesize of everything in c2's tree branch */ codesize[c2]++; @@ -781,7 +217,7 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) /* The JPEG standard seems to think that this can't happen, */ /* but I'm paranoid... */ if (codesize[i] > MAX_CLEN) - ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); + ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW); bits[codesize[i]]++; } @@ -800,19 +236,19 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) for (i = MAX_CLEN; i > 16; i--) { while (bits[i] > 0) { - j = i - 2; /* find length of new prefix to be used */ + j = i - 2; /* find length of new prefix to be used */ while (bits[j] == 0) - j--; + j--; - bits[i] -= 2; /* remove two symbols */ - bits[i-1]++; /* one goes in this length */ - bits[j+1] += 2; /* two new symbols in this length */ - bits[j]--; /* symbol of this length is now a prefix */ + bits[i] -= 2; /* remove two symbols */ + bits[i-1]++; /* one goes in this length */ + bits[j+1] += 2; /* two new symbols in this length */ + bits[j]--; /* symbol of this length is now a prefix */ } } /* Remove the count for the pseudo-symbol 256 from the largest codelength */ - while (bits[i] == 0) /* find largest codelength still in use */ + while (bits[i] == 0) /* find largest codelength still in use */ i--; bits[i]--; @@ -827,8 +263,8 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) for (i = 1; i <= MAX_CLEN; i++) { for (j = 0; j <= 255; j++) { if (codesize[j] == i) { - htbl->huffval[p] = (UINT8) j; - p++; + htbl->huffval[p] = (UINT8) j; + p++; } } } @@ -836,74 +272,3 @@ jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]) /* Set sent_table FALSE so updated table will be written to JPEG file. */ htbl->sent_table = FALSE; } - - -/* - * Finish up a statistics-gathering pass and create the new Huffman tables. - */ - -METHODDEF(void) -finish_pass_gather (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, dctbl, actbl; - jpeg_component_info * compptr; - JHUFF_TBL **htblptr; - boolean did_dc[NUM_HUFF_TBLS]; - boolean did_ac[NUM_HUFF_TBLS]; - - /* It's important not to apply jpeg_gen_optimal_table more than once - * per table, because it clobbers the input frequency counts! - */ - MEMZERO(did_dc, SIZEOF(did_dc)); - MEMZERO(did_ac, SIZEOF(did_ac)); - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - if (! did_dc[dctbl]) { - htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); - did_dc[dctbl] = TRUE; - } - if (! did_ac[actbl]) { - htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; - if (*htblptr == NULL) - *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); - jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); - did_ac[actbl] = TRUE; - } - } -} - - -#endif /* ENTROPY_OPT_SUPPORTED */ - - -/* - * Module initialization routine for Huffman entropy encoding. - */ - -GLOBAL(void) -jinit_huff_encoder (j_compress_ptr cinfo) -{ - huff_entropy_ptr entropy; - int i; - - entropy = (huff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(huff_entropy_encoder)); - cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; - entropy->pub.start_pass = start_pass_huff; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; -#ifdef ENTROPY_OPT_SUPPORTED - entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; -#endif - } -} diff --git a/src/jpeg/libijg/jchuff.h b/src/jpeg/libijg/jchuff.h index a9599fc1..6b0570ea 100644 --- a/src/jpeg/libijg/jchuff.h +++ b/src/jpeg/libijg/jchuff.h @@ -22,26 +22,33 @@ #define MAX_COEF_BITS 14 #endif +/* The legal range of a spatial difference is + * -32767 .. +32768. + * Hence the magnitude should always fit in 16 bits. + */ + +#define MAX_DIFF_BITS 16 + /* 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; /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_make_c_derived_tbl jMkCDerived -#define jpeg_gen_optimal_table jGenOptTbl +#define jpeg_make_c_derived_tbl jMkCDerived +#define jpeg_gen_optimal_table jGenOptTbl #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Expand a Huffman table definition into the derived format */ EXTERN(void) jpeg_make_c_derived_tbl - JPP((j_compress_ptr cinfo, boolean isDC, int tblno, - c_derived_tbl ** pdtbl)); + JPP((j_compress_ptr cinfo, boolean isDC, int tblno, + c_derived_tbl ** pdtbl)); /* Generate an optimal table definition given the specified counts */ EXTERN(void) jpeg_gen_optimal_table - JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); + JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])); diff --git a/src/jpeg/libijg/jcinit.c b/src/jpeg/libijg/jcinit.c index 5efffe33..b485a8e7 100644 --- a/src/jpeg/libijg/jcinit.c +++ b/src/jpeg/libijg/jcinit.c @@ -32,31 +32,16 @@ jinit_compress_master (j_compress_ptr cinfo) /* Initialize master control (includes parameter checking/processing) */ jinit_c_master_control(cinfo, FALSE /* full compression */); + /* Initialize compression codec */ + jinit_c_codec(cinfo); + /* Preprocessing */ if (! cinfo->raw_data_in) { jinit_color_converter(cinfo); jinit_downsampler(cinfo); jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */); } - /* Forward DCT */ - jinit_forward_dct(cinfo); - /* Entropy encoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - jinit_phuff_encoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_encoder(cinfo); - } - /* Need a full-image coefficient buffer in any multi-pass mode. */ - jinit_c_coef_controller(cinfo, - (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding)); jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */); jinit_marker_writer(cinfo); diff --git a/src/jpeg/libijg/jclhuff.c b/src/jpeg/libijg/jclhuff.c new file mode 100644 index 00000000..6f2a2f19 --- /dev/null +++ b/src/jpeg/libijg/jclhuff.c @@ -0,0 +1,601 @@ +/* + * jclhuff.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for lossless JPEG. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ +#include "jchuff.h" /* Declarations shared with jc*huff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits) +#endif + + +typedef struct { + int ci, yoffset, MCU_width; +} lhe_input_ptr_info; + + +typedef struct { + savable_state saved; /* Bit buffer at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Pointers to derived tables to be used for each data unit within an MCU */ + c_derived_tbl * cur_tbls[C_MAX_DATA_UNITS_IN_MCU]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * count_ptrs[NUM_HUFF_TBLS]; + + /* Pointers to stats tables to be used for each data unit within an MCU */ + long * cur_counts[C_MAX_DATA_UNITS_IN_MCU]; +#endif + + /* Pointers to the proper input difference row for each group of data units + * within an MCU. For each component, there are Vi groups of Hi data units. + */ + JDIFFROW input_ptr[C_MAX_DATA_UNITS_IN_MCU]; + + /* Number of input pointers in use for the current MCU. This is the sum + * of all Vi in the MCU. + */ + int num_input_ptrs; + + /* Information used for positioning the input pointers within the input + * difference rows. + */ + lhe_input_ptr_info input_ptr_info[C_MAX_DATA_UNITS_IN_MCU]; + + /* Index of the proper input pointer for each data unit within an MCU */ + int input_ptr_index[C_MAX_DATA_UNITS_IN_MCU]; + +} lhuff_entropy_encoder; + +typedef lhuff_entropy_encoder * lhuff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF(JDIMENSION) encode_mcus_huff (j_compress_ptr cinfo, + JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, + JDIMENSION MCU_col_num, + JDIMENSION nMCU); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF(JDIMENSION) encode_mcus_gather (j_compress_ptr cinfo, + JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, + JDIMENSION MCU_col_num, + JDIMENSION nMCU); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF(void) +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsc->entropy_private; + int ci, dctbl, sampn, ptrn, yoffset, xoffset; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + losslsc->entropy_encode_mcus = encode_mcus_gather; + losslsc->pub.entropy_finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + losslsc->entropy_encode_mcus = encode_mcus_huff; + losslsc->pub.entropy_finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->count_ptrs[dctbl] == NULL) + entropy->count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->count_ptrs[dctbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + & entropy->derived_tbls[dctbl]); + } + } + + /* Precalculate encoding info for each sample in an MCU of this scan */ + for (sampn = 0, ptrn = 0; sampn < cinfo->data_units_in_MCU;) { + compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]]; + ci = compptr->component_index; + /* ci = cinfo->MCU_membership[sampn]; + compptr = cinfo->cur_comp_info[ci];*/ + for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) { + /* Precalculate the setup info for each input pointer */ + entropy->input_ptr_info[ptrn].ci = ci; + entropy->input_ptr_info[ptrn].yoffset = yoffset; + entropy->input_ptr_info[ptrn].MCU_width = compptr->MCU_width; + for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) { + /* Precalculate the input pointer index for each sample */ + entropy->input_ptr_index[sampn] = ptrn; + /* Precalculate which tables to use for each sample */ + entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no]; + entropy->cur_counts[sampn] = entropy->count_ptrs[compptr->dc_tbl_no]; + } + } + } + entropy->num_input_ptrs = ptrn; + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL(boolean) +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(boolean) +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL(boolean) +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(boolean) +emit_restart (working_state * state, int restart_num) +{ + /* int ci; */ + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one nMCU's worth of Huffman-compressed differences. + */ + +METHODDEF(JDIMENSION) +encode_mcus_huff (j_compress_ptr cinfo, JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, + JDIMENSION nMCU) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsc->entropy_private; + working_state state; + unsigned int mcu_num; + int sampn, ci, yoffset, MCU_width, ptrn; + /* jpeg_component_info * compptr; */ + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return 0; + } + + /* Set input pointer locations based on MCU_col_num */ + for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) { + ci = entropy->input_ptr_info[ptrn].ci; + yoffset = entropy->input_ptr_info[ptrn].yoffset; + MCU_width = entropy->input_ptr_info[ptrn].MCU_width; + entropy->input_ptr[ptrn] = + diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width); + } + + for (mcu_num = 0; mcu_num < nMCU; mcu_num++) { + + /* Inner loop handles the samples in the MCU */ + for (sampn = 0; sampn < cinfo->data_units_in_MCU; sampn++) { + register int temp, temp2 /* , temp3 */ ; + register int nbits; + c_derived_tbl *dctbl = entropy->cur_tbls[sampn]; + + /* Encode the difference per section H.1.2.2 */ + + /* Input the sample difference */ + temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++; + + if (temp & 0x8000) { /* instead of temp < 0 */ + temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */ + if (temp == 0) /* special case: magnitude = 32768 */ + temp2 = temp = 0x8000; + temp2 = ~ temp; /* one's complement of magnitude */ + } else { + temp &= 0x7FFF; /* abs value mod 2^16 */ + temp2 = temp; /* magnitude */ + } + + /* Find the number of bits needed for the magnitude of the difference */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range difference values. + */ + if (nbits > MAX_DIFF_BITS) + ERREXIT(cinfo, JERR_BAD_DIFF); + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(&state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return mcu_num; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits && /* emit_bits rejects calls with size 0 */ + nbits != 16) /* special case: no bits should be emitted */ + if (! emit_bits(&state, (unsigned int) temp2, nbits)) + return mcu_num; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + } + + return nMCU; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF(void) +finish_pass_huff (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsc->entropy_private; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + +/* + * Trial-encode one nMCU's worth of Huffman-compressed differences. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF(JDIMENSION) +encode_mcus_gather (j_compress_ptr cinfo, JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, + JDIMENSION nMCU) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsc->entropy_private; + unsigned int mcu_num; + int sampn, ci, yoffset, MCU_width, ptrn; + /* jpeg_component_info * compptr; */ + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + /* Set input pointer locations based on MCU_col_num */ + for (ptrn = 0; ptrn < entropy->num_input_ptrs; ptrn++) { + ci = entropy->input_ptr_info[ptrn].ci; + yoffset = entropy->input_ptr_info[ptrn].yoffset; + MCU_width = entropy->input_ptr_info[ptrn].MCU_width; + entropy->input_ptr[ptrn] = + diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width); + } + + for (mcu_num = 0; mcu_num < nMCU; mcu_num++) { + + /* Inner loop handles the samples in the MCU */ + for (sampn = 0; sampn < cinfo->data_units_in_MCU; sampn++) { + register int temp; + register int nbits; + /* c_derived_tbl *dctbl = entropy->cur_tbls[sampn]; */ + long * counts = entropy->cur_counts[sampn]; + + /* Encode the difference per section H.1.2.2 */ + + /* Input the sample difference */ + temp = *entropy->input_ptr[entropy->input_ptr_index[sampn]]++; + + if (temp & 0x8000) { /* instead of temp < 0 */ + temp = (-temp) & 0x7FFF; /* absolute value, mod 2^16 */ + if (temp == 0) /* special case: magnitude = 32768 */ + temp = 0x8000; + } else + temp &= 0x7FFF; /* abs value mod 2^16 */ + + /* Find the number of bits needed for the magnitude of the difference */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range difference values. + */ + if (nbits > MAX_DIFF_BITS) + ERREXIT(cinfo, JERR_BAD_DIFF); + + /* Count the Huffman symbol for the number of bits */ + counts[nbits]++; + } + } + + return nMCU; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsc->entropy_private; + int ci, dctbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +METHODDEF(boolean) +need_optimization_pass (j_compress_ptr cinfo) +{ + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_lhuff_encoder (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + lhuff_entropy_ptr entropy; + int i; + + entropy = (lhuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(lhuff_entropy_encoder)); + losslsc->entropy_private = (struct jpeg_entropy_encoder *) entropy; + losslsc->pub.entropy_start_pass = start_pass_huff; + losslsc->pub.need_optimization_pass = need_optimization_pass; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->count_ptrs[i] = NULL; +#endif + } +} diff --git a/src/jpeg/libijg/jclossls.c b/src/jpeg/libijg/jclossls.c new file mode 100644 index 00000000..34c95294 --- /dev/null +++ b/src/jpeg/libijg/jclossls.c @@ -0,0 +1,78 @@ +/* + * jclossls.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the control logic for the lossless JPEG compressor. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" + + +#ifdef C_LOSSLESS_SUPPORTED + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + + (*losslsc->scaler_start_pass) (cinfo); + (*losslsc->predict_start_pass) (cinfo); + (*losslsc->diff_start_pass) (cinfo, pass_mode); +} + + +/* + * Initialize the lossless compression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_lossless_c_codec(j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc; + + /* Create subobject in permanent pool */ + losslsc = (j_lossless_c_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(jpeg_lossless_c_codec)); + cinfo->codec = (struct jpeg_c_codec *) losslsc; + + /* Initialize sub-modules */ + + /* Scaler */ + jinit_c_scaler(cinfo); + + /* Differencer */ + jinit_differencer(cinfo); + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + jinit_arith_encoder(cinfo); + } else { + jinit_lhuff_encoder(cinfo); + } + + /* Need a full-image difference buffer in any multi-pass mode. */ + jinit_c_diff_controller(cinfo, + (boolean) (cinfo->num_scans > 1 || + cinfo->optimize_coding)); + + /* Initialize method pointers. + * + * Note: entropy_start_pass and entropy_finish_pass are assigned in + * jclhuff.c and compress_data is assigned in jcdiffct.c. + */ + losslsc->pub.start_pass = start_pass; +} + +#endif /* C_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jclossy.c b/src/jpeg/libijg/jclossy.c new file mode 100644 index 00000000..44847140 --- /dev/null +++ b/src/jpeg/libijg/jclossy.c @@ -0,0 +1,76 @@ +/* + * jclossy.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the control logic for the lossy JPEG compressor. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossy.h" + + +/* + * Initialize for a processing pass. + */ + +METHODDEF(void) +start_pass (j_compress_ptr cinfo, J_BUF_MODE pass_mode) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + + (*lossyc->fdct_start_pass) (cinfo); + (*lossyc->coef_start_pass) (cinfo, pass_mode); +} + + +/* + * Initialize the lossy compression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_lossy_c_codec (j_compress_ptr cinfo) +{ + j_lossy_c_ptr lossyc; + + /* Create subobject in permanent pool */ + lossyc = (j_lossy_c_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(jpeg_lossy_c_codec)); + cinfo->codec = (struct jpeg_c_codec *) lossyc; + + /* Initialize sub-modules */ + + /* Forward DCT */ + jinit_forward_dct(cinfo); + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + jinit_arith_encoder(cinfo); + } else { + if (cinfo->process == JPROC_PROGRESSIVE) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_shuff_encoder(cinfo); + } + + /* Need a full-image coefficient buffer in any multi-pass mode. */ + jinit_c_coef_controller(cinfo, + (boolean) (cinfo->num_scans > 1 || + cinfo->optimize_coding)); + + /* Initialize method pointers. + * + * Note: entropy_start_pass and entropy_finish_pass are assigned in + * jcshuff.c or jcphuff.c and compress_data is assigned in jccoefct.c. + */ + lossyc->pub.start_pass = start_pass; +} diff --git a/src/jpeg/libijg/jcmainct.c b/src/jpeg/libijg/jcmainct.c index 0b30159f..64b51dea 100644 --- a/src/jpeg/libijg/jcmainct.c +++ b/src/jpeg/libijg/jcmainct.c @@ -1,7 +1,7 @@ /* * jcmainct.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -68,32 +68,32 @@ METHODDEF(void) process_data_buffer_main METHODDEF(void) start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; /* Do nothing in raw-data mode. */ if (cinfo->raw_data_in) return; - mainPtr->cur_iMCU_row = 0; /* initialize counters */ - mainPtr->rowgroup_ctr = 0; - mainPtr->suspended = FALSE; - mainPtr->pass_mode = pass_mode; /* save mode for use by process_data */ + main->cur_iMCU_row = 0; /* initialize counters */ + main->rowgroup_ctr = 0; + main->suspended = FALSE; + main->pass_mode = pass_mode; /* save mode for use by process_data */ switch (pass_mode) { case JBUF_PASS_THRU: #ifdef FULL_MAIN_BUFFER_SUPPORTED - if (mainPtr->whole_image[0] != NULL) + if (main->whole_image[0] != NULL) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); #endif - mainPtr->pub.process_data = process_data_simple_main; + main->pub.process_data = process_data_simple_main; break; #ifdef FULL_MAIN_BUFFER_SUPPORTED case JBUF_SAVE_SOURCE: case JBUF_CRANK_DEST: case JBUF_SAVE_AND_PASS: - if (mainPtr->whole_image[0] == NULL) + if (main->whole_image[0] == NULL) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); - mainPtr->pub.process_data = process_data_buffer_main; + main->pub.process_data = process_data_buffer_main; break; #endif default: @@ -114,46 +114,47 @@ process_data_simple_main (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; + JDIMENSION data_unit = (JDIMENSION)(cinfo->data_unit); - while (mainPtr->cur_iMCU_row < cinfo->total_iMCU_rows) { + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { /* Read input data if we haven't filled the main buffer yet */ - if (mainPtr->rowgroup_ctr < DCTSIZE) + if (main->rowgroup_ctr < data_unit) (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr, in_rows_avail, - mainPtr->buffer, &mainPtr->rowgroup_ctr, - (JDIMENSION) DCTSIZE); + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) data_unit); /* If we don't have a full iMCU row buffered, return to application for * more data. Note that preprocessor will always pad to fill the iMCU row * at the bottom of the image. */ - if (mainPtr->rowgroup_ctr != DCTSIZE) + if (main->rowgroup_ctr != data_unit) return; /* Send the completed row to the compressor */ - if (! (*cinfo->coef->compress_data) (cinfo, mainPtr->buffer)) { + if (! (*cinfo->codec->compress_data) (cinfo, main->buffer)) { /* If compressor did not consume the whole row, then we must need to * suspend processing and return to the application. In this situation * we pretend we didn't yet consume the last input row; otherwise, if * it happened to be the last row of the image, the application would * think we were done. */ - if (! mainPtr->suspended) { + if (! main->suspended) { (*in_row_ctr)--; - mainPtr->suspended = TRUE; + main->suspended = TRUE; } return; } /* We did finish the row. Undo our little suspension hack if a previous * call suspended; then mark the main buffer empty. */ - if (mainPtr->suspended) { + if (main->suspended) { (*in_row_ctr)++; - mainPtr->suspended = FALSE; + main->suspended = FALSE; } - mainPtr->rowgroup_ctr = 0; - mainPtr->cur_iMCU_row++; + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; } } @@ -170,25 +171,26 @@ process_data_buffer_main (j_compress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; int ci; jpeg_component_info *compptr; - boolean writing = (mainPtr->pass_mode != JBUF_CRANK_DEST); + boolean writing = (main->pass_mode != JBUF_CRANK_DEST); + JDIMENSION data_unit = (JDIMENSION)(cinfo->data_unit); - while (mainPtr->cur_iMCU_row < cinfo->total_iMCU_rows) { + while (main->cur_iMCU_row < cinfo->total_iMCU_rows) { /* Realign the virtual buffers if at the start of an iMCU row. */ - if (mainPtr->rowgroup_ctr == 0) { + if (main->rowgroup_ctr == 0) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - mainPtr->buffer[ci] = (*cinfo->mem->access_virt_sarray) - ((j_common_ptr) cinfo, mainPtr->whole_image[ci], - mainPtr->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE), - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing); + main->buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, main->whole_image[ci], + main->cur_iMCU_row * (compptr->v_samp_factor * data_unit), + (JDIMENSION) (compptr->v_samp_factor * data_unit), writing); } /* In a read pass, pretend we just read some source data. */ if (! writing) { - *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE; - mainPtr->rowgroup_ctr = DCTSIZE; + *in_row_ctr += cinfo->max_v_samp_factor * data_unit; + main->rowgroup_ctr = data_unit; } } @@ -197,40 +199,40 @@ process_data_buffer_main (j_compress_ptr cinfo, if (writing) { (*cinfo->prep->pre_process_data) (cinfo, input_buf, in_row_ctr, in_rows_avail, - mainPtr->buffer, &mainPtr->rowgroup_ctr, - (JDIMENSION) DCTSIZE); + main->buffer, &main->rowgroup_ctr, + (JDIMENSION) data_unit); /* Return to application if we need more data to fill the iMCU row. */ - if (mainPtr->rowgroup_ctr < DCTSIZE) + if (main->rowgroup_ctr < data_unit) return; } /* Emit data, unless this is a sink-only pass. */ - if (mainPtr->pass_mode != JBUF_SAVE_SOURCE) { - if (! (*cinfo->coef->compress_data) (cinfo, mainPtr->buffer)) { + if (main->pass_mode != JBUF_SAVE_SOURCE) { + if (! (*cinfo->codec->compress_data) (cinfo, main->buffer)) { /* If compressor did not consume the whole row, then we must need to * suspend processing and return to the application. In this situation * we pretend we didn't yet consume the last input row; otherwise, if * it happened to be the last row of the image, the application would * think we were done. */ - if (! mainPtr->suspended) { + if (! main->suspended) { (*in_row_ctr)--; - mainPtr->suspended = TRUE; + main->suspended = TRUE; } return; } /* We did finish the row. Undo our little suspension hack if a previous * call suspended; then mark the main buffer empty. */ - if (mainPtr->suspended) { + if (main->suspended) { (*in_row_ctr)++; - mainPtr->suspended = FALSE; + main->suspended = FALSE; } } /* If get here, we are done with this iMCU row. Mark buffer empty. */ - mainPtr->rowgroup_ctr = 0; - mainPtr->cur_iMCU_row++; + main->rowgroup_ctr = 0; + main->cur_iMCU_row++; } } @@ -244,15 +246,16 @@ process_data_buffer_main (j_compress_ptr cinfo, GLOBAL(void) jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) { - my_main_ptr mainPtr; + my_main_ptr main; int ci; jpeg_component_info *compptr; + int data_unit = cinfo->data_unit; - mainPtr = (my_main_ptr) + main = (my_main_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_main_controller)); - cinfo->main = (struct jpeg_c_main_controller *) mainPtr; - mainPtr->pub.start_pass = start_pass_main; + cinfo->main = (struct jpeg_c_main_controller *) main; + main->pub.start_pass = start_pass_main; /* We don't need to create a buffer in raw-data mode. */ if (cinfo->raw_data_in) @@ -267,27 +270,27 @@ jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer) /* Note we pad the bottom to a multiple of the iMCU height */ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - mainPtr->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + main->whole_image[ci] = (*cinfo->mem->request_virt_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) jround_up((long) compptr->height_in_blocks, - (long) compptr->v_samp_factor) * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + compptr->width_in_data_units * data_unit, + (JDIMENSION) jround_up((long) compptr->height_in_data_units, + (long) compptr->v_samp_factor) * data_unit, + (JDIMENSION) (compptr->v_samp_factor * data_unit)); } #else ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); #endif } else { #ifdef FULL_MAIN_BUFFER_SUPPORTED - mainPtr->whole_image[0] = NULL; /* flag for no virtual arrays */ + main->whole_image[0] = NULL; /* flag for no virtual arrays */ #endif /* Allocate a strip buffer for each component */ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - mainPtr->buffer[ci] = (*cinfo->mem->alloc_sarray) + main->buffer[ci] = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, - compptr->width_in_blocks * DCTSIZE, - (JDIMENSION) (compptr->v_samp_factor * DCTSIZE)); + compptr->width_in_data_units * data_unit, + (JDIMENSION) (compptr->v_samp_factor * data_unit)); } } } diff --git a/src/jpeg/libijg/jcmarker.c b/src/jpeg/libijg/jcmarker.c index 6f089d57..f84f7882 100644 --- a/src/jpeg/libijg/jcmarker.c +++ b/src/jpeg/libijg/jcmarker.c @@ -258,7 +258,6 @@ emit_dac (j_compress_ptr cinfo) } } #endif /* C_ARITH_CODING_SUPPORTED */ - cinfo = 0; } @@ -323,7 +322,7 @@ emit_sos (j_compress_ptr cinfo) emit_byte(cinfo, compptr->component_id); td = compptr->dc_tbl_no; ta = compptr->ac_tbl_no; - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_PROGRESSIVE) { /* Progressive mode: only DC or only AC tables are used in one scan; * furthermore, Huffman coding of DC refinement uses no table at all. * We emit 0 for unused field(s); this is recommended by the P&M text @@ -497,21 +496,23 @@ 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); + if (cinfo->process != JPROC_LOSSLESS) { + /* Emit DQT for each quantization table. + * Note that emit_dqt() suppresses any duplicate tables. + */ + 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. */ } - /* now prec is nonzero iff there are any 16-bit quant tables. */ /* Check for a non-baseline specification. * Note we assume that Huffman table numbers won't be changed later. */ - if (cinfo->arith_code || cinfo->progressive_mode || + if (cinfo->arith_code || cinfo->process != JPROC_SEQUENTIAL || cinfo->data_precision != 8) { is_baseline = FALSE; } else { @@ -530,10 +531,17 @@ write_frame_header (j_compress_ptr cinfo) /* Emit the proper SOF marker */ if (cinfo->arith_code) { - emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */ + if (cinfo->process == JPROC_PROGRESSIVE) + emit_sof(cinfo, M_SOF10); /* SOF code for progressive arithmetic */ + else if (cinfo->process == JPROC_LOSSLESS) + emit_sof(cinfo, M_SOF11); /* SOF code for lossless arithmetic */ + else + emit_sof(cinfo, M_SOF9); /* SOF code for sequential arithmetic */ } else { - if (cinfo->progressive_mode) + if (cinfo->process == JPROC_PROGRESSIVE) emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */ + else if (cinfo->process == JPROC_LOSSLESS) + emit_sof(cinfo, M_SOF3); /* SOF code for lossless Huffman */ else if (is_baseline) emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */ else @@ -567,7 +575,7 @@ write_scan_header (j_compress_ptr cinfo) */ for (i = 0; i < cinfo->comps_in_scan; i++) { compptr = cinfo->cur_comp_info[i]; - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_PROGRESSIVE) { /* Progressive mode: only DC or only AC tables are used in one scan */ if (cinfo->Ss == 0) { if (cinfo->Ah == 0) /* DC needs no table for refinement scan */ @@ -575,6 +583,9 @@ write_scan_header (j_compress_ptr cinfo) } else { emit_dht(cinfo, compptr->ac_tbl_no, TRUE); } + } else if (cinfo->process == JPROC_LOSSLESS) { + /* Lossless mode: only DC tables are used */ + emit_dht(cinfo, compptr->dc_tbl_no, FALSE); } else { /* Sequential mode: need both DC and AC tables */ emit_dht(cinfo, compptr->dc_tbl_no, FALSE); diff --git a/src/jpeg/libijg/jcmaster.c b/src/jpeg/libijg/jcmaster.c index aab4020b..c9851268 100644 --- a/src/jpeg/libijg/jcmaster.c +++ b/src/jpeg/libijg/jcmaster.c @@ -1,7 +1,7 @@ /* * jcmaster.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -14,25 +14,26 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" +#include "jlossy.h" /* Private declarations for lossy codec */ /* Private state */ typedef enum { - main_pass, /* input data, also do first output step */ - huff_opt_pass, /* Huffman code optimization pass */ - output_pass /* data output pass */ + main_pass, /* input data, also do first output step */ + huff_opt_pass, /* Huffman code optimization pass */ + output_pass /* data output 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[] */ } my_comp_master; typedef my_comp_master * my_master_ptr; @@ -50,6 +51,7 @@ initial_setup (j_compress_ptr cinfo) jpeg_component_info *compptr; long samplesperrow; JDIMENSION jd_samplesperrow; + int data_unit = cinfo->data_unit; /* Sanity check on image dimensions */ if (cinfo->image_height <= 0 || cinfo->image_width <= 0 @@ -74,7 +76,7 @@ initial_setup (j_compress_ptr cinfo) /* 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; @@ -82,12 +84,12 @@ initial_setup (j_compress_ptr cinfo) 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 */ @@ -95,22 +97,22 @@ initial_setup (j_compress_ptr cinfo) ci++, compptr++) { /* Fill in the correct component_index value; don't rely on application */ compptr->component_index = ci; - /* For compression, we never do DCT scaling. */ - compptr->DCT_scaled_size = DCTSIZE; - /* Size in DCT blocks */ - compptr->width_in_blocks = (JDIMENSION) + /* For compression, we never do any codec-based processing. */ + compptr->codec_data_unit = data_unit; + /* Size in data units */ + compptr->width_in_data_units = (JDIMENSION) jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->height_in_blocks = (JDIMENSION) + (long) (cinfo->max_h_samp_factor * data_unit)); + compptr->height_in_data_units = (JDIMENSION) jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * DCTSIZE)); + (long) (cinfo->max_v_samp_factor * data_unit)); /* Size in samples */ compptr->downsampled_width = (JDIMENSION) jdiv_round_up((long) cinfo->image_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->image_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; } @@ -120,16 +122,23 @@ initial_setup (j_compress_ptr cinfo) */ cinfo->total_iMCU_rows = (JDIMENSION) jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor*data_unit)); } - #ifdef C_MULTISCAN_FILES_SUPPORTED +#define NEED_SCAN_SCRIPT +#else +#ifdef C_LOSSLESS_SUPPORTED +#define NEED_SCAN_SCRIPT +#endif +#endif + +#ifdef NEED_SCAN_SCRIPT LOCAL(void) validate_script (j_compress_ptr cinfo) /* Verify that the scan script in cinfo->scan_info[] is valid; also - * determine whether it uses progressive JPEG, and set cinfo->progressive_mode. + * determine whether it uses progressive JPEG, and set cinfo->process. */ { const jpeg_scan_info * scanptr; @@ -145,22 +154,36 @@ validate_script (j_compress_ptr cinfo) if (cinfo->num_scans <= 0) ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0); +#ifndef C_MULTISCAN_FILES_SUPPORTED + if (cinfo->num_scans > 1) + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + + scanptr = cinfo->scan_info; + if (cinfo->lossless) { +#ifdef C_LOSSLESS_SUPPORTED + cinfo->process = JPROC_LOSSLESS; + for (ci = 0; ci < cinfo->num_components; ci++) + component_sent[ci] = FALSE; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1; * for progressive JPEG, no scan can have this. */ - scanptr = cinfo->scan_info; - if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { + else if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) { #ifdef C_PROGRESSIVE_SUPPORTED - cinfo->progressive_mode = TRUE; + cinfo->process = JPROC_PROGRESSIVE; last_bitpos_ptr = & last_bitpos[0][0]; 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; + cinfo->process = JPROC_SEQUENTIAL; for (ci = 0; ci < cinfo->num_components; ci++) component_sent[ci] = FALSE; } @@ -173,17 +196,36 @@ 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; Se = scanptr->Se; Ah = scanptr->Ah; Al = scanptr->Al; - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_LOSSLESS) { +#ifdef C_LOSSLESS_SUPPORTED + /* The JPEG spec simply gives the range 0..15 for Al (Pt), but that + * seems wrong: the upper bound ought to depend on data precision. + * Perhaps they really meant 0..N-1 for N-bit precision, which is what + * we allow here. + */ + if (Ss < 1 || Ss > 7 || /* predictor selector */ + Se != 0 || Ah != 0 || + Al < 0 || Al >= cinfo->data_precision) /* point transform */ + ERREXIT1(cinfo, JERR_BAD_LOSSLESS_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; + } +#endif + } else if (cinfo->process == JPROC_PROGRESSIVE) { #ifdef C_PROGRESSIVE_SUPPORTED /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that * seems wrong: the upper bound ought to depend on data precision. @@ -198,49 +240,49 @@ 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; } } } /* Now verify that everything got sent. */ - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_PROGRESSIVE) { #ifdef C_PROGRESSIVE_SUPPORTED /* For progressive mode, we only check that at least some DC data * got sent for each component; the spec does not require that all bits @@ -249,18 +291,18 @@ 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); } } } -#endif /* C_MULTISCAN_FILES_SUPPORTED */ +#endif /* NEED_SCAN_SCRIPT */ LOCAL(void) @@ -269,7 +311,7 @@ select_scan_parameters (j_compress_ptr cinfo) { int ci; -#ifdef C_MULTISCAN_FILES_SUPPORTED +#ifdef NEED_SCAN_SCRIPT if (cinfo->scan_info != NULL) { /* Prepare for current scan --- the script is already validated */ my_master_ptr master = (my_master_ptr) cinfo->master; @@ -278,28 +320,37 @@ 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; cinfo->Ah = scanptr->Ah; cinfo->Al = scanptr->Al; - } - else + } else #endif { /* 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]; } - cinfo->Ss = 0; - cinfo->Se = DCTSIZE2-1; - cinfo->Ah = 0; - cinfo->Al = 0; + if (cinfo->lossless) { +#ifdef C_LOSSLESS_SUPPORTED + /* If we fall through to here, the user specified lossless, but did not + * provide a scan script. + */ + ERREXIT(cinfo, JERR_NO_LOSSLESS_SCRIPT); +#endif + } else { + cinfo->process = JPROC_SEQUENTIAL; + cinfo->Ss = 0; + cinfo->Se = DCTSIZE2-1; + cinfo->Ah = 0; + cinfo->Al = 0; + } } } @@ -311,6 +362,7 @@ per_scan_setup (j_compress_ptr cinfo) { int ci, mcublks, tmp; jpeg_component_info *compptr; + int data_unit = cinfo->data_unit; if (cinfo->comps_in_scan == 1) { @@ -318,24 +370,24 @@ per_scan_setup (j_compress_ptr cinfo) 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; + cinfo->MCUs_per_row = compptr->width_in_data_units; + cinfo->MCU_rows_in_scan = compptr->height_in_data_units; /* For noninterleaved scan, always one block per MCU */ compptr->MCU_width = 1; compptr->MCU_height = 1; - compptr->MCU_blocks = 1; - compptr->MCU_sample_width = DCTSIZE; + compptr->MCU_data_units = 1; + compptr->MCU_sample_width = data_unit; compptr->last_col_width = 1; /* For noninterleaved scans, it is convenient to define last_row_height * as the number of block rows present in the last iMCU row. */ - tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + tmp = (int) (compptr->height_in_data_units % 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->data_units_in_MCU = 1; cinfo->MCU_membership[0] = 0; } else { @@ -343,38 +395,38 @@ per_scan_setup (j_compress_ptr cinfo) /* 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->image_width, - (long) (cinfo->max_h_samp_factor*DCTSIZE)); + (long) (cinfo->max_h_samp_factor*data_unit)); cinfo->MCU_rows_in_scan = (JDIMENSION) jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor*data_unit)); - cinfo->blocks_in_MCU = 0; + cinfo->data_units_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 */ compptr->MCU_width = compptr->h_samp_factor; compptr->MCU_height = compptr->v_samp_factor; - compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; - compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE; + compptr->MCU_data_units = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * data_unit; /* Figure number of non-dummy blocks in last MCU column & row */ - tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + tmp = (int) (compptr->width_in_data_units % compptr->MCU_width); if (tmp == 0) tmp = compptr->MCU_width; compptr->last_col_width = tmp; - tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + tmp = (int) (compptr->height_in_data_units % compptr->MCU_height); if (tmp == 0) tmp = compptr->MCU_height; compptr->last_row_height = tmp; /* 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); + mcublks = compptr->MCU_data_units; + if (cinfo->data_units_in_MCU + mcublks > C_MAX_DATA_UNITS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); while (mcublks-- > 0) { - cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + cinfo->MCU_membership[cinfo->data_units_in_MCU++] = ci; } } @@ -400,6 +452,7 @@ per_scan_setup (j_compress_ptr cinfo) METHODDEF(void) prepare_for_pass (j_compress_ptr cinfo) { + /* j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; */ my_master_ptr master = (my_master_ptr) cinfo->master; switch (master->pass_type) { @@ -414,11 +467,10 @@ prepare_for_pass (j_compress_ptr cinfo) (*cinfo->downsample->start_pass) (cinfo); (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU); } - (*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)); + (*cinfo->codec->entropy_start_pass) (cinfo, cinfo->optimize_coding); + (*cinfo->codec->start_pass) (cinfo, + (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 */ @@ -433,9 +485,9 @@ prepare_for_pass (j_compress_ptr cinfo) /* Do Huffman optimization for a scan after the first one. */ select_scan_parameters(cinfo); per_scan_setup(cinfo); - if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) { - (*cinfo->entropy->start_pass) (cinfo, TRUE); - (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + if ((*cinfo->codec->need_optimization_pass) (cinfo)) { + (*cinfo->codec->entropy_start_pass) (cinfo, TRUE); + (*cinfo->codec->start_pass) (cinfo, JBUF_CRANK_DEST); master->pub.call_pass_startup = FALSE; break; } @@ -453,8 +505,8 @@ prepare_for_pass (j_compress_ptr cinfo) select_scan_parameters(cinfo); per_scan_setup(cinfo); } - (*cinfo->entropy->start_pass) (cinfo, FALSE); - (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST); + (*cinfo->codec->entropy_start_pass) (cinfo, FALSE); + (*cinfo->codec->start_pass) (cinfo, JBUF_CRANK_DEST); /* We emit frame/scan headers now */ if (master->scan_number == 0) (*cinfo->marker->write_frame_header) (cinfo); @@ -502,12 +554,13 @@ pass_startup (j_compress_ptr cinfo) METHODDEF(void) finish_pass_master (j_compress_ptr cinfo) { + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; my_master_ptr master = (my_master_ptr) cinfo->master; /* The entropy coder always needs an end-of-pass call, * either to analyze statistics or to flush its output buffer. */ - (*cinfo->entropy->finish_pass) (cinfo); + (*lossyc->pub.entropy_finish_pass) (cinfo); /* Update state for next pass */ switch (master->pass_type) { @@ -546,29 +599,34 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) master = (my_master_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_comp_master)); + SIZEOF(my_comp_master)); cinfo->master = (struct jpeg_comp_master *) master; master->pub.prepare_for_pass = prepare_for_pass; master->pub.pass_startup = pass_startup; master->pub.finish_pass = finish_pass_master; master->pub.is_last_pass = FALSE; + cinfo->data_unit = cinfo->lossless ? 1 : DCTSIZE; + /* Validate parameters, determine derived values */ initial_setup(cinfo); if (cinfo->scan_info != NULL) { -#ifdef C_MULTISCAN_FILES_SUPPORTED +#ifdef NEED_SCAN_SCRIPT validate_script(cinfo); #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif } else { - cinfo->progressive_mode = FALSE; + cinfo->process = JPROC_SEQUENTIAL; cinfo->num_scans = 1; } - if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */ - cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + if ((cinfo->arith_code == 0) && + (cinfo->process == JPROC_PROGRESSIVE || /* TEMPORARY HACK ??? */ + cinfo->process == JPROC_LOSSLESS)) + cinfo->optimize_coding = TRUE; /* assume default tables no good for + * progressive mode or lossless mode */ /* Initialize my private state */ if (transcode_only) { diff --git a/src/jpeg/libijg/jcodec.c b/src/jpeg/libijg/jcodec.c new file mode 100644 index 00000000..9529caaa --- /dev/null +++ b/src/jpeg/libijg/jcodec.c @@ -0,0 +1,53 @@ +/* + * jcodec.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains utility functions for the JPEG codec(s). + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossy.h" +#include "jlossls.h" + + +/* + * Initialize the compression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_c_codec (j_compress_ptr cinfo) +{ + if (cinfo->process == JPROC_LOSSLESS) { +#ifdef C_LOSSLESS_SUPPORTED + jinit_lossless_c_codec(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_lossy_c_codec(cinfo); +} + + +/* + * Initialize the decompression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_d_codec (j_decompress_ptr cinfo) +{ + if (cinfo->process == JPROC_LOSSLESS) { +#ifdef D_LOSSLESS_SUPPORTED + jinit_lossless_d_codec(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_lossy_d_codec(cinfo); +} diff --git a/src/jpeg/libijg/jcomapi.c b/src/jpeg/libijg/jcomapi.c index 9b1fa756..2d45449a 100644 --- a/src/jpeg/libijg/jcomapi.c +++ b/src/jpeg/libijg/jcomapi.c @@ -72,8 +72,8 @@ jpeg_destroy (j_common_ptr cinfo) /* NB: mem pointer is NULL if memory mgr failed to initialize. */ if (cinfo->mem != NULL) (*cinfo->mem->self_destruct) (cinfo); - cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ - cinfo->global_state = 0; /* mark it destroyed */ + cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */ + cinfo->global_state = 0; /* mark it destroyed */ } @@ -89,7 +89,7 @@ jpeg_alloc_quant_table (j_common_ptr cinfo) tbl = (JQUANT_TBL *) (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JQUANT_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ + tbl->sent_table = FALSE; /* make sure this is false in any new table */ return tbl; } @@ -101,6 +101,6 @@ jpeg_alloc_huff_table (j_common_ptr cinfo) tbl = (JHUFF_TBL *) (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL)); - tbl->sent_table = FALSE; /* make sure this is false in any new table */ + tbl->sent_table = FALSE; /* make sure this is false in any new table */ return tbl; } diff --git a/src/jpeg/libijg/jconfig.h b/src/jpeg/libijg/jconfig.h deleted file mode 100644 index fc0d3d89..00000000 --- a/src/jpeg/libijg/jconfig.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef _MSC_VER - #include "jconfig.vc" -#endif -#ifdef __GNUC__ - #include "jconfig.linux" -#endif - diff --git a/src/jpeg/libijg/jconfig.h.in b/src/jpeg/libijg/jconfig.h.in index 9a6b39dd..39740333 100644 --- a/src/jpeg/libijg/jconfig.h.in +++ b/src/jpeg/libijg/jconfig.h.in @@ -63,5 +63,4 @@ typedef unsigned char boolean; /* GDCM stuff */ #include "@BITS_TYPE_JPEG_MANGLE_NAME@" -//#include "jinclude.h" -//#include "jpeglib.h" + diff --git a/src/jpeg/libijg/jconfig.linux b/src/jpeg/libijg/jconfig.linux deleted file mode 100644 index 9594ec56..00000000 --- a/src/jpeg/libijg/jconfig.linux +++ /dev/null @@ -1,45 +0,0 @@ -/* jconfig.h. Generated automatically by configure. */ -/* jconfig.cfg --- source file edited by configure script */ -/* see jconfig.doc for explanations */ - -#define HAVE_PROTOTYPES -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT -#undef void -#undef const -#undef CHAR_IS_UNSIGNED -#define HAVE_STDDEF_H -#define HAVE_STDLIB_H -#undef NEED_BSD_STRINGS -#undef NEED_SYS_TYPES_H -#undef NEED_FAR_POINTERS -#undef NEED_SHORT_EXTERNAL_NAMES -/* Define this if you get warnings about undefined structures. */ -#undef INCOMPLETE_TYPES_BROKEN - -#ifdef JPEG_INTERNALS - -#undef RIGHT_SHIFT_IS_UNSIGNED -#define INLINE __inline__ -/* These are for configuring the JPEG memory manager. */ -#undef DEFAULT_MAX_MEM -#undef NO_MKTEMP - -#endif /* JPEG_INTERNALS */ - -#ifdef JPEG_CJPEG_DJPEG - -#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 */ - -#undef TWO_FILE_COMMANDLINE -#undef NEED_SIGNAL_CATCHER -#undef DONT_USE_B_MODE - -/* Define this if you want percent-done progress reports from cjpeg/djpeg. */ -#undef PROGRESS_REPORT - -#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/jpeg/libijg/jconfig.vc b/src/jpeg/libijg/jconfig.vc deleted file mode 100644 index 7e291c75..00000000 --- a/src/jpeg/libijg/jconfig.vc +++ /dev/null @@ -1,45 +0,0 @@ -/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */ -/* see jconfig.doc for explanations */ - -#define HAVE_PROTOTYPES -#define HAVE_UNSIGNED_CHAR -#define HAVE_UNSIGNED_SHORT -/* #define void char */ -/* #define const */ -#undef CHAR_IS_UNSIGNED -#define HAVE_STDDEF_H -#define HAVE_STDLIB_H -#undef NEED_BSD_STRINGS -#undef NEED_SYS_TYPES_H -#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */ -#undef NEED_SHORT_EXTERNAL_NAMES -#undef INCOMPLETE_TYPES_BROKEN - -/* Define "boolean" as unsigned char, not int, per Windows custom */ -#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 */ - - -#ifdef JPEG_INTERNALS - -#undef RIGHT_SHIFT_IS_UNSIGNED - -#endif /* JPEG_INTERNALS */ - -#ifdef JPEG_CJPEG_DJPEG - -#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 TWO_FILE_COMMANDLINE /* optional */ -#define USE_SETMODE /* Microsoft has setmode() */ -#undef NEED_SIGNAL_CATCHER -#undef DONT_USE_B_MODE -#undef PROGRESS_REPORT /* optional */ - -#endif /* JPEG_CJPEG_DJPEG */ diff --git a/src/jpeg/libijg/jcparam.c b/src/jpeg/libijg/jcparam.c index 6fc48f53..1f3d0022 100644 --- a/src/jpeg/libijg/jcparam.c +++ b/src/jpeg/libijg/jcparam.c @@ -21,8 +21,8 @@ GLOBAL(void) jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, boolean force_baseline) + const unsigned int *basic_table, + int scale_factor, boolean force_baseline) /* Define a quantization table equal to the basic_table times * a scale factor (given as a percentage). * If force_baseline is TRUE, the computed quantization table entries @@ -51,7 +51,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, if (temp <= 0L) temp = 1L; if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */ if (force_baseline && temp > 255L) - temp = 255L; /* limit to baseline range if requested */ + temp = 255L; /* limit to baseline range if requested */ (*qtblptr)->quantval[i] = (UINT16) temp; } @@ -62,7 +62,7 @@ jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl, GLOBAL(void) jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, - boolean force_baseline) + boolean force_baseline) /* Set or change the 'quality' (quantization) setting, using default tables * and a straight percentage-scaling quality scale. In most cases it's better * to use jpeg_set_quality (below); this entry point is provided for @@ -96,9 +96,9 @@ jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor, /* Set up two quantization tables using the specified scaling */ jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl, - scale_factor, force_baseline); + scale_factor, force_baseline); jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl, - scale_factor, force_baseline); + scale_factor, force_baseline); } @@ -150,7 +150,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) LOCAL(void) add_huff_table (j_compress_ptr cinfo, - JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) + JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val) /* Define a Huffman table */ { int nsymbols, len; @@ -244,13 +244,13 @@ std_huff_tables (j_compress_ptr cinfo) 0xf9, 0xfa }; add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0], - bits_dc_luminance, val_dc_luminance); + bits_dc_luminance, val_dc_luminance); add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0], - bits_ac_luminance, val_ac_luminance); + bits_ac_luminance, val_ac_luminance); add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1], - bits_dc_chrominance, val_dc_chrominance); + bits_dc_chrominance, val_dc_chrominance); add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1], - bits_ac_chrominance, val_ac_chrominance); + bits_ac_chrominance, val_ac_chrominance); } @@ -280,10 +280,11 @@ jpeg_set_defaults (j_compress_ptr cinfo) if (cinfo->comp_info == NULL) cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - MAX_COMPONENTS * SIZEOF(jpeg_component_info)); + MAX_COMPONENTS * SIZEOF(jpeg_component_info)); /* Initialize everything not dependent on the color space */ + cinfo->lossless = FALSE; cinfo->data_precision = BITS_IN_JSAMPLE; /* Set up two quantization tables using default quality of 75 */ jpeg_set_quality(cinfo, 75, TRUE); @@ -341,8 +342,8 @@ jpeg_set_defaults (j_compress_ptr cinfo) */ cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */ cinfo->JFIF_minor_version = 1; - cinfo->density_unit = 0; /* Pixel size is unknown by default */ - cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ + cinfo->density_unit = 0; /* Pixel size is unknown by default */ + cinfo->X_density = 1; /* Pixel aspect ratio is square by default */ cinfo->Y_density = 1; /* Choose JPEG colorspace based on input space, set defaults accordingly */ @@ -358,27 +359,31 @@ jpeg_set_defaults (j_compress_ptr cinfo) GLOBAL(void) jpeg_default_colorspace (j_compress_ptr cinfo) { - switch (cinfo->in_color_space) { - case JCS_GRAYSCALE: - jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); - break; - case JCS_RGB: - jpeg_set_colorspace(cinfo, JCS_YCbCr); - break; - case JCS_YCbCr: - jpeg_set_colorspace(cinfo, JCS_YCbCr); - break; - case JCS_CMYK: - jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ - break; - case JCS_YCCK: - jpeg_set_colorspace(cinfo, JCS_YCCK); - break; - case JCS_UNKNOWN: - jpeg_set_colorspace(cinfo, JCS_UNKNOWN); - break; - default: - ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + if (cinfo->lossless) + jpeg_set_colorspace(cinfo, cinfo->in_color_space); + else { /* lossy */ + switch (cinfo->in_color_space) { + case JCS_GRAYSCALE: + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + break; + case JCS_RGB: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_YCbCr: + jpeg_set_colorspace(cinfo, JCS_YCbCr); + break; + case JCS_CMYK: + jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */ + break; + case JCS_YCCK: + jpeg_set_colorspace(cinfo, JCS_YCCK); + break; + case JCS_UNKNOWN: + jpeg_set_colorspace(cinfo, JCS_UNKNOWN); + break; + default: + ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE); + } } } @@ -433,10 +438,16 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */ cinfo->num_components = 3; /* JFIF specifies component IDs 1,2,3 */ - /* We default to 2x2 subsamples of chrominance */ - SET_COMP(0, 1, 2,2, 0, 0,0); - SET_COMP(1, 2, 1,1, 1, 1,1); - SET_COMP(2, 3, 1,1, 1, 1,1); + if (cinfo->lossless) { + SET_COMP(0, 1, 1,1, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + } else { /* lossy */ + /* We default to 2x2 subsamples of chrominance */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + } break; case JCS_CMYK: cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */ @@ -449,16 +460,23 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) case JCS_YCCK: cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */ cinfo->num_components = 4; - SET_COMP(0, 1, 2,2, 0, 0,0); - SET_COMP(1, 2, 1,1, 1, 1,1); - SET_COMP(2, 3, 1,1, 1, 1,1); - SET_COMP(3, 4, 2,2, 0, 0,0); + if (cinfo->lossless) { + SET_COMP(0, 1, 1,1, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 1,1, 0, 0,0); + } else { /* lossy */ + SET_COMP(0, 1, 2,2, 0, 0,0); + SET_COMP(1, 2, 1,1, 1, 1,1); + SET_COMP(2, 3, 1,1, 1, 1,1); + SET_COMP(3, 4, 2,2, 0, 0,0); + } break; case JCS_UNKNOWN: cinfo->num_components = cinfo->input_components; if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS) ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, - MAX_COMPONENTS); + MAX_COMPONENTS); for (ci = 0; ci < cinfo->num_components; ci++) { SET_COMP(ci, ci, 1,1, 0, 0,0); } @@ -471,24 +489,9 @@ jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace) #ifdef C_PROGRESSIVE_SUPPORTED -LOCAL(jpeg_scan_info *) -fill_a_scan (jpeg_scan_info * scanptr, int ci, - int Ss, int Se, int Ah, int Al) -/* Support routine: generate one scan for specified component */ -{ - scanptr->comps_in_scan = 1; - scanptr->component_index[0] = ci; - scanptr->Ss = Ss; - scanptr->Se = Se; - scanptr->Ah = Ah; - scanptr->Al = Al; - scanptr++; - return scanptr; -} - LOCAL(jpeg_scan_info *) fill_scans (jpeg_scan_info * scanptr, int ncomps, - int Ss, int Se, int Ah, int Al) + int Ss, int Se, int Ah, int Al) /* Support routine: generate one scan for each component */ { int ci; @@ -505,6 +508,22 @@ fill_scans (jpeg_scan_info * scanptr, int ncomps, return scanptr; } + +LOCAL(jpeg_scan_info *) +fill_a_scan (jpeg_scan_info * scanptr, int ci, + int Ss, int Se, int Ah, int Al) +/* Support routine: generate one scan for specified component */ +{ + scanptr->comps_in_scan = 1; + scanptr->component_index[0] = ci; + scanptr->Ss = Ss; + scanptr->Se = Se; + scanptr->Ah = Ah; + scanptr->Al = Al; + scanptr++; + return scanptr; +} + LOCAL(jpeg_scan_info *) fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al) /* Support routine: generate interleaved DC scan if possible, else N scans */ @@ -551,9 +570,9 @@ jpeg_simple_progression (j_compress_ptr cinfo) } else { /* All-purpose script for other color spaces. */ if (ncomps > MAX_COMPS_IN_SCAN) - nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ + nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */ else - nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ + nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */ } /* Allocate space for script. @@ -567,7 +586,7 @@ jpeg_simple_progression (j_compress_ptr cinfo) cinfo->script_space_size = MAX(nscans, 10); cinfo->script_space = (jpeg_scan_info *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); } scanptr = cinfo->script_space; cinfo->scan_info = scanptr; @@ -608,3 +627,61 @@ jpeg_simple_progression (j_compress_ptr cinfo) } #endif /* C_PROGRESSIVE_SUPPORTED */ + + +#ifdef C_LOSSLESS_SUPPORTED + +/* + * Create a single-entry lossless-JPEG script containing all components. + * cinfo->num_components must be correct. + */ + +GLOBAL(void) +jpeg_simple_lossless (j_compress_ptr cinfo, int predictor, int point_transform) +{ + int ncomps = cinfo->num_components; + int nscans = 1; + int ci; + jpeg_scan_info * scanptr; + + /* Safety check to ensure start_compress not called yet. */ + if (cinfo->global_state != CSTATE_START) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); + + cinfo->lossless = TRUE; + + /* Set jpeg_color_space. */ + jpeg_default_colorspace(cinfo); + + /* Check to ensure that all components will fit in one scan. */ + if (cinfo->num_components > MAX_COMPS_IN_SCAN) + ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components, + MAX_COMPS_IN_SCAN); + + /* Allocate space for script. + * We need to put it in the permanent pool in case the application performs + * multiple compressions without changing the settings. To avoid a memory + * leak if jpeg_simple_lossless is called repeatedly for the same JPEG + * object, we try to re-use previously allocated space. + */ + if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) { + cinfo->script_space_size = nscans; + cinfo->script_space = (jpeg_scan_info *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + cinfo->script_space_size * SIZEOF(jpeg_scan_info)); + } + scanptr = cinfo->script_space; + cinfo->scan_info = scanptr; + cinfo->num_scans = nscans; + + /* Fill the script. */ + scanptr->comps_in_scan = ncomps; + for (ci = 0; ci < ncomps; ci++) + scanptr->component_index[ci] = ci; + scanptr->Ss = predictor; + scanptr->Se = 0; + scanptr->Ah = 0; + scanptr->Al = point_transform; +} + +#endif /* C_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jcphuff.c b/src/jpeg/libijg/jcphuff.c index 07f9178b..63b9e461 100644 --- a/src/jpeg/libijg/jcphuff.c +++ b/src/jpeg/libijg/jcphuff.c @@ -1,7 +1,7 @@ /* * jcphuff.c * - * Copyright (C) 1995-1997, Thomas G. Lane. + * Copyright (C) 1995-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -15,39 +15,38 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jchuff.h" /* Declarations shared with jchuff.c */ +#include "jlossy.h" /* Private declarations for lossy codec */ +#include "jchuff.h" /* Declarations shared with jc*huff.c */ #ifdef C_PROGRESSIVE_SUPPORTED /* Expanded entropy encoder object for progressive Huffman encoding. */ typedef struct { - struct jpeg_entropy_encoder pub; /* public fields */ - /* Mode flag: TRUE for optimization, FALSE for actual data output */ boolean gather_statistics; /* Bit-level coding status. * next_output_byte/free_in_buffer are local copies of cinfo->dest fields. */ - JOCTET * next_output_byte; /* => next byte to write in buffer */ - size_t free_in_buffer; /* # of byte spaces remaining in buffer */ - INT32 put_buffer; /* current bit-accumulation buffer */ - int put_bits; /* # of bits now in it */ - j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */ /* Coding status for DC components */ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ /* Coding status for AC components */ - int ac_tbl_no; /* the table number of the single component */ - unsigned int EOBRUN; /* run length of EOBs */ - unsigned int BE; /* # of buffered correction bits before MCU */ - char * bit_buffer; /* buffer for correction bits (1 per char) */ + int ac_tbl_no; /* the table number of the single component */ + unsigned int EOBRUN; /* run length of EOBs */ + unsigned int BE; /* # of buffered correction bits before MCU */ + char * bit_buffer; /* buffer for correction bits (1 per char) */ /* packing correction bits tightly would save some space but cost time... */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - int next_restart_num; /* next restart number to write (0-7) */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ /* Pointers to derived tables (these workspaces have image lifespan). * Since any one scan codes only DC or only AC, we only need one set @@ -67,7 +66,7 @@ typedef phuff_entropy_encoder * phuff_entropy_ptr; * The minimum safe size is 64 bits. */ -#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ +#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */ /* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32. * We assume that int right shift is unsigned if INT32 right shift is, @@ -75,25 +74,25 @@ typedef phuff_entropy_encoder * phuff_entropy_ptr; */ #ifdef RIGHT_SHIFT_IS_UNSIGNED -#define ISHIFT_TEMPS int ishift_temp; +#define ISHIFT_TEMPS int ishift_temp; #define IRIGHT_SHIFT(x,shft) \ - ((ishift_temp = (x)) < 0 ? \ - (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ - (ishift_temp >> (shft))) + ((ishift_temp = (x)) < 0 ? \ + (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \ + (ishift_temp >> (shft))) #else #define ISHIFT_TEMPS -#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) #endif /* Forward declarations */ METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo)); METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); @@ -105,7 +104,8 @@ METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo)); METHODDEF(void) start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; boolean is_DC_band; int ci, tbl; jpeg_component_info * compptr; @@ -120,25 +120,25 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) /* Select execution routines */ if (cinfo->Ah == 0) { if (is_DC_band) - entropy->pub.encode_mcu = encode_mcu_DC_first; + lossyc->entropy_encode_mcu = encode_mcu_DC_first; else - entropy->pub.encode_mcu = encode_mcu_AC_first; + lossyc->entropy_encode_mcu = encode_mcu_AC_first; } else { if (is_DC_band) - entropy->pub.encode_mcu = encode_mcu_DC_refine; + lossyc->entropy_encode_mcu = encode_mcu_DC_refine; else { - entropy->pub.encode_mcu = encode_mcu_AC_refine; + lossyc->entropy_encode_mcu = encode_mcu_AC_refine; /* AC refinement needs a correction bit buffer */ if (entropy->bit_buffer == NULL) - entropy->bit_buffer = (char *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - MAX_CORR_BITS * SIZEOF(char)); + entropy->bit_buffer = (char *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + MAX_CORR_BITS * SIZEOF(char)); } } if (gather_statistics) - entropy->pub.finish_pass = finish_pass_gather_phuff; + lossyc->pub.entropy_finish_pass = finish_pass_gather_phuff; else - entropy->pub.finish_pass = finish_pass_phuff; + lossyc->pub.entropy_finish_pass = finish_pass_phuff; /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1 * for AC coefficients. @@ -149,8 +149,8 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) entropy->last_dc_val[ci] = 0; /* Get table index */ if (is_DC_band) { - if (cinfo->Ah != 0) /* DC refinement needs no table */ - continue; + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; tbl = compptr->dc_tbl_no; } else { entropy->ac_tbl_no = tbl = compptr->ac_tbl_no; @@ -163,15 +163,15 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) /* Allocate and zero the statistics tables */ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ if (entropy->count_ptrs[tbl] == NULL) - entropy->count_ptrs[tbl] = (long *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - 257 * SIZEOF(long)); + entropy->count_ptrs[tbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long)); } else { /* Compute derived values for Huffman table */ /* We may do this more than once for a table, but it's not expensive */ jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl, - & entropy->derived_tbls[tbl]); + & entropy->derived_tbls[tbl]); } } @@ -196,9 +196,9 @@ start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics) /* Emit a byte */ #define emit_byte(entropy,val) \ - { *(entropy)->next_output_byte++ = (JOCTET) (val); \ - if (--(entropy)->free_in_buffer == 0) \ - dump_buffer(entropy); } + { *(entropy)->next_output_byte++ = (JOCTET) (val); \ + if (--(entropy)->free_in_buffer == 0) \ + dump_buffer(entropy); } LOCAL(void) @@ -237,11 +237,11 @@ emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size) ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE); if (entropy->gather_statistics) - return; /* do nothing if we're only getting stats */ + return; /* do nothing if we're only getting stats */ put_buffer &= (((INT32) 1)<> 16) & 0xFF); emit_byte(entropy, c); - if (c == 0xFF) { /* need to stuff a zero byte? */ + if (c == 0xFF) { /* need to stuff a zero byte? */ emit_byte(entropy, 0); } put_buffer <<= 8; @@ -295,10 +295,10 @@ emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol) LOCAL(void) emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart, - unsigned int nbits) + unsigned int nbits) { if (entropy->gather_statistics) - return; /* no real work */ + return; /* no real work */ while (nbits > 0) { emit_bits(entropy, (unsigned int) (*bufstart), 1); @@ -317,7 +317,7 @@ emit_eobrun (phuff_entropy_ptr entropy) { register int temp, nbits; - if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ + if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */ temp = entropy->EOBRUN; nbits = 0; while ((temp >>= 1)) @@ -376,7 +376,8 @@ emit_restart (phuff_entropy_ptr entropy, int restart_num) METHODDEF(boolean) encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; register int temp, temp2; register int nbits; int blkn, ci; @@ -394,7 +395,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) emit_restart(entropy, entropy->next_restart_num); /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { block = MCU_data[blkn]; ci = cinfo->MCU_membership[blkn]; compptr = cinfo->cur_comp_info[ci]; @@ -411,7 +412,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Encode the DC coefficient difference per section G.1.2.1 */ temp2 = temp; if (temp < 0) { - temp = -temp; /* temp is abs value of input */ + temp = -temp; /* temp is abs value of input */ /* For a negative input, want temp2 = bitwise complement of abs(input) */ /* This code assumes we are on a two's complement machine */ temp2--; @@ -434,7 +435,7 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Emit that number of bits of the value, if positive, */ /* or the complement of its magnitude, if negative. */ - if (nbits) /* emit_bits rejects calls with size 0 */ + if (nbits) /* emit_bits rejects calls with size 0 */ emit_bits(entropy, (unsigned int) temp2, nbits); } @@ -463,7 +464,8 @@ encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; register int temp, temp2; register int nbits; register int r, k; @@ -484,7 +486,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */ - r = 0; /* r = run length of zeros */ + r = 0; /* r = run length of zeros */ for (k = cinfo->Ss; k <= Se; k++) { if ((temp = (*block)[jpeg_natural_order[k]]) == 0) { @@ -497,12 +499,12 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * interwoven with finding the abs value (temp) and output bits (temp2). */ if (temp < 0) { - temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ /* For a negative coef, want temp2 = bitwise complement of abs(coef) */ temp2 = ~temp; } else { - temp >>= Al; /* apply the point transform */ + temp >>= Al; /* apply the point transform */ temp2 = temp; } /* Watch out for case that nonzero coef is zero after point transform */ @@ -521,7 +523,7 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) } /* Find the number of bits needed for the magnitude of the coefficient */ - nbits = 1; /* there must be at least one 1 bit */ + nbits = 1; /* there must be at least one 1 bit */ while ((temp >>= 1)) nbits++; /* Check for out-of-range coefficient values */ @@ -535,13 +537,13 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) /* or the complement of its magnitude, if negative. */ emit_bits(entropy, (unsigned int) temp2, nbits); - r = 0; /* reset zero run length */ + r = 0; /* reset zero run length */ } - if (r > 0) { /* If there are trailing zeroes, */ - entropy->EOBRUN++; /* count an EOB */ + if (r > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ if (entropy->EOBRUN == 0x7FFF) - emit_eobrun(entropy); /* force it out to avoid overflow */ + emit_eobrun(entropy); /* force it out to avoid overflow */ } cinfo->dest->next_output_byte = entropy->next_output_byte; @@ -570,7 +572,8 @@ encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; register int temp; int blkn; int Al = cinfo->Al; @@ -585,7 +588,7 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) emit_restart(entropy, entropy->next_restart_num); /* Encode the MCU data blocks */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { block = MCU_data[blkn]; /* We simply emit the Al'th bit of the DC coefficient value. */ @@ -617,7 +620,8 @@ encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; register int temp; register int r, k; int EOB; @@ -650,17 +654,17 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) * in C, we shift after obtaining the absolute value. */ if (temp < 0) - temp = -temp; /* temp is abs value of input */ - temp >>= Al; /* apply the point transform */ - absvalues[k] = temp; /* save abs value for main pass */ + temp = -temp; /* temp is abs value of input */ + temp >>= Al; /* apply the point transform */ + absvalues[k] = temp; /* save abs value for main pass */ if (temp == 1) - EOB = k; /* EOB = index of last newly-nonzero coef */ + EOB = k; /* EOB = index of last newly-nonzero coef */ } /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */ - r = 0; /* r = run length of zeros */ - BR = 0; /* BR = count of buffered bits added now */ + r = 0; /* r = run length of zeros */ + BR = 0; /* BR = count of buffered bits added now */ BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */ for (k = cinfo->Ss; k <= Se; k++) { @@ -707,12 +711,12 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) emit_buffered_bits(entropy, BR_buffer, BR); BR_buffer = entropy->bit_buffer; /* BE bits are gone now */ BR = 0; - r = 0; /* reset zero run length */ + r = 0; /* reset zero run length */ } - if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ - entropy->EOBRUN++; /* count an EOB */ - entropy->BE += BR; /* concat my correction bits to older ones */ + if (r > 0 || BR > 0) { /* If there are trailing zeroes, */ + entropy->EOBRUN++; /* count an EOB */ + entropy->BE += BR; /* concat my correction bits to older ones */ /* We force out the EOB if we risk either: * 1. overflow of the EOB counter; * 2. overflow of the correction bit buffer during the next MCU. @@ -745,7 +749,8 @@ encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(void) finish_pass_phuff (j_compress_ptr cinfo) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -766,7 +771,8 @@ finish_pass_phuff (j_compress_ptr cinfo) METHODDEF(void) finish_pass_gather_phuff (j_compress_ptr cinfo) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyc->entropy_private; boolean is_DC_band; int ci, tbl; jpeg_component_info * compptr; @@ -786,8 +792,8 @@ finish_pass_gather_phuff (j_compress_ptr cinfo) for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; if (is_DC_band) { - if (cinfo->Ah != 0) /* DC refinement needs no table */ - continue; + if (cinfo->Ah != 0) /* DC refinement needs no table */ + continue; tbl = compptr->dc_tbl_no; } else { tbl = compptr->ac_tbl_no; @@ -806,6 +812,13 @@ finish_pass_gather_phuff (j_compress_ptr cinfo) } +METHODDEF(boolean) +need_optimization_pass (j_compress_ptr cinfo) +{ + return (cinfo->Ss != 0 || cinfo->Ah == 0); +} + + /* * Module initialization routine for progressive Huffman entropy encoding. */ @@ -813,21 +826,23 @@ finish_pass_gather_phuff (j_compress_ptr cinfo) GLOBAL(void) jinit_phuff_encoder (j_compress_ptr cinfo) { + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; phuff_entropy_ptr entropy; int i; entropy = (phuff_entropy_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(phuff_entropy_encoder)); - cinfo->entropy = (struct jpeg_entropy_encoder *) entropy; - entropy->pub.start_pass = start_pass_phuff; + SIZEOF(phuff_entropy_encoder)); + lossyc->entropy_private = (struct jpeg_entropy_encoder *) entropy; + lossyc->pub.entropy_start_pass = start_pass_phuff; + lossyc->pub.need_optimization_pass = need_optimization_pass; /* Mark tables unallocated */ for (i = 0; i < NUM_HUFF_TBLS; i++) { entropy->derived_tbls[i] = NULL; entropy->count_ptrs[i] = NULL; } - entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ + entropy->bit_buffer = NULL; /* needed only in AC refinement scan */ } #endif /* C_PROGRESSIVE_SUPPORTED */ diff --git a/src/jpeg/libijg/jcpred.c b/src/jpeg/libijg/jcpred.c new file mode 100644 index 00000000..8a731847 --- /dev/null +++ b/src/jpeg/libijg/jcpred.c @@ -0,0 +1,300 @@ +/* + * jcpred.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains sample differencing for lossless JPEG. + * + * In order to avoid paying the performance penalty of having to check the + * predictor being used and the row being processed for each call of the + * undifferencer, and to promote optimization, we have separate differencing + * functions for each case. + * + * We are able to avoid duplicating source code by implementing the predictors + * and differencers as macros. Each of the differencing functions are + * simply wrappers around a DIFFERENCE macro with the appropriate PREDICTOR + * macro passed as an argument. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ + + +#ifdef C_LOSSLESS_SUPPORTED + +/* Private predictor object */ + +typedef struct { + /* MCU-rows left in the restart interval for each component */ + unsigned int restart_rows_to_go[MAX_COMPONENTS]; +} c_predictor; + +typedef c_predictor * c_pred_ptr; + +/* Forward declarations */ +LOCAL(void) reset_predictor + JPP((j_compress_ptr cinfo, int ci)); +METHODDEF(void) start_pass + JPP((j_compress_ptr cinfo)); + + +/* Predictor for the first column of the first row: 2^(P-Pt-1) */ +#define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1)) + +/* Predictor for the first column of the remaining rows: Rb */ +#define INITIAL_PREDICTOR2 GETJSAMPLE(prev_row[0]) + + +/* + * 1-Dimensional differencer routine. + * + * This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR + * is used as the special case predictor for the first column, which must be + * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples + * use PREDICTOR1. + */ + +#define DIFFERENCE_1D(INITIAL_PREDICTOR) \ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \ + c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \ + boolean restart = FALSE; \ + unsigned int xindex; \ + int samp, Ra; \ + \ + samp = GETJSAMPLE(input_buf[0]); \ + diff_buf[0] = samp - INITIAL_PREDICTOR; \ + \ + for (xindex = 1; xindex < width; xindex++) { \ + Ra = samp; \ + samp = GETJSAMPLE(input_buf[xindex]); \ + diff_buf[xindex] = samp - PREDICTOR1; \ + } \ + \ + /* Account for restart interval (no-op if not using restarts) */ \ + if (cinfo->restart_interval) { \ + if (--(pred->restart_rows_to_go[ci]) == 0) { \ + reset_predictor(cinfo, ci); \ + restart = TRUE; \ + } \ + } + + +/* + * 2-Dimensional differencer routine. + * + * This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is + * used as the special case predictor for the first column. The remaining + * samples use PREDICTOR, which is a function of Ra, Rb, Rc. + * + * Because prev_row and output_buf may point to the same storage area (in an + * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc + * before writing the current reconstructed sample value into output_buf. + */ + +#define DIFFERENCE_2D(PREDICTOR) \ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; \ + c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; \ + unsigned int xindex; \ + int samp, Ra, Rb, Rc; \ + \ + Rb = GETJSAMPLE(prev_row[0]); \ + samp = GETJSAMPLE(input_buf[0]); \ + diff_buf[0] = samp - PREDICTOR2; \ + \ + for (xindex = 1; xindex < width; xindex++) { \ + Rc = Rb; \ + Rb = GETJSAMPLE(prev_row[xindex]); \ + Ra = samp; \ + samp = GETJSAMPLE(input_buf[xindex]); \ + diff_buf[xindex] = samp - PREDICTOR; \ + } \ + \ + /* Account for restart interval (no-op if not using restarts) */ \ + if (cinfo->restart_interval) { \ + if (--pred->restart_rows_to_go[ci] == 0) \ + reset_predictor(cinfo, ci); \ + } + + +/* + * Differencers for the all rows but the first in a scan or restart interval. + * The first sample in the row is differenced using the vertical + * predictor (2). The rest of the samples are differenced using the + * predictor specified in the scan header. + */ + +METHODDEF(void) +jpeg_difference1(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + DIFFERENCE_1D(INITIAL_PREDICTOR2); +} + +METHODDEF(void) +jpeg_difference2(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + DIFFERENCE_2D(PREDICTOR2); +} + +METHODDEF(void) +jpeg_difference3(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + DIFFERENCE_2D(PREDICTOR3); +} + +METHODDEF(void) +jpeg_difference4(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + DIFFERENCE_2D(PREDICTOR4); +} + +METHODDEF(void) +jpeg_difference5(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + DIFFERENCE_2D(PREDICTOR5); +} + +METHODDEF(void) +jpeg_difference6(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + DIFFERENCE_2D(PREDICTOR6); +} + +METHODDEF(void) +jpeg_difference7(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + DIFFERENCE_2D(PREDICTOR7); +} + + +/* + * Differencer for the first row in a scan or restart interval. The first + * sample in the row is differenced using the special predictor constant + * x=2^(P-Pt-1). The rest of the samples are differenced using the + * 1-D horizontal predictor (1). + */ + +METHODDEF(void) +jpeg_difference_first_row(j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width) +{ + DIFFERENCE_1D(INITIAL_PREDICTORx); + + /* + * Now that we have differenced the first row, we want to use the + * differencer which corresponds to the predictor specified in the + * scan header. + * + * Note that we don't to do this if we have just reset the predictor + * for a new restart interval. + */ + if (!restart) { + switch (cinfo->Ss) { + case 1: + losslsc->predict_difference[ci] = jpeg_difference1; + break; + case 2: + losslsc->predict_difference[ci] = jpeg_difference2; + break; + case 3: + losslsc->predict_difference[ci] = jpeg_difference3; + break; + case 4: + losslsc->predict_difference[ci] = jpeg_difference4; + break; + case 5: + losslsc->predict_difference[ci] = jpeg_difference5; + break; + case 6: + losslsc->predict_difference[ci] = jpeg_difference6; + break; + case 7: + losslsc->predict_difference[ci] = jpeg_difference7; + break; + } + } +} + +/* + * Reset predictor at the start of a pass or restart interval. + */ + +LOCAL(void) +reset_predictor (j_compress_ptr cinfo, int ci) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; + + /* Initialize restart counter */ + pred->restart_rows_to_go[ci] = + cinfo->restart_interval / cinfo->MCUs_per_row; + + /* Set difference function to first row function */ + losslsc->predict_difference[ci] = jpeg_difference_first_row; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_pass (j_compress_ptr cinfo) +{ + /* j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; */ + /* c_pred_ptr pred = (c_pred_ptr) losslsc->pred_private; */ + int ci; + + /* Check that the restart interval is an integer multiple of the number + * of MCU in an MCU-row. + */ + if (cinfo->restart_interval % cinfo->MCUs_per_row != 0) + ERREXIT2(cinfo, JERR_BAD_RESTART, + cinfo->restart_interval, cinfo->MCUs_per_row); + + /* Set predictors for start of pass */ + for (ci = 0; ci < cinfo->num_components; ci++) + reset_predictor(cinfo, ci); +} + + +/* + * Module initialization routine for the differencer. + */ + +GLOBAL(void) +jinit_differencer (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + c_pred_ptr pred; + + pred = (c_pred_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(c_predictor)); + losslsc->pred_private = (void *) pred; + losslsc->predict_start_pass = start_pass; +} + +#endif /* C_LOSSLESS_SUPPORTED */ + diff --git a/src/jpeg/libijg/jcprepct.c b/src/jpeg/libijg/jcprepct.c index fa93333d..18854819 100644 --- a/src/jpeg/libijg/jcprepct.c +++ b/src/jpeg/libijg/jcprepct.c @@ -1,7 +1,7 @@ /* * jcprepct.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -58,12 +58,12 @@ typedef struct { */ JSAMPARRAY color_buf[MAX_COMPONENTS]; - JDIMENSION rows_to_go; /* counts rows remaining in source image */ - int next_buf_row; /* index of next row to store in color_buf */ + JDIMENSION rows_to_go; /* counts rows remaining in source image */ + int next_buf_row; /* index of next row to store in color_buf */ -#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ - int this_row_group; /* starting row index of group to process */ - int next_buf_stop; /* downsample when we reach this index */ +#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */ + int this_row_group; /* starting row index of group to process */ + int next_buf_stop; /* downsample when we reach this index */ #endif } my_prep_controller; @@ -104,13 +104,13 @@ start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode) LOCAL(void) expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, - int input_rows, int output_rows) + int input_rows, int output_rows) { register int row; for (row = input_rows; row < output_rows; row++) { jcopy_sample_rows(image_data, input_rows-1, image_data, row, - 1, num_cols); + 1, num_cols); } } @@ -126,10 +126,10 @@ expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols, METHODDEF(void) pre_process_data (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail) + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; int numrows, ci; @@ -137,32 +137,32 @@ pre_process_data (j_compress_ptr cinfo, jpeg_component_info * compptr; while (*in_row_ctr < in_rows_avail && - *out_row_group_ctr < out_row_groups_avail) { + *out_row_group_ctr < out_row_groups_avail) { /* Do color conversion to fill the conversion buffer. */ inrows = in_rows_avail - *in_row_ctr; numrows = cinfo->max_v_samp_factor - prep->next_buf_row; numrows = (int) MIN((JDIMENSION) numrows, inrows); (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, - prep->color_buf, - (JDIMENSION) prep->next_buf_row, - numrows); + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); *in_row_ctr += numrows; prep->next_buf_row += numrows; prep->rows_to_go -= numrows; /* If at bottom of image, pad to fill the conversion buffer. */ if (prep->rows_to_go == 0 && - prep->next_buf_row < cinfo->max_v_samp_factor) { + prep->next_buf_row < cinfo->max_v_samp_factor) { for (ci = 0; ci < cinfo->num_components; ci++) { - expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, - prep->next_buf_row, cinfo->max_v_samp_factor); + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, cinfo->max_v_samp_factor); } prep->next_buf_row = cinfo->max_v_samp_factor; } /* If we've filled the conversion buffer, empty it. */ if (prep->next_buf_row == cinfo->max_v_samp_factor) { (*cinfo->downsample->downsample) (cinfo, - prep->color_buf, (JDIMENSION) 0, - output_buf, *out_row_group_ctr); + prep->color_buf, (JDIMENSION) 0, + output_buf, *out_row_group_ctr); prep->next_buf_row = 0; (*out_row_group_ctr)++; } @@ -170,16 +170,16 @@ pre_process_data (j_compress_ptr cinfo, * Note we assume the caller is providing a one-iMCU-height output buffer! */ if (prep->rows_to_go == 0 && - *out_row_group_ctr < out_row_groups_avail) { + *out_row_group_ctr < out_row_groups_avail) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - expand_bottom_edge(output_buf[ci], - compptr->width_in_blocks * DCTSIZE, - (int) (*out_row_group_ctr * compptr->v_samp_factor), - (int) (out_row_groups_avail * compptr->v_samp_factor)); + ci++, compptr++) { + expand_bottom_edge(output_buf[ci], + compptr->width_in_data_units * cinfo->data_unit, + (int) (*out_row_group_ctr * compptr->v_samp_factor), + (int) (out_row_groups_avail * compptr->v_samp_factor)); } *out_row_group_ctr = out_row_groups_avail; - break; /* can exit outer loop without test */ + break; /* can exit outer loop without test */ } } } @@ -193,10 +193,10 @@ pre_process_data (j_compress_ptr cinfo, METHODDEF(void) pre_process_context (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail) + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail) { my_prep_ptr prep = (my_prep_ptr) cinfo->prep; int numrows, ci; @@ -210,19 +210,19 @@ pre_process_context (j_compress_ptr cinfo, numrows = prep->next_buf_stop - prep->next_buf_row; numrows = (int) MIN((JDIMENSION) numrows, inrows); (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr, - prep->color_buf, - (JDIMENSION) prep->next_buf_row, - numrows); + prep->color_buf, + (JDIMENSION) prep->next_buf_row, + numrows); /* Pad at top of image, if first time through */ if (prep->rows_to_go == cinfo->image_height) { - for (ci = 0; ci < cinfo->num_components; ci++) { - int row; - for (row = 1; row <= cinfo->max_v_samp_factor; row++) { - jcopy_sample_rows(prep->color_buf[ci], 0, - prep->color_buf[ci], -row, - 1, cinfo->image_width); - } - } + for (ci = 0; ci < cinfo->num_components; ci++) { + int row; + for (row = 1; row <= cinfo->max_v_samp_factor; row++) { + jcopy_sample_rows(prep->color_buf[ci], 0, + prep->color_buf[ci], -row, + 1, cinfo->image_width); + } + } } *in_row_ctr += numrows; prep->next_buf_row += numrows; @@ -230,29 +230,29 @@ pre_process_context (j_compress_ptr cinfo, } else { /* Return for more data, unless we are at the bottom of the image. */ if (prep->rows_to_go != 0) - break; + break; /* When at bottom of image, pad to fill the conversion buffer. */ if (prep->next_buf_row < prep->next_buf_stop) { - for (ci = 0; ci < cinfo->num_components; ci++) { - expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, - prep->next_buf_row, prep->next_buf_stop); - } - prep->next_buf_row = prep->next_buf_stop; + for (ci = 0; ci < cinfo->num_components; ci++) { + expand_bottom_edge(prep->color_buf[ci], cinfo->image_width, + prep->next_buf_row, prep->next_buf_stop); + } + prep->next_buf_row = prep->next_buf_stop; } } /* If we've gotten enough data, downsample a row group. */ if (prep->next_buf_row == prep->next_buf_stop) { (*cinfo->downsample->downsample) (cinfo, - prep->color_buf, - (JDIMENSION) prep->this_row_group, - output_buf, *out_row_group_ctr); + prep->color_buf, + (JDIMENSION) prep->this_row_group, + output_buf, *out_row_group_ctr); (*out_row_group_ctr)++; /* Advance pointers with wraparound as necessary. */ prep->this_row_group += cinfo->max_v_samp_factor; if (prep->this_row_group >= buf_height) - prep->this_row_group = 0; + prep->this_row_group = 0; if (prep->next_buf_row >= buf_height) - prep->next_buf_row = 0; + prep->next_buf_row = 0; prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor; } } @@ -277,8 +277,8 @@ create_context_buffer (j_compress_ptr cinfo) */ fake_buffer = (JSAMPARRAY) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (cinfo->num_components * 5 * rgroup_height) * - SIZEOF(JSAMPROW)); + (cinfo->num_components * 5 * rgroup_height) * + SIZEOF(JSAMPROW)); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { @@ -288,12 +288,12 @@ create_context_buffer (j_compress_ptr cinfo) */ true_buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * - cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) (((long) compptr->width_in_data_units * cinfo->data_unit * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), (JDIMENSION) (3 * rgroup_height)); /* Copy true buffer row pointers into the middle of the fake row array */ MEMCOPY(fake_buffer + rgroup_height, true_buffer, - 3 * rgroup_height * SIZEOF(JSAMPROW)); + 3 * rgroup_height * SIZEOF(JSAMPROW)); /* Fill in the above and below wraparound pointers */ for (i = 0; i < rgroup_height; i++) { fake_buffer[i] = true_buffer[2 * rgroup_height + i]; @@ -318,12 +318,12 @@ jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) int ci; jpeg_component_info * compptr; - if (need_full_buffer) /* safety check */ + if (need_full_buffer) /* safety check */ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); prep = (my_prep_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_prep_controller)); + SIZEOF(my_prep_controller)); cinfo->prep = (struct jpeg_c_prep_controller *) prep; prep->pub.start_pass = start_pass_prep; @@ -343,12 +343,12 @@ jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer) /* No context, just make it tall enough for one row group */ prep->pub.pre_process_data = pre_process_data; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { + ci++, compptr++) { prep->color_buf[ci] = (*cinfo->mem->alloc_sarray) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE * - cinfo->max_h_samp_factor) / compptr->h_samp_factor), - (JDIMENSION) cinfo->max_v_samp_factor); + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) (((long) compptr->width_in_data_units * cinfo->data_unit * + cinfo->max_h_samp_factor) / compptr->h_samp_factor), + (JDIMENSION) cinfo->max_v_samp_factor); } } } diff --git a/src/jpeg/libijg/jcsample.c b/src/jpeg/libijg/jcsample.c index 1e82aa7b..50657b12 100644 --- a/src/jpeg/libijg/jcsample.c +++ b/src/jpeg/libijg/jcsample.c @@ -1,7 +1,7 @@ /* * jcsample.c * - * Copyright (C) 1991-1996, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -74,7 +74,6 @@ typedef my_downsampler * my_downsample_ptr; METHODDEF(void) start_pass_downsample (j_compress_ptr cinfo) { - cinfo = 0; /* no work for now */ } @@ -143,7 +142,7 @@ int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, { int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v; JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */ - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JDIMENSION output_cols = compptr->width_in_data_units * cinfo->data_unit; JSAMPROW inptr, outptr; INT32 outvalue; @@ -193,7 +192,7 @@ fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, cinfo->max_v_samp_factor, cinfo->image_width); /* Edge-expand */ expand_right_edge(output_data, cinfo->max_v_samp_factor, - cinfo->image_width, compptr->width_in_blocks * DCTSIZE); + cinfo->image_width, compptr->width_in_data_units * cinfo->data_unit); } @@ -215,7 +214,7 @@ h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, { int outrow; JDIMENSION outcol; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JDIMENSION output_cols = compptr->width_in_data_units * cinfo->data_unit; register JSAMPROW inptr, outptr; register int bias; @@ -252,7 +251,7 @@ h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, { int inrow, outrow; JDIMENSION outcol; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JDIMENSION output_cols = compptr->width_in_data_units * cinfo->data_unit; register JSAMPROW inptr0, inptr1, outptr; register int bias; @@ -295,7 +294,7 @@ h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr, { int inrow, outrow; JDIMENSION colctr; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JDIMENSION output_cols = compptr->width_in_data_units * cinfo->data_unit; register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr; INT32 membersum, neighsum, memberscale, neighscale; @@ -395,7 +394,7 @@ fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr, { int outrow; JDIMENSION colctr; - JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE; + JDIMENSION output_cols = compptr->width_in_data_units * cinfo->data_unit; register JSAMPROW inptr, above_ptr, below_ptr, outptr; INT32 membersum, neighsum, memberscale, neighscale; int colsum, lastcolsum, nextcolsum; diff --git a/src/jpeg/libijg/jcscale.c b/src/jpeg/libijg/jcscale.c new file mode 100644 index 00000000..16570373 --- /dev/null +++ b/src/jpeg/libijg/jcscale.c @@ -0,0 +1,63 @@ +/* + * jcscale.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains sample downscaling by 2^Pt for lossless JPEG. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ + + +#ifdef C_LOSSLESS_SUPPORTED + +METHODDEF(void) +simple_downscale(j_compress_ptr cinfo, + JSAMPROW input_buf, JSAMPROW output_buf, JDIMENSION width) +{ + /* j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; */ + unsigned int xindex; + SHIFT_TEMPS + + for (xindex = 0; xindex < width; xindex++) + output_buf[xindex] = (JSAMPLE) RIGHT_SHIFT(GETJSAMPLE(input_buf[xindex]), + cinfo->Al); +} + + +METHODDEF(void) +noscale(j_compress_ptr cinfo, + JSAMPROW input_buf, JSAMPROW output_buf, JDIMENSION width) +{ + MEMCOPY(output_buf, input_buf, width * SIZEOF(JSAMPLE)); + return; +} + + +METHODDEF(void) +scaler_start_pass (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + + /* Set scaler function based on Pt */ + if (cinfo->Al) + losslsc->scaler_scale = simple_downscale; + else + losslsc->scaler_scale = noscale; +} + + +GLOBAL(void) +jinit_c_scaler (j_compress_ptr cinfo) +{ + j_lossless_c_ptr losslsc = (j_lossless_c_ptr) cinfo->codec; + + losslsc->scaler_start_pass = scaler_start_pass; +} + +#endif /* C_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jcshuff.c b/src/jpeg/libijg/jcshuff.c new file mode 100644 index 00000000..91698f80 --- /dev/null +++ b/src/jpeg/libijg/jcshuff.c @@ -0,0 +1,661 @@ +/* + * jcshuff.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy encoding routines for sequential JPEG. + * + * Much of the complexity here has to do with supporting output suspension. + * If the data destination module demands suspension, we want to be able to + * back up to the start of the current MCU. To do this, we copy state + * variables into local working storage, and update them back to the + * permanent JPEG objects only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossy.h" /* Private declarations for lossy codec */ +#include "jchuff.h" /* Declarations shared with jc*huff.c */ + + +/* Expanded entropy encoder object for Huffman encoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + INT32 put_buffer; /* current bit-accumulation buffer */ + int put_bits; /* # of bits now in it */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).put_buffer = (src).put_buffer, \ + (dest).put_bits = (src).put_bits, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + savable_state saved; /* Bit buffer & DC state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + int next_restart_num; /* next restart number to write (0-7) */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + +#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */ + long * dc_count_ptrs[NUM_HUFF_TBLS]; + long * ac_count_ptrs[NUM_HUFF_TBLS]; +#endif +} shuff_entropy_encoder; + +typedef shuff_entropy_encoder * shuff_entropy_ptr; + +/* Working state while writing an MCU. + * This struct contains all the fields that are needed by subroutines. + */ + +typedef struct { + JOCTET * next_output_byte; /* => next byte to write in buffer */ + size_t free_in_buffer; /* # of byte spaces remaining in buffer */ + savable_state cur; /* Current bit buffer & DC state */ + j_compress_ptr cinfo; /* dump_buffer needs access to this */ +} working_state; + + +/* Forward declarations */ +METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo)); +#ifdef ENTROPY_OPT_SUPPORTED +METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); +METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo)); +#endif + + +/* + * Initialize for a Huffman-compressed scan. + * If gather_statistics is TRUE, we do not output anything during the scan, + * just count the Huffman symbols used and generate Huffman code tables. + */ + +METHODDEF(void) +start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyc->entropy_private; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + lossyc->entropy_encode_mcu = encode_mcu_gather; + lossyc->pub.entropy_finish_pass = finish_pass_gather; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + lossyc->entropy_encode_mcu = encode_mcu_huff; + lossyc->pub.entropy_finish_pass = finish_pass_huff; + } + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (gather_statistics) { +#ifdef ENTROPY_OPT_SUPPORTED + /* Check for invalid table indexes */ + /* (make_c_derived_tbl does this in the other path) */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + if (actbl < 0 || actbl >= NUM_HUFF_TBLS) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl); + /* Allocate and zero the statistics tables */ + /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */ + if (entropy->dc_count_ptrs[dctbl] == NULL) + entropy->dc_count_ptrs[dctbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long)); + if (entropy->ac_count_ptrs[actbl] == NULL) + entropy->ac_count_ptrs[actbl] = (long *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + 257 * SIZEOF(long)); + MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long)); +#endif + } else { + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_c_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + } + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Initialize bit buffer to empty */ + entropy->saved.put_buffer = 0; + entropy->saved.put_bits = 0; + + /* Initialize restart stuff */ + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num = 0; +} + + +/* Outputting bytes to the file */ + +/* Emit a byte, taking 'action' if must suspend. */ +#define emit_byte(state,val,action) \ + { *(state)->next_output_byte++ = (JOCTET) (val); \ + if (--(state)->free_in_buffer == 0) \ + if (! dump_buffer(state)) \ + { action; } } + + +LOCAL(boolean) +dump_buffer (working_state * state) +/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */ +{ + struct jpeg_destination_mgr * dest = state->cinfo->dest; + + if (! (*dest->empty_output_buffer) (state->cinfo)) + return FALSE; + /* After a successful buffer dump, must reset buffer pointers */ + state->next_output_byte = dest->next_output_byte; + state->free_in_buffer = dest->free_in_buffer; + return TRUE; +} + + +/* Outputting bits to the file */ + +/* Only the right 24 bits of put_buffer are used; the valid bits are + * left-justified in this part. At most 16 bits can be passed to emit_bits + * in one call, and we never retain more than 7 bits in put_buffer + * between calls, so 24 bits are sufficient. + */ + +INLINE +LOCAL(boolean) +emit_bits (working_state * state, unsigned int code, int size) +/* Emit some bits; return TRUE if successful, FALSE if must suspend */ +{ + /* This routine is heavily used, so it's worth coding tightly. */ + register INT32 put_buffer = (INT32) code; + register int put_bits = state->cur.put_bits; + + /* if size is 0, caller used an invalid Huffman table entry */ + if (size == 0) + ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE); + + put_buffer &= (((INT32) 1)<cur.put_buffer; /* and merge with old buffer contents */ + + while (put_bits >= 8) { + int c = (int) ((put_buffer >> 16) & 0xFF); + + emit_byte(state, c, return FALSE); + if (c == 0xFF) { /* need to stuff a zero byte? */ + emit_byte(state, 0, return FALSE); + } + put_buffer <<= 8; + put_bits -= 8; + } + + state->cur.put_buffer = put_buffer; /* update state variables */ + state->cur.put_bits = put_bits; + + return TRUE; +} + + +LOCAL(boolean) +flush_bits (working_state * state) +{ + if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */ + return FALSE; + state->cur.put_buffer = 0; /* and reset bit-buffer to empty */ + state->cur.put_bits = 0; + return TRUE; +} + + +/* Encode a single block's worth of coefficients */ + +LOCAL(boolean) +encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val, + c_derived_tbl *dctbl, c_derived_tbl *actbl) +{ + register int temp, temp2; + register int nbits; + register int k, r, i; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = temp2 = block[0] - last_dc_val; + + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* For a negative input, want temp2 = bitwise complement of abs(input) */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit the Huffman-coded symbol for the number of bits */ + if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (nbits) /* emit_bits rejects calls with size 0 */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0])) + return FALSE; + r -= 16; + } + + temp2 = temp; + if (temp < 0) { + temp = -temp; /* temp is abs value of input */ + /* This code assumes we are on a two's complement machine */ + temp2--; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(state->cinfo, JERR_BAD_DCT_COEF); + + /* Emit Huffman symbol for run length / number of bits */ + i = (r << 4) + nbits; + if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i])) + return FALSE; + + /* Emit that number of bits of the value, if positive, */ + /* or the complement of its magnitude, if negative. */ + if (! emit_bits(state, (unsigned int) temp2, nbits)) + return FALSE; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0])) + return FALSE; + + return TRUE; +} + + +/* + * Emit a restart marker & resynchronize predictions. + */ + +LOCAL(boolean) +emit_restart (working_state * state, int restart_num) +{ + int ci; + + if (! flush_bits(state)) + return FALSE; + + emit_byte(state, 0xFF, return FALSE); + emit_byte(state, JPEG_RST0 + restart_num, return FALSE); + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < state->cinfo->comps_in_scan; ci++) + state->cur.last_dc_val[ci] = 0; + + /* The restart counter is not updated until we successfully write the MCU. */ + + return TRUE; +} + + +/* + * Encode and output one MCU's worth of Huffman-compressed coefficients. + */ + +METHODDEF(boolean) +encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyc->entropy_private; + working_state state; + int blkn, ci; + jpeg_component_info * compptr; + + /* Load up working state */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Emit restart marker if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! emit_restart(&state, entropy->next_restart_num)) + return FALSE; + } + + /* Encode the MCU data blocks */ + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + if (! encode_one_block(&state, + MCU_data[blkn][0], state.cur.last_dc_val[ci], + entropy->dc_derived_tbls[compptr->dc_tbl_no], + entropy->ac_derived_tbls[compptr->ac_tbl_no])) + return FALSE; + /* Update last_dc_val */ + state.cur.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + /* Completed MCU, so update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); + + /* Update restart-interval state too */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + entropy->restarts_to_go = cinfo->restart_interval; + entropy->next_restart_num++; + entropy->next_restart_num &= 7; + } + entropy->restarts_to_go--; + } + + return TRUE; +} + + +/* + * Finish up at the end of a Huffman-compressed scan. + */ + +METHODDEF(void) +finish_pass_huff (j_compress_ptr cinfo) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyc->entropy_private; + working_state state; + + /* Load up working state ... flush_bits needs it */ + state.next_output_byte = cinfo->dest->next_output_byte; + state.free_in_buffer = cinfo->dest->free_in_buffer; + ASSIGN_STATE(state.cur, entropy->saved); + state.cinfo = cinfo; + + /* Flush out the last data */ + if (! flush_bits(&state)) + ERREXIT(cinfo, JERR_CANT_SUSPEND); + + /* Update state */ + cinfo->dest->next_output_byte = state.next_output_byte; + cinfo->dest->free_in_buffer = state.free_in_buffer; + ASSIGN_STATE(entropy->saved, state.cur); +} + + +/* + * Huffman coding optimization. + * + * We first scan the supplied data and count the number of uses of each symbol + * that is to be Huffman-coded. (This process MUST agree with the code above.) + * Then we build a Huffman coding tree for the observed counts. + * Symbols which are not needed at all for the particular image are not + * assigned any code, which saves space in the DHT marker as well as in + * the compressed data. + */ + +#ifdef ENTROPY_OPT_SUPPORTED + + +/* Process a single block's worth of coefficients */ + +LOCAL(void) +htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val, + long dc_counts[], long ac_counts[]) +{ + register int temp; + register int nbits; + register int k, r; + + /* Encode the DC coefficient difference per section F.1.2.1 */ + + temp = block[0] - last_dc_val; + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 0; + while (temp) { + nbits++; + temp >>= 1; + } + /* Check for out-of-range coefficient values. + * Since we're encoding a difference, the range limit is twice as much. + */ + if (nbits > MAX_COEF_BITS+1) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count the Huffman symbol for the number of bits */ + dc_counts[nbits]++; + + /* Encode the AC coefficients per section F.1.2.2 */ + + r = 0; /* r = run length of zeros */ + + for (k = 1; k < DCTSIZE2; k++) { + if ((temp = block[jpeg_natural_order[k]]) == 0) { + r++; + } else { + /* if run length > 15, must emit special run-length-16 codes (0xF0) */ + while (r > 15) { + ac_counts[0xF0]++; + r -= 16; + } + + /* Find the number of bits needed for the magnitude of the coefficient */ + if (temp < 0) + temp = -temp; + + /* Find the number of bits needed for the magnitude of the coefficient */ + nbits = 1; /* there must be at least one 1 bit */ + while ((temp >>= 1)) + nbits++; + /* Check for out-of-range coefficient values */ + if (nbits > MAX_COEF_BITS) + ERREXIT(cinfo, JERR_BAD_DCT_COEF); + + /* Count Huffman symbol for run length / number of bits */ + ac_counts[(r << 4) + nbits]++; + + r = 0; + } + } + + /* If the last coef(s) were zero, emit an end-of-block code */ + if (r > 0) + ac_counts[0]++; +} + + +/* + * Trial-encode one MCU's worth of Huffman-compressed coefficients. + * No data is actually output, so no suspension return is possible. + */ + +METHODDEF(boolean) +encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyc->entropy_private; + int blkn, ci; + jpeg_component_info * compptr; + + /* Take care of restart intervals if needed */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) { + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + /* Update restart state */ + entropy->restarts_to_go = cinfo->restart_interval; + } + entropy->restarts_to_go--; + } + + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci], + entropy->dc_count_ptrs[compptr->dc_tbl_no], + entropy->ac_count_ptrs[compptr->ac_tbl_no]); + entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0]; + } + + return TRUE; +} + + +/* + * Finish up a statistics-gathering pass and create the new Huffman tables. + */ + +METHODDEF(void) +finish_pass_gather (j_compress_ptr cinfo) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyc->entropy_private; + int ci, dctbl, actbl; + jpeg_component_info * compptr; + JHUFF_TBL **htblptr; + boolean did_dc[NUM_HUFF_TBLS]; + boolean did_ac[NUM_HUFF_TBLS]; + + /* It's important not to apply jpeg_gen_optimal_table more than once + * per table, because it clobbers the input frequency counts! + */ + MEMZERO(did_dc, SIZEOF(did_dc)); + MEMZERO(did_ac, SIZEOF(did_ac)); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + if (! did_dc[dctbl]) { + htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]); + did_dc[dctbl] = TRUE; + } + if (! did_ac[actbl]) { + htblptr = & cinfo->ac_huff_tbl_ptrs[actbl]; + if (*htblptr == NULL) + *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo); + jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]); + did_ac[actbl] = TRUE; + } + } +} + + +#endif /* ENTROPY_OPT_SUPPORTED */ + + +METHODDEF(boolean) +need_optimization_pass (j_compress_ptr cinfo) +{ + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy encoding. + */ + +GLOBAL(void) +jinit_shuff_encoder (j_compress_ptr cinfo) +{ + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + shuff_entropy_ptr entropy; + int i; + + entropy = (shuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(shuff_entropy_encoder)); + lossyc->entropy_private = (struct jpeg_entropy_encoder *) entropy; + lossyc->pub.entropy_start_pass = start_pass_huff; + lossyc->pub.need_optimization_pass = need_optimization_pass; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; +#ifdef ENTROPY_OPT_SUPPORTED + entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL; +#endif + } +} diff --git a/src/jpeg/libijg/jctrans.c b/src/jpeg/libijg/jctrans.c index b84f1d84..e5302d5d 100644 --- a/src/jpeg/libijg/jctrans.c +++ b/src/jpeg/libijg/jctrans.c @@ -13,11 +13,14 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" +#include "jlossy.h" /* Private declarations for lossy codec */ /* Forward declarations */ LOCAL(void) transencode_master_selection JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); +LOCAL(void) transencode_codec + JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); LOCAL(void) transencode_coef_controller JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); @@ -158,6 +161,7 @@ LOCAL(void) transencode_master_selection (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { + cinfo->data_unit = DCTSIZE; /* Although we don't actually use input_components for transcoding, * jcmaster.c's initial_setup will complain if input_components is 0. */ @@ -165,22 +169,8 @@ transencode_master_selection (j_compress_ptr cinfo, /* Initialize master control (includes parameter checking/processing) */ jinit_c_master_control(cinfo, TRUE /* transcode only */); - /* Entropy encoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef C_PROGRESSIVE_SUPPORTED - jinit_phuff_encoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_encoder(cinfo); - } - - /* We need a special coefficient buffer controller. */ - transencode_coef_controller(cinfo, coef_arrays); + /* We need a special compression codec. */ + transencode_codec(cinfo, coef_arrays); jinit_marker_writer(cinfo); @@ -206,8 +196,6 @@ transencode_master_selection (j_compress_ptr cinfo, /* Private buffer controller object */ typedef struct { - struct jpeg_c_coef_controller pub; /* public fields */ - JDIMENSION iMCU_row_num; /* iMCU row # within image */ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ int MCU_vert_offset; /* counts MCU rows within iMCU row */ @@ -217,17 +205,18 @@ typedef struct { jvirt_barray_ptr * whole_image; /* Workspace for constructing dummy blocks at right/bottom edges. */ - JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; -} my_coef_controller; + JBLOCKROW dummy_buffer[C_MAX_DATA_UNITS_IN_MCU]; +} c_coef_controller; -typedef my_coef_controller * my_coef_ptr; +typedef c_coef_controller * c_coef_ptr; LOCAL(void) start_iMCU_row (j_compress_ptr cinfo) /* Reset within-iMCU-row counters for a new row */ { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; /* In an interleaved scan, an MCU row is the same as an iMCU row. * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. @@ -254,7 +243,8 @@ start_iMCU_row (j_compress_ptr cinfo) METHODDEF(void) start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; if (pass_mode != JBUF_CRANK_DEST) ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); @@ -277,19 +267,18 @@ start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) METHODDEF(boolean) compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef = (c_coef_ptr) lossyc->coef_private; JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; int blkn, ci, xindex, yindex, yoffset, blockcnt; JDIMENSION start_col; JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; - JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; + JBLOCKROW MCU_buffer[C_MAX_DATA_UNITS_IN_MCU]; JBLOCKROW buffer_ptr; jpeg_component_info *compptr; - input_buf = 0; - /* Align the virtual buffers for the components used in this scan. */ for (ci = 0; ci < cinfo->comps_in_scan; ci++) { compptr = cinfo->cur_comp_info[ci]; @@ -336,7 +325,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) } } /* Try to write the MCU. */ - if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { + if (! (*lossyc->entropy_encode_mcu) (cinfo, MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; coef->mcu_ctr = MCU_col_num; @@ -357,7 +346,7 @@ compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) * Initialize coefficient buffer controller. * * Each passed coefficient array must be the right size for that - * coefficient: width_in_blocks wide and height_in_blocks high, + * coefficient: width_in_data_units wide and height_in_data_units high, * with unitheight at least v_samp_factor. */ @@ -365,16 +354,15 @@ LOCAL(void) transencode_coef_controller (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) { - my_coef_ptr coef; + j_lossy_c_ptr lossyc = (j_lossy_c_ptr) cinfo->codec; + c_coef_ptr coef; JBLOCKROW buffer; int i; - coef = (my_coef_ptr) + coef = (c_coef_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_c_coef_controller *) coef; - coef->pub.start_pass = start_pass_coef; - coef->pub.compress_data = compress_output; + SIZEOF(c_coef_controller)); + lossyc->coef_private = (struct jpeg_c_coef_controller *) coef; /* Save pointer to virtual arrays */ coef->whole_image = coef_arrays; @@ -382,9 +370,51 @@ transencode_coef_controller (j_compress_ptr cinfo, /* Allocate and pre-zero space for dummy DCT blocks. */ buffer = (JBLOCKROW) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { + C_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK)); + jzero_far((void FAR *) buffer, C_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < C_MAX_DATA_UNITS_IN_MCU; i++) { coef->dummy_buffer[i] = buffer + i; } } + + +/* + * Initialize the transencoer codec. + * This is called only once, during master selection. + */ + +LOCAL(void) +transencode_codec (j_compress_ptr cinfo, + jvirt_barray_ptr * coef_arrays) +{ + j_lossy_c_ptr lossyc; + + /* Create subobject in permanent pool */ + lossyc = (j_lossy_c_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(jpeg_lossy_c_codec)); + cinfo->codec = (struct jpeg_c_codec *) lossyc; + + /* Initialize sub-modules */ + + /* Entropy encoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + jinit_arith_encoder(cinfo); + } else { + if (cinfo->process == JPROC_PROGRESSIVE) { +#ifdef C_PROGRESSIVE_SUPPORTED + jinit_phuff_encoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_shuff_encoder(cinfo); + } + + /* We need a special coefficient buffer controller. */ + transencode_coef_controller(cinfo, coef_arrays); + + /* Initialize method pointers */ + lossyc->pub.start_pass = start_pass_coef; + lossyc->pub.compress_data = compress_output; +} diff --git a/src/jpeg/libijg/jdapimin.c b/src/jpeg/libijg/jdapimin.c index cadb59fc..d13a1540 100644 --- a/src/jpeg/libijg/jdapimin.c +++ b/src/jpeg/libijg/jdapimin.c @@ -32,12 +32,12 @@ jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize) int i; /* Guard against version mismatches between library and caller. */ - cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ + cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */ if (version != JPEG_LIB_VERSION) ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version); if (structsize != SIZEOF(struct jpeg_decompress_struct)) ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE, - (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); + (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize); /* For debugging purposes, we zero the whole master structure. * But the application has already set the err pointer, and may have set @@ -128,15 +128,15 @@ default_decompress_parms (j_decompress_ptr cinfo) } else if (cinfo->saw_Adobe_marker) { switch (cinfo->Adobe_transform) { case 0: - cinfo->jpeg_color_space = JCS_RGB; - break; + cinfo->jpeg_color_space = JCS_RGB; + break; case 1: - cinfo->jpeg_color_space = JCS_YCbCr; - break; + cinfo->jpeg_color_space = JCS_YCbCr; + break; default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ - break; + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + break; } } else { /* Saw no special markers, try to guess from the component IDs */ @@ -145,12 +145,18 @@ default_decompress_parms (j_decompress_ptr cinfo) int cid2 = cinfo->comp_info[2].component_id; if (cid0 == 1 && cid1 == 2 && cid2 == 3) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ else if (cid0 == 82 && cid1 == 71 && cid2 == 66) - cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ + cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ else { - TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); - cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + if (cinfo->process == JPROC_LOSSLESS) { + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_LOSSLESS_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_RGB; /* assume it's RGB */ + } + else { /* Lossy processes */ + TRACEMS3(cinfo, 1, JTRC_UNKNOWN_LOSSY_IDS, cid0, cid1, cid2); + cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */ + } } } /* Always guess RGB is proper output colorspace. */ @@ -161,15 +167,15 @@ default_decompress_parms (j_decompress_ptr cinfo) if (cinfo->saw_Adobe_marker) { switch (cinfo->Adobe_transform) { case 0: - cinfo->jpeg_color_space = JCS_CMYK; - break; + cinfo->jpeg_color_space = JCS_CMYK; + break; case 2: - cinfo->jpeg_color_space = JCS_YCCK; - break; + cinfo->jpeg_color_space = JCS_YCCK; + break; default: - WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); - cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ - break; + WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform); + cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */ + break; } } else { /* No special markers, assume straight CMYK. */ @@ -185,7 +191,7 @@ default_decompress_parms (j_decompress_ptr cinfo) } /* Set defaults for other decompression parameters. */ - cinfo->scale_num = 1; /* 1:1 scaling */ + cinfo->scale_num = 1; /* 1:1 scaling */ cinfo->scale_denom = 1; cinfo->output_gamma = 1.0; cinfo->buffered_image = FALSE; @@ -253,7 +259,7 @@ jpeg_read_header (j_decompress_ptr cinfo, boolean require_image) retcode = JPEG_HEADER_OK; break; case JPEG_REACHED_EOI: - if (require_image) /* Complain if application wanted an image */ + if (require_image) /* Complain if application wanted an image */ ERREXIT(cinfo, JERR_NO_IMAGE); /* Reset to start state; it would be safer to require the application to * call jpeg_abort, but we can't change it now for compatibility reasons. @@ -385,7 +391,7 @@ jpeg_finish_decompress (j_decompress_ptr cinfo) /* Read until EOI */ while (! cinfo->inputctl->eoi_reached) { if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ + return FALSE; /* Suspend, come back later */ } /* Do final cleanup */ (*cinfo->src->term_source) (cinfo); diff --git a/src/jpeg/libijg/jdapistd.c b/src/jpeg/libijg/jdapistd.c index c8e3fa0c..4cc36d71 100644 --- a/src/jpeg/libijg/jdapistd.c +++ b/src/jpeg/libijg/jdapistd.c @@ -1,7 +1,7 @@ /* * jdapistd.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -52,24 +52,24 @@ jpeg_start_decompress (j_decompress_ptr cinfo) if (cinfo->inputctl->has_multiple_scans) { #ifdef D_MULTISCAN_FILES_SUPPORTED for (;;) { - int retcode; - /* Call progress monitor hook if present */ - if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); - /* Absorb some more input */ - retcode = (*cinfo->inputctl->consume_input) (cinfo); - if (retcode == JPEG_SUSPENDED) - return FALSE; - if (retcode == JPEG_REACHED_EOI) - break; - /* Advance progress counter if appropriate */ - if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* jdmaster underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; - } - } + int retcode; + /* Call progress monitor hook if present */ + if (cinfo->progress != NULL) + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + /* Absorb some more input */ + retcode = (*cinfo->inputctl->consume_input) (cinfo); + if (retcode == JPEG_SUSPENDED) + return FALSE; + if (retcode == JPEG_REACHED_EOI) + break; + /* Advance progress counter if appropriate */ + if (cinfo->progress != NULL && + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* jdmaster underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } + } } #else ERREXIT(cinfo, JERR_NOT_COMPILED); @@ -108,16 +108,16 @@ output_pass_setup (j_decompress_ptr cinfo) JDIMENSION last_scanline; /* Call progress monitor hook if present */ if (cinfo->progress != NULL) { - cinfo->progress->pass_counter = (long) cinfo->output_scanline; - cinfo->progress->pass_limit = (long) cinfo->output_height; - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + cinfo->progress->pass_counter = (long) cinfo->output_scanline; + cinfo->progress->pass_limit = (long) cinfo->output_height; + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); } /* Process some data */ last_scanline = cinfo->output_scanline; (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL, - &cinfo->output_scanline, (JDIMENSION) 0); + &cinfo->output_scanline, (JDIMENSION) 0); if (cinfo->output_scanline == last_scanline) - return FALSE; /* No progress made, must suspend */ + return FALSE; /* No progress made, must suspend */ } /* Finish up dummy pass, and set up for another one */ (*cinfo->master->finish_output_pass) (cinfo); @@ -150,7 +150,7 @@ output_pass_setup (j_decompress_ptr cinfo) GLOBAL(JDIMENSION) jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, - JDIMENSION max_lines) + JDIMENSION max_lines) { JDIMENSION row_ctr; @@ -183,7 +183,7 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, GLOBAL(JDIMENSION) jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, - JDIMENSION max_lines) + JDIMENSION max_lines) { JDIMENSION lines_per_iMCU_row; @@ -202,13 +202,13 @@ jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data, } /* Verify that at least one iMCU row can be returned. */ - lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size; + lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_codec_data_unit; if (max_lines < lines_per_iMCU_row) ERREXIT(cinfo, JERR_BUFFER_SIZE); /* Decompress directly into user's buffer. */ - if (! (*cinfo->coef->decompress_data) (cinfo, data)) - return 0; /* suspension forced, can do nothing more */ + if (! (*cinfo->codec->decompress_data) (cinfo, data)) + return 0; /* suspension forced, can do nothing more */ /* OK, we processed one iMCU row. */ cinfo->output_scanline += lines_per_iMCU_row; @@ -264,9 +264,9 @@ jpeg_finish_output (j_decompress_ptr cinfo) } /* Read markers looking for SOS or EOI */ while (cinfo->input_scan_number <= cinfo->output_scan_number && - ! cinfo->inputctl->eoi_reached) { + ! cinfo->inputctl->eoi_reached) { if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED) - return FALSE; /* Suspend, come back later */ + return FALSE; /* Suspend, come back later */ } cinfo->global_state = DSTATE_BUFIMAGE; return TRUE; diff --git a/src/jpeg/libijg/jdarith.c b/src/jpeg/libijg/jdarith.c new file mode 100644 index 00000000..52eb79d7 --- /dev/null +++ b/src/jpeg/libijg/jdarith.c @@ -0,0 +1,24 @@ +/* + * jdarith.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file holds place for arithmetic entropy decoding routines. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" + + +/* + * Module initialization routine for arithmetic entropy decoding. + */ + +GLOBAL(void) +jinit_arith_decoder (j_decompress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_ARITH_NOTIMPL); +} diff --git a/src/jpeg/libijg/jdatadst.c b/src/jpeg/libijg/jdatadst.c index a8f6fb0e..88d859d2 100644 --- a/src/jpeg/libijg/jdatadst.c +++ b/src/jpeg/libijg/jdatadst.c @@ -25,13 +25,13 @@ typedef struct { struct jpeg_destination_mgr pub; /* public fields */ - FILE * outfile; /* target stream */ - JOCTET * buffer; /* start of buffer */ + FILE * outfile; /* target stream */ + JOCTET * buffer; /* start of buffer */ } my_destination_mgr; typedef my_destination_mgr * my_dest_ptr; -#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ +#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */ /* @@ -47,7 +47,7 @@ init_destination (j_compress_ptr cinfo) /* Allocate the output buffer --- it will be released when done with image */ dest->buffer = (JOCTET *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); + OUTPUT_BUF_SIZE * SIZEOF(JOCTET)); dest->pub.next_output_byte = dest->buffer; dest->pub.free_in_buffer = OUTPUT_BUF_SIZE; @@ -137,10 +137,10 @@ jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile) * manager serially with the same JPEG object, because their private object * sizes may be different. Caveat programmer. */ - if (cinfo->dest == NULL) { /* first time for this JPEG object? */ + if (cinfo->dest == NULL) { /* first time for this JPEG object? */ cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_destination_mgr)); + SIZEOF(my_destination_mgr)); } dest = (my_dest_ptr) cinfo->dest; diff --git a/src/jpeg/libijg/jdatasrc.c b/src/jpeg/libijg/jdatasrc.c index f6711d9e..8c539b09 100644 --- a/src/jpeg/libijg/jdatasrc.c +++ b/src/jpeg/libijg/jdatasrc.c @@ -168,7 +168,6 @@ skip_input_data (j_decompress_ptr cinfo, long num_bytes) METHODDEF(void) term_source (j_decompress_ptr cinfo) { - cinfo=cinfo; /* no work necessary here */ } diff --git a/src/jpeg/libijg/jdcoefct.c b/src/jpeg/libijg/jdcoefct.c index 0016bdda..49e03f8f 100644 --- a/src/jpeg/libijg/jdcoefct.c +++ b/src/jpeg/libijg/jdcoefct.c @@ -1,12 +1,12 @@ /* * jdcoefct.c * - * Copyright (C) 1994-1997, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains the coefficient buffer controller for decompression. - * This controller is the top level of the JPEG decompressor proper. + * This controller is the top level of the lossy JPEG decompressor proper. * The coefficient buffer lies between entropy decoding and inverse-DCT steps. * * In buffered-image mode, this controller is the interface between @@ -17,6 +17,7 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" +#include "jlossy.h" /* Block smoothing is only applicable for progressive JPEG, so: */ #ifndef D_PROGRESSIVE_SUPPORTED @@ -26,8 +27,6 @@ /* Private buffer controller object */ typedef struct { - struct jpeg_d_coef_controller pub; /* public fields */ - /* These variables keep track of the current location of the input side. */ /* cinfo->input_iMCU_row is also used for this. */ JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ @@ -37,7 +36,7 @@ typedef struct { /* The output side's location is represented by cinfo->output_iMCU_row. */ /* In single-pass modes, it's sufficient to buffer just one MCU. - * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks, + * We allocate a workspace of D_MAX_DATA_UNITS_IN_MCU coefficient blocks, * and let the entropy decoder write into that workspace each time. * (On 80x86, the workspace is FAR even though it's not really very big; * this is to keep the module interfaces unchanged when a large coefficient @@ -45,7 +44,7 @@ typedef struct { * In multi-pass modes, this array points to the current MCU's blocks * within the virtual arrays; it is used only by the input side. */ - JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU]; + JBLOCKROW MCU_buffer[D_MAX_DATA_UNITS_IN_MCU]; #ifdef D_MULTISCAN_FILES_SUPPORTED /* In multi-pass modes, we need a virtual block array for each component. */ @@ -57,9 +56,9 @@ typedef struct { int * coef_bits_latch; #define SAVED_COEFS 6 /* we save coef_bits[0..5] */ #endif -} my_coef_controller; +} d_coef_controller; -typedef my_coef_controller * my_coef_ptr; +typedef d_coef_controller * d_coef_ptr; /* Forward declarations */ METHODDEF(int) decompress_onepass @@ -79,7 +78,8 @@ LOCAL(void) start_iMCU_row (j_decompress_ptr cinfo) /* Reset within-iMCU-row counters for a new row (input side) */ { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; /* In an interleaved scan, an MCU row is the same as an iMCU row. * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. @@ -119,14 +119,15 @@ METHODDEF(void) start_output_pass (j_decompress_ptr cinfo) { #ifdef BLOCK_SMOOTHING_SUPPORTED - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + /* d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; */ /* If multipass, check to see whether to use block smoothing on this pass */ - if (coef->pub.coef_arrays != NULL) { + if (lossyd->coef_arrays != NULL) { if (cinfo->do_block_smoothing && smoothing_ok(cinfo)) - coef->pub.decompress_data = decompress_smooth_data; + lossyd->pub.decompress_data = decompress_smooth_data; else - coef->pub.decompress_data = decompress_data; + lossyd->pub.decompress_data = decompress_data; } #endif cinfo->output_iMCU_row = 0; @@ -146,7 +147,8 @@ start_output_pass (j_decompress_ptr cinfo) METHODDEF(int) decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; JDIMENSION MCU_col_num; /* index of current MCU within row */ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; @@ -163,8 +165,8 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) MCU_col_num++) { /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */ jzero_far((void FAR *) coef->MCU_buffer[0], - (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK))); - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + (size_t) (cinfo->data_units_in_MCU * SIZEOF(JBLOCK))); + if (! (*lossyd->entropy_decode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; coef->MCU_ctr = MCU_col_num; @@ -180,14 +182,14 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) compptr = cinfo->cur_comp_info[ci]; /* Don't bother to IDCT an uninteresting component. */ if (! compptr->component_needed) { - blkn += compptr->MCU_blocks; + blkn += compptr->MCU_data_units; continue; } - inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index]; + inverse_DCT = lossyd->inverse_DCT[compptr->component_index]; useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width : compptr->last_col_width; output_ptr = output_buf[compptr->component_index] + - yoffset * compptr->DCT_scaled_size; + yoffset * compptr->codec_data_unit; start_col = MCU_col_num * compptr->MCU_sample_width; for (yindex = 0; yindex < compptr->MCU_height; yindex++) { if (cinfo->input_iMCU_row < last_iMCU_row || @@ -197,11 +199,11 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) coef->MCU_buffer[blkn+xindex], output_ptr, output_col); - output_col += compptr->DCT_scaled_size; + output_col += compptr->codec_data_unit; } } blkn += compptr->MCU_width; - output_ptr += compptr->DCT_scaled_size; + output_ptr += compptr->codec_data_unit; } } } @@ -227,7 +229,6 @@ decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) METHODDEF(int) dummy_consume_data (j_decompress_ptr cinfo) { - cinfo = 0; return JPEG_SUSPENDED; /* Always indicate nothing was done */ } @@ -244,7 +245,8 @@ dummy_consume_data (j_decompress_ptr cinfo) METHODDEF(int) consume_data (j_decompress_ptr cinfo) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; JDIMENSION MCU_col_num; /* index of current MCU within row */ int blkn, ci, xindex, yindex, yoffset; JDIMENSION start_col; @@ -283,7 +285,7 @@ consume_data (j_decompress_ptr cinfo) } } /* Try to fetch the MCU. */ - if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) { + if (! (*lossyd->entropy_decode_mcu) (cinfo, coef->MCU_buffer)) { /* Suspension forced; update state counters and exit */ coef->MCU_vert_offset = yoffset; coef->MCU_ctr = MCU_col_num; @@ -315,7 +317,8 @@ consume_data (j_decompress_ptr cinfo) METHODDEF(int) decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION block_num; int ci, block_row, block_rows; @@ -350,22 +353,22 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) block_rows = compptr->v_samp_factor; else { /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + block_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); if (block_rows == 0) block_rows = compptr->v_samp_factor; } - inverse_DCT = cinfo->idct->inverse_DCT[ci]; + inverse_DCT = lossyd->inverse_DCT[ci]; output_ptr = output_buf[ci]; /* Loop over all DCT blocks to be processed. */ for (block_row = 0; block_row < block_rows; block_row++) { buffer_ptr = buffer[block_row]; output_col = 0; - for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) { + for (block_num = 0; block_num < compptr->width_in_data_units; block_num++) { (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr, output_ptr, output_col); buffer_ptr++; - output_col += compptr->DCT_scaled_size; + output_col += compptr->codec_data_unit; } - output_ptr += compptr->DCT_scaled_size; + output_ptr += compptr->codec_data_unit; } } @@ -405,7 +408,8 @@ decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) LOCAL(boolean) smoothing_ok (j_decompress_ptr cinfo) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; boolean smoothing_useful = FALSE; int ci, coefi; jpeg_component_info *compptr; @@ -413,7 +417,7 @@ smoothing_ok (j_decompress_ptr cinfo) int * coef_bits; int * coef_bits_latch; - if (! cinfo->progressive_mode || cinfo->coef_bits == NULL) + if (! cinfo->process == JPROC_PROGRESSIVE || cinfo->coef_bits == NULL) return FALSE; /* Allocate latch area if not already done */ @@ -461,7 +465,8 @@ smoothing_ok (j_decompress_ptr cinfo) METHODDEF(int) decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) { - my_coef_ptr coef = (my_coef_ptr) cinfo->coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef = (d_coef_ptr) lossyd->coef_private; JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; JDIMENSION block_num, last_block_column; int ci, block_row, block_rows, access_rows; @@ -509,7 +514,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) last_row = FALSE; } else { /* NB: can't use last_row_height here; it is input-side-dependent! */ - block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + block_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); if (block_rows == 0) block_rows = compptr->v_samp_factor; access_rows = block_rows; /* this iMCU row only */ last_row = TRUE; @@ -538,7 +543,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) Q20 = quanttbl->quantval[Q20_POS]; Q11 = quanttbl->quantval[Q11_POS]; Q02 = quanttbl->quantval[Q02_POS]; - inverse_DCT = cinfo->idct->inverse_DCT[ci]; + inverse_DCT = lossyd->inverse_DCT[ci]; output_ptr = output_buf[ci]; /* Loop over all DCT blocks to be processed. */ for (block_row = 0; block_row < block_rows; block_row++) { @@ -558,7 +563,7 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) DC4 = DC5 = DC6 = (int) buffer_ptr[0][0]; DC7 = DC8 = DC9 = (int) next_block_row[0][0]; output_col = 0; - last_block_column = compptr->width_in_blocks - 1; + last_block_column = compptr->width_in_data_units - 1; for (block_num = 0; block_num <= last_block_column; block_num++) { /* Fetch current DCT block into workspace so we can modify it. */ jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1); @@ -655,9 +660,9 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) DC4 = DC5; DC5 = DC6; DC7 = DC8; DC8 = DC9; buffer_ptr++, prev_block_row++, next_block_row++; - output_col += compptr->DCT_scaled_size; + output_col += compptr->codec_data_unit; } - output_ptr += compptr->DCT_scaled_size; + output_ptr += compptr->codec_data_unit; } } @@ -676,14 +681,15 @@ decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) GLOBAL(void) jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { - my_coef_ptr coef; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + d_coef_ptr coef; - coef = (my_coef_ptr) + coef = (d_coef_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_coef_controller)); - cinfo->coef = (struct jpeg_d_coef_controller *) coef; - coef->pub.start_input_pass = start_input_pass; - coef->pub.start_output_pass = start_output_pass; + SIZEOF(d_coef_controller)); + lossyd->coef_private = (void *) coef; + lossyd->coef_start_input_pass = start_input_pass; + lossyd->coef_start_output_pass = start_output_pass; #ifdef BLOCK_SMOOTHING_SUPPORTED coef->coef_bits_latch = NULL; #endif @@ -702,20 +708,20 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) access_rows = compptr->v_samp_factor; #ifdef BLOCK_SMOOTHING_SUPPORTED /* If block smoothing could be used, need a bigger window */ - if (cinfo->progressive_mode) + if (cinfo->process == JPROC_PROGRESSIVE) access_rows *= 3; #endif coef->whole_image[ci] = (*cinfo->mem->request_virt_barray) ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE, - (JDIMENSION) jround_up((long) compptr->width_in_blocks, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, (long) compptr->h_samp_factor), - (JDIMENSION) jround_up((long) compptr->height_in_blocks, + (JDIMENSION) jround_up((long) compptr->height_in_data_units, (long) compptr->v_samp_factor), (JDIMENSION) access_rows); } - coef->pub.consume_data = consume_data; - coef->pub.decompress_data = decompress_data; - coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */ + lossyd->pub.consume_data = consume_data; + lossyd->pub.decompress_data = decompress_data; + lossyd->coef_arrays = coef->whole_image; /* link to virtual arrays */ #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif @@ -726,12 +732,12 @@ jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer) buffer = (JBLOCKROW) (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); - for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) { + D_MAX_DATA_UNITS_IN_MCU * SIZEOF(JBLOCK)); + for (i = 0; i < D_MAX_DATA_UNITS_IN_MCU; i++) { coef->MCU_buffer[i] = buffer + i; } - coef->pub.consume_data = dummy_consume_data; - coef->pub.decompress_data = decompress_onepass; - coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */ + lossyd->pub.consume_data = dummy_consume_data; + lossyd->pub.decompress_data = decompress_onepass; + lossyd->coef_arrays = NULL; /* flag for no virtual arrays */ } } diff --git a/src/jpeg/libijg/jdcolor.c b/src/jpeg/libijg/jdcolor.c index cb9333ae..f23777d9 100644 --- a/src/jpeg/libijg/jdcolor.c +++ b/src/jpeg/libijg/jdcolor.c @@ -72,7 +72,11 @@ build_ycc_rgb_table (j_decompress_ptr cinfo) my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert; int i; INT32 x; +#if BITS_IN_JSAMPLE == 16 + /* no need for temporaries */ +#else SHIFT_TEMPS +#endif cconvert->Cr_r_tab = (int *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, @@ -90,12 +94,25 @@ build_ycc_rgb_table (j_decompress_ptr cinfo) for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) { /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ + +#if BITS_IN_JSAMPLE == 16 + /* Bug fix 2001-11-06 by Eichelberg: The integer routines below + produce an overflow when used with MAXJSAMPLE == 65535. + Use floating point calculation instead. */ + + /* Cr=>R value is nearest int to 1.40200 * x */ + cconvert->Cr_r_tab[i] = (int)(1.40200 * (double)x + 0.5); + /* Cb=>B value is nearest int to 1.77200 * x */ + cconvert->Cb_b_tab[i] = (int)(1.77200 * (double)x + 0.5); +#else /* Cr=>R value is nearest int to 1.40200 * x */ cconvert->Cr_r_tab[i] = (int) RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS); /* Cb=>B value is nearest int to 1.77200 * x */ cconvert->Cb_b_tab[i] = (int) RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS); +#endif + /* Cr=>G value is scaled-up -0.71414 * x */ cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x; /* Cb=>G value is scaled-up -0.34414 * x */ @@ -292,7 +309,6 @@ ycck_cmyk_convert (j_decompress_ptr cinfo, METHODDEF(void) start_pass_dcolor (j_decompress_ptr cinfo) { - cinfo = 0; /* no work needed */ } diff --git a/src/jpeg/libijg/jdct.h b/src/jpeg/libijg/jdct.h index 04192a26..ffdd5e50 100644 --- a/src/jpeg/libijg/jdct.h +++ b/src/jpeg/libijg/jdct.h @@ -27,9 +27,9 @@ */ #if BITS_IN_JSAMPLE == 8 -typedef int DCTELEM; /* 16 or 32 bits is fine */ +typedef int DCTELEM; /* 16 or 32 bits is fine */ #else -typedef INT32 DCTELEM; /* must have 32 bits */ +typedef INT32 DCTELEM; /* must have 32 bits */ #endif typedef JMETHOD(void, forward_DCT_method_ptr, (DCTELEM * data)); @@ -56,10 +56,10 @@ typedef JMETHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data)); typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */ #if BITS_IN_JSAMPLE == 8 typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */ -#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ +#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */ #else -typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ -#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ +typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */ +#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */ #endif typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ @@ -81,15 +81,15 @@ typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */ /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_fdct_islow jFDislow -#define jpeg_fdct_ifast jFDifast -#define jpeg_fdct_float jFDfloat -#define jpeg_idct_islow jRDislow -#define jpeg_idct_ifast jRDifast -#define jpeg_idct_float jRDfloat -#define jpeg_idct_4x4 jRD4x4 -#define jpeg_idct_2x2 jRD2x2 -#define jpeg_idct_1x1 jRD1x1 +#define jpeg_fdct_islow jFDislow +#define jpeg_fdct_ifast jFDifast +#define jpeg_fdct_float jFDfloat +#define jpeg_idct_islow jRDislow +#define jpeg_idct_ifast jRDifast +#define jpeg_idct_float jRDfloat +#define jpeg_idct_4x4 jRD4x4 +#define jpeg_idct_2x2 jRD2x2 +#define jpeg_idct_1x1 jRD1x1 #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Extern declarations for the forward and inverse DCT routines. */ @@ -100,22 +100,22 @@ EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data)); EXTERN(void) jpeg_idct_islow JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); EXTERN(void) jpeg_idct_ifast JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); EXTERN(void) jpeg_idct_float JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); EXTERN(void) jpeg_idct_4x4 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); EXTERN(void) jpeg_idct_2x2 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); EXTERN(void) jpeg_idct_1x1 JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); + JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col)); /* @@ -128,7 +128,7 @@ EXTERN(void) jpeg_idct_1x1 * and may differ from one module to the next. */ -#define ONE ((INT32) 1) +#define ONE ((INT32) 1) #define CONST_SCALE (ONE << CONST_BITS) /* Convert a positive real constant to an integer scaled by CONST_SCALE. @@ -136,7 +136,7 @@ EXTERN(void) jpeg_idct_1x1 * thus causing a lot of useless floating-point operations at run time. */ -#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) +#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5)) /* Descale and correctly round an INT32 value that's scaled by N bits. * We assume RIGHT_SHIFT rounds towards minus infinity, so adding @@ -154,23 +154,23 @@ EXTERN(void) jpeg_idct_1x1 * correct combination of casts. */ -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ #define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const))) #endif -#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ +#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */ #define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const))) #endif -#ifndef MULTIPLY16C16 /* default definition */ +#ifndef MULTIPLY16C16 /* default definition */ #define MULTIPLY16C16(var,const) ((var) * (const)) #endif /* Same except both inputs are variables. */ -#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ +#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */ #define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2))) #endif -#ifndef MULTIPLY16V16 /* default definition */ +#ifndef MULTIPLY16V16 /* default definition */ #define MULTIPLY16V16(var1,var2) ((var1) * (var2)) #endif diff --git a/src/jpeg/libijg/jddctmgr.c b/src/jpeg/libijg/jddctmgr.c index bbf8d0e9..6f6c4442 100644 --- a/src/jpeg/libijg/jddctmgr.c +++ b/src/jpeg/libijg/jddctmgr.c @@ -1,7 +1,7 @@ /* * jddctmgr.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -18,7 +18,8 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jdct.h" /* Private declarations for DCT subsystem */ +#include "jlossy.h" /* Private declarations for lossy subsystem */ +#include "jdct.h" /* Private declarations for DCT subsystem */ /* @@ -41,17 +42,15 @@ /* Private subobject for this module */ typedef struct { - struct jpeg_inverse_dct pub; /* public fields */ - /* This array contains the IDCT method code that each multiplier table * is currently set up for, or -1 if it's not yet set up. * The actual multiplier tables are pointed to by dct_table in the * per-component comp_info structures. */ int cur_method[MAX_COMPONENTS]; -} my_idct_controller; +} idct_controller; -typedef my_idct_controller * my_idct_ptr; +typedef idct_controller * idct_ptr; /* Allocated multiplier tables: big enough for any supported variant */ @@ -88,7 +87,8 @@ typedef union { METHODDEF(void) start_pass (j_decompress_ptr cinfo) { - my_idct_ptr idct = (my_idct_ptr) cinfo->idct; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + idct_ptr idct = (idct_ptr) lossyd->idct_private; int ci, i; jpeg_component_info *compptr; int method = 0; @@ -98,51 +98,51 @@ start_pass (j_decompress_ptr cinfo) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { /* Select the proper IDCT routine for this component's scaling */ - switch (compptr->DCT_scaled_size) { + switch (compptr->codec_data_unit) { #ifdef IDCT_SCALING_SUPPORTED case 1: method_ptr = jpeg_idct_1x1; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ + method = JDCT_ISLOW; /* jidctred uses islow-style table */ break; case 2: method_ptr = jpeg_idct_2x2; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ + method = JDCT_ISLOW; /* jidctred uses islow-style table */ break; case 4: method_ptr = jpeg_idct_4x4; - method = JDCT_ISLOW; /* jidctred uses islow-style table */ + method = JDCT_ISLOW; /* jidctred uses islow-style table */ break; #endif case DCTSIZE: switch (cinfo->dct_method) { #ifdef DCT_ISLOW_SUPPORTED case JDCT_ISLOW: - method_ptr = jpeg_idct_islow; - method = JDCT_ISLOW; - break; + method_ptr = jpeg_idct_islow; + method = JDCT_ISLOW; + break; #endif #ifdef DCT_IFAST_SUPPORTED case JDCT_IFAST: - method_ptr = jpeg_idct_ifast; - method = JDCT_IFAST; - break; + method_ptr = jpeg_idct_ifast; + method = JDCT_IFAST; + break; #endif #ifdef DCT_FLOAT_SUPPORTED case JDCT_FLOAT: - method_ptr = jpeg_idct_float; - method = JDCT_FLOAT; - break; + method_ptr = jpeg_idct_float; + method = JDCT_FLOAT; + break; #endif default: - ERREXIT(cinfo, JERR_NOT_COMPILED); - break; + ERREXIT(cinfo, JERR_NOT_COMPILED); + break; } break; default: - ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size); + ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->codec_data_unit); break; } - idct->pub.inverse_DCT[ci] = method_ptr; + lossyd->inverse_DCT[ci] = method_ptr; /* Create multiplier table from quant table. * However, we can skip this if the component is uninteresting * or if we already built the table. Also, if no quant table @@ -153,81 +153,81 @@ start_pass (j_decompress_ptr cinfo) if (! compptr->component_needed || idct->cur_method[ci] == method) continue; qtbl = compptr->quant_table; - if (qtbl == NULL) /* happens if no data yet for component */ + if (qtbl == NULL) /* happens if no data yet for component */ continue; idct->cur_method[ci] = method; switch (method) { #ifdef PROVIDE_ISLOW_TABLES case JDCT_ISLOW: { - /* For LL&M IDCT method, multipliers are equal to raw quantization - * coefficients, but are stored as ints to ensure access efficiency. - */ - ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; - for (i = 0; i < DCTSIZE2; i++) { - ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; - } + /* For LL&M IDCT method, multipliers are equal to raw quantization + * coefficients, but are stored as ints to ensure access efficiency. + */ + ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table; + for (i = 0; i < DCTSIZE2; i++) { + ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i]; + } } break; #endif #ifdef DCT_IFAST_SUPPORTED case JDCT_IFAST: { - /* For AA&N IDCT method, multipliers 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 - * For integer operation, the multiplier table is to be scaled by - * IFAST_SCALE_BITS. - */ - IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; + /* For AA&N IDCT method, multipliers 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 + * For integer operation, the multiplier table is to be scaled by + * IFAST_SCALE_BITS. + */ + IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table; #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 - for (i = 0; i < DCTSIZE2; i++) { - ifmtbl[i] = (IFAST_MULT_TYPE) - DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], - (INT32) aanscales[i]), - CONST_BITS-IFAST_SCALE_BITS); - } + for (i = 0; i < DCTSIZE2; i++) { + ifmtbl[i] = (IFAST_MULT_TYPE) + DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i], + (INT32) aanscales[i]), + CONST_BITS-IFAST_SCALE_BITS); + } } break; #endif #ifdef DCT_FLOAT_SUPPORTED case JDCT_FLOAT: { - /* For float AA&N IDCT method, multipliers 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 - */ - FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; - 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, multipliers 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 + */ + FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table; + int row, col; + static const double aanscalefactor[DCTSIZE] = { + 1.0, 1.387039845, 1.306562965, 1.175875602, + 1.0, 0.785694958, 0.541196100, 0.275899379 + }; - i = 0; - for (row = 0; row < DCTSIZE; row++) { - for (col = 0; col < DCTSIZE; col++) { - fmtbl[i] = (FLOAT_MULT_TYPE) - ((double) qtbl->quantval[i] * - aanscalefactor[row] * aanscalefactor[col]); - i++; - } - } + i = 0; + for (row = 0; row < DCTSIZE; row++) { + for (col = 0; col < DCTSIZE; col++) { + fmtbl[i] = (FLOAT_MULT_TYPE) + ((double) qtbl->quantval[i] * + aanscalefactor[row] * aanscalefactor[col]); + i++; + } + } } break; #endif @@ -246,22 +246,23 @@ start_pass (j_decompress_ptr cinfo) GLOBAL(void) jinit_inverse_dct (j_decompress_ptr cinfo) { - my_idct_ptr idct; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + idct_ptr idct; int ci; jpeg_component_info *compptr; - idct = (my_idct_ptr) + idct = (idct_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_idct_controller)); - cinfo->idct = (struct jpeg_inverse_dct *) idct; - idct->pub.start_pass = start_pass; + SIZEOF(idct_controller)); + lossyd->idct_private = (void *) idct; + lossyd->idct_start_pass = start_pass; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { /* Allocate and pre-zero a multiplier table for each component */ compptr->dct_table = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(multiplier_table)); + SIZEOF(multiplier_table)); MEMZERO(compptr->dct_table, SIZEOF(multiplier_table)); /* Mark multiplier table not yet set up for any method */ idct->cur_method[ci] = -1; diff --git a/src/jpeg/libijg/jddiffct.c b/src/jpeg/libijg/jddiffct.c new file mode 100644 index 00000000..42a7309c --- /dev/null +++ b/src/jpeg/libijg/jddiffct.c @@ -0,0 +1,399 @@ +/* + * jddiffct.c + * + * Copyright (C) 1994-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the [un]difference buffer controller for decompression. + * This controller is the top level of the lossless JPEG decompressor proper. + * The difference buffer lies between the entropy decoding and + * prediction/undifferencing steps. The undifference buffer lies between the + * prediction/undifferencing and scaling steps. + * + * In buffered-image mode, this controller is the interface between + * input-oriented processing and output-oriented processing. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" + + +#ifdef D_LOSSLESS_SUPPORTED + +/* Private buffer controller object */ + +typedef struct { + /* These variables keep track of the current location of the input side. */ + /* cinfo->input_iMCU_row is also used for this. */ + JDIMENSION MCU_ctr; /* counts MCUs processed in current row */ + unsigned int restart_rows_to_go; /* MCU-rows left in this restart interval */ + unsigned int MCU_vert_offset; /* counts MCU rows within iMCU row */ + unsigned int MCU_rows_per_iMCU_row; /* number of such rows needed */ + + /* The output side's location is represented by cinfo->output_iMCU_row. */ + + JDIFFARRAY diff_buf[MAX_COMPONENTS]; /* iMCU row of differences */ + JDIFFARRAY undiff_buf[MAX_COMPONENTS]; /* iMCU row of undiff'd samples */ + +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* In multi-pass modes, we need a virtual sample array for each component. */ + jvirt_sarray_ptr whole_image[MAX_COMPONENTS]; +#endif +} d_diff_controller; + +typedef d_diff_controller * d_diff_ptr; + +/* Forward declarations */ +METHODDEF(int) decompress_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#ifdef D_MULTISCAN_FILES_SUPPORTED +METHODDEF(int) output_data + JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf)); +#endif + + +LOCAL(void) +start_iMCU_row (j_decompress_ptr cinfo) +/* Reset within-iMCU-row counters for a new row (input side) */ +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + + /* In an interleaved scan, an MCU row is the same as an iMCU row. + * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. + * But at the bottom of the image, process only what's left. + */ + if (cinfo->comps_in_scan > 1) { + diff->MCU_rows_per_iMCU_row = 1; + } else { + if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1)) + diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; + else + diff->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; + } + + diff->MCU_ctr = 0; + diff->MCU_vert_offset = 0; +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + + /* Check that the restart interval is an integer multiple of the number + * of MCU in an MCU-row. + */ + if (cinfo->restart_interval % cinfo->MCUs_per_row != 0) + ERREXIT2(cinfo, JERR_BAD_RESTART, + cinfo->restart_interval, cinfo->MCUs_per_row); + + /* Initialize restart counter */ + diff->restart_rows_to_go = cinfo->restart_interval / cinfo->MCUs_per_row; + + cinfo->input_iMCU_row = 0; + start_iMCU_row(cinfo); +} + + +/* + * Check for a restart marker & resynchronize decoder, undifferencer. + * Returns FALSE if must suspend. + */ + +METHODDEF(boolean) +process_restart (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + + if (! (*losslsd->entropy_process_restart) (cinfo)) + return FALSE; + + (*losslsd->predict_process_restart) (cinfo); + + /* Reset restart counter */ + diff->restart_rows_to_go = cinfo->restart_interval / cinfo->MCUs_per_row; + + return TRUE; +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ + cinfo->output_iMCU_row = 0; +} + + +/* + * Decompress and return some data in the supplied buffer. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Input and output must run in lockstep since we have only a one-MCU buffer. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image, + * which we index according to the component's SOF position. + */ + +METHODDEF(int) +decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + JDIMENSION MCU_col_num; /* index of current MCU within row */ + JDIMENSION MCU_count; /* number of MCUs decoded */ + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int comp, ci, row, prev_row; + unsigned int yoffset; + jpeg_component_info *compptr; + + /* Loop to process as much as one whole iMCU row */ + for (yoffset = diff->MCU_vert_offset; yoffset < diff->MCU_rows_per_iMCU_row; + yoffset++) { + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (diff->restart_rows_to_go == 0) + if (! process_restart(cinfo)) + return JPEG_SUSPENDED; + } + + MCU_col_num = diff->MCU_ctr; + /* Try to fetch an MCU-row (or remaining portion of suspended MCU-row). */ + MCU_count = + (*losslsd->entropy_decode_mcus) (cinfo, + diff->diff_buf, yoffset, MCU_col_num, + cinfo->MCUs_per_row - MCU_col_num); + if (MCU_count != cinfo->MCUs_per_row - MCU_col_num) { + /* Suspension forced; update state counters and exit */ + diff->MCU_vert_offset = yoffset; + diff->MCU_ctr += MCU_count; + return JPEG_SUSPENDED; + } + + /* Account for restart interval (no-op if not using restarts) */ + diff->restart_rows_to_go--; + + /* Completed an MCU row, but perhaps not an iMCU row */ + diff->MCU_ctr = 0; + } + + /* + * Undifference and scale each scanline of the disassembled MCU-row + * separately. We do not process dummy samples at the end of a scanline + * or dummy rows at the end of the image. + */ + for (comp = 0; comp < cinfo->comps_in_scan; comp++) { + compptr = cinfo->cur_comp_info[comp]; + ci = compptr->component_index; + for (row = 0, prev_row = compptr->v_samp_factor - 1; + row < (cinfo->input_iMCU_row == last_iMCU_row ? + compptr->last_row_height : compptr->v_samp_factor); + prev_row = row, row++) { + (*losslsd->predict_undifference[ci]) (cinfo, ci, + diff->diff_buf[ci][row], + diff->undiff_buf[ci][prev_row], + diff->undiff_buf[ci][row], + compptr->width_in_data_units); + (*losslsd->scaler_scale) (cinfo, diff->undiff_buf[ci][row], + output_buf[ci][row], + compptr->width_in_data_units); + } + } + + /* Completed the iMCU row, advance counters for next one. + * + * NB: output_data will increment output_iMCU_row. + * This counter is not needed for the single-pass case + * or the input side of the multi-pass case. + */ + if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) { + start_iMCU_row(cinfo); + return JPEG_ROW_COMPLETED; + } + /* Completed the scan */ + (*cinfo->inputctl->finish_input_pass) (cinfo); + return JPEG_SCAN_COMPLETED; +} + + +/* + * Dummy consume-input routine for single-pass operation. + */ + +METHODDEF(int) +dummy_consume_data (j_decompress_ptr cinfo) +{ + return JPEG_SUSPENDED; /* Always indicate nothing was done */ +} + + +#ifdef D_MULTISCAN_FILES_SUPPORTED + +/* + * Consume input data and store it in the full-image sample buffer. + * We read as much as one fully interleaved MCU row ("iMCU" row) per call, + * ie, v_samp_factor rows for each component in the scan. + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + */ + +METHODDEF(int) +consume_data (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + /* JDIMENSION MCU_col_num; */ /* index of current MCU within row */ + /* JDIMENSION MCU_count; */ /* number of MCUs decoded */ + /* JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; */ + int comp, ci /* , yoffset, row, prev_row */; + JSAMPARRAY buffer[MAX_COMPS_IN_SCAN]; + jpeg_component_info *compptr; + + /* Align the virtual buffers for the components used in this scan. */ + for (comp = 0; comp < cinfo->comps_in_scan; comp++) { + compptr = cinfo->cur_comp_info[comp]; + ci = compptr->component_index; + buffer[ci] = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, diff->whole_image[ci], + cinfo->input_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, TRUE); + } + + return decompress_data(cinfo, buffer); +} + + +/* + * Output some data from the full-image buffer sample in the multi-pass case. + * Always attempts to emit one fully interleaved MCU row ("iMCU" row). + * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED. + * + * NB: output_buf contains a plane for each component in image. + */ + +METHODDEF(int) +output_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff = (d_diff_ptr) losslsd->diff_private; + JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; + int ci, samp_rows, row; + JSAMPARRAY buffer; + jpeg_component_info *compptr; + + /* Force some input to be done if we are getting ahead of the input. */ + while (cinfo->input_scan_number < cinfo->output_scan_number || + (cinfo->input_scan_number == cinfo->output_scan_number && + cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) { + if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED) + return JPEG_SUSPENDED; + } + + /* OK, output from the virtual arrays. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Align the virtual buffer for this component. */ + buffer = (*cinfo->mem->access_virt_sarray) + ((j_common_ptr) cinfo, diff->whole_image[ci], + cinfo->output_iMCU_row * compptr->v_samp_factor, + (JDIMENSION) compptr->v_samp_factor, FALSE); + + if (cinfo->output_iMCU_row < last_iMCU_row) + samp_rows = compptr->v_samp_factor; + else { + /* NB: can't use last_row_height here; it is input-side-dependent! */ + samp_rows = (int) (compptr->height_in_data_units % compptr->v_samp_factor); + if (samp_rows == 0) samp_rows = compptr->v_samp_factor; + } + + for (row = 0; row < samp_rows; row++) { + MEMCOPY(output_buf[ci][row], buffer[row], + compptr->width_in_data_units * SIZEOF(JSAMPLE)); + } + } + + if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows) + return JPEG_ROW_COMPLETED; + return JPEG_SCAN_COMPLETED; +} + +#endif /* D_MULTISCAN_FILES_SUPPORTED */ + + +/* + * Initialize difference buffer controller. + */ + +GLOBAL(void) +jinit_d_diff_controller (j_decompress_ptr cinfo, boolean need_full_buffer) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + d_diff_ptr diff; + int ci; + jpeg_component_info *compptr; + + diff = (d_diff_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(d_diff_controller)); + losslsd->diff_private = (void *) diff; + losslsd->diff_start_input_pass = start_input_pass; + losslsd->pub.start_output_pass = start_output_pass; + + /* Create the [un]difference buffers. */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + diff->diff_buf[ci] = (*cinfo->mem->alloc_darray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + diff->undiff_buf[ci] = (*cinfo->mem->alloc_darray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) compptr->v_samp_factor); + } + + if (need_full_buffer) { +#ifdef D_MULTISCAN_FILES_SUPPORTED + /* Allocate a full-image virtual array for each component. */ + int access_rows; + + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + access_rows = compptr->v_samp_factor; + diff->whole_image[ci] = (*cinfo->mem->request_virt_sarray) + ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE, + (JDIMENSION) jround_up((long) compptr->width_in_data_units, + (long) compptr->h_samp_factor), + (JDIMENSION) jround_up((long) compptr->height_in_data_units, + (long) compptr->v_samp_factor), + (JDIMENSION) access_rows); + } + losslsd->pub.consume_data = consume_data; + losslsd->pub.decompress_data = output_data; +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else { + losslsd->pub.consume_data = dummy_consume_data; + losslsd->pub.decompress_data = decompress_data; + diff->whole_image[0] = NULL; /* flag for no virtual arrays */ + } +} + +#endif /* D_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jdhuff.c b/src/jpeg/libijg/jdhuff.c index 4c9765fa..54a82724 100644 --- a/src/jpeg/libijg/jdhuff.c +++ b/src/jpeg/libijg/jdhuff.c @@ -1,148 +1,25 @@ /* * jdhuff.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * - * This file contains Huffman entropy decoding routines. - * - * Much of the complexity here has to do with supporting input suspension. - * If the data source module demands suspension, we want to be able to back - * up to the start of the current MCU. To do this, we copy state variables - * into local working storage, and update them back to the permanent - * storage only upon successful completion of an MCU. + * This file contains Huffman entropy decoding routines which are shared + * by the sequential, progressive and lossless decoders. */ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jdhuff.h" /* Declarations shared with jdphuff.c */ - - -/* - * Expanded entropy decoder object for Huffman decoding. - * - * The savable_state subrecord contains fields that change within an MCU, - * but must not be updated permanently until we complete the MCU. - */ - -typedef struct { - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ -} savable_state; - -/* This macro is to work around compilers with missing or broken - * structure assignment. You'll need to fix this code if you have - * such a compiler and you change MAX_COMPS_IN_SCAN. - */ - -#ifndef NO_STRUCT_ASSIGN -#define ASSIGN_STATE(dest,src) ((dest) = (src)) -#else -#if MAX_COMPS_IN_SCAN == 4 -#define ASSIGN_STATE(dest,src) \ - ((dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) -#endif -#endif - - -typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ - - /* These fields are loaded into local variables at start of each MCU. - * In case of suspension, we exit WITHOUT updating them. - */ - bitread_perm_state bitstate; /* Bit buffer at start of MCU */ - savable_state saved; /* Other state at start of MCU */ - - /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ - - /* Pointers to derived tables (these workspaces have image lifespan) */ - d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; - d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; - - /* Precalculated info set up by start_pass for use in decode_mcu: */ - - /* Pointers to derived tables to be used for each block within an MCU */ - d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU]; - d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU]; - /* Whether we care about the DC and AC coefficient values for each block */ - boolean dc_needed[D_MAX_BLOCKS_IN_MCU]; - boolean ac_needed[D_MAX_BLOCKS_IN_MCU]; -} huff_entropy_decoder; - -typedef huff_entropy_decoder * huff_entropy_ptr; - - -/* - * Initialize for a Huffman-compressed scan. - */ - -METHODDEF(void) -start_pass_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci, blkn, dctbl, actbl; - jpeg_component_info * compptr; - - /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. - * This ought to be an error condition, but we make it a warning because - * there are some baseline files out there with all zeroes in these bytes. - */ - if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || - cinfo->Ah != 0 || cinfo->Al != 0) - WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - dctbl = compptr->dc_tbl_no; - actbl = compptr->ac_tbl_no; - /* Compute derived values for Huffman tables */ - /* We may do this more than once for a table, but it's not expensive */ - jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, - & entropy->dc_derived_tbls[dctbl]); - jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, - & entropy->ac_derived_tbls[actbl]); - /* Initialize DC predictions to 0 */ - entropy->saved.last_dc_val[ci] = 0; - } - - /* Precalculate decoding info for each block in an MCU of this scan */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - ci = cinfo->MCU_membership[blkn]; - compptr = cinfo->cur_comp_info[ci]; - /* Precalculate which table to use for each block */ - entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; - entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; - /* Decide whether we really care about the coefficient values */ - if (compptr->component_needed) { - entropy->dc_needed[blkn] = TRUE; - /* we don't need the ACs if producing a 1/8th-size image */ - entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1); - } else { - entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; - } - } - - /* Initialize bitread state variables */ - entropy->bitstate.bits_left = 0; - entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->pub.insufficient_data = FALSE; - - /* Initialize restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; -} +#include "jlossy.h" /* Private declarations for lossy codec */ +#include "jlossls.h" /* Private declarations for lossless codec */ +#include "jdhuff.h" /* Declarations shared with jd*huff.c */ /* * Compute the derived values for a Huffman table. * This routine also performs some validation checks on the table. - * - * Note this is also used by jdphuff.c. */ GLOBAL(void) @@ -203,8 +80,9 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, } /* code is now 1 more than the last code used for codelength si; but * it must still fit in si bits, since no code is allowed to be all ones. + * BUG FIX 2001-09-03: Comparison must be >, not >= */ - if (((INT32) code) >= (((INT32) 1) << si)) + if (((INT32) code) > (((INT32) 1) << si)) ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); code <<= 1; si++; @@ -252,25 +130,27 @@ jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno, /* Validate symbols as being reasonable. * For AC tables, we make no check, but accept all byte values 0..255. - * For DC tables, we require the symbols to be in range 0..15. + * For DC tables, we require the symbols to be in range 0..16. * (Tighter bounds could be applied depending on the data depth and mode, * but this is sufficient to ensure safe decoding.) */ if (isDC) { for (i = 0; i < numsymbols; i++) { int sym = htbl->huffval[i]; - if (sym < 0 || sym > 15) { - // Now, we can read Philips MRI Images - htbl->huffval[i]=15; -// ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); - } + if (sym < 0 || sym > 16) +/* The following is needed to be able to read certain Philips DICOM MRI images */ +#if BITS_IN_JSAMPLE == 12 + htbl->huffval[i]=15; +#else + ERREXIT(cinfo, JERR_BAD_HUFF_TABLE); +#endif /* BITS_IN_JSAMPLE == 12 */ } } } /* - * Out-of-line code for bit fetching (shared with jdphuff.c). + * Out-of-line code for bit fetching. * See jdhuff.h for info about usage. * Note: current values of get_buffer and bits_left are passed as parameters, * but are returned in the corresponding fields of the state struct. @@ -372,9 +252,14 @@ jpeg_fill_bit_buffer (bitread_working_state * state, * We use a nonvolatile flag to ensure that only one warning message * appears per data segment. */ - if (! cinfo->entropy->insufficient_data) { + huffd_common_ptr huffd; + if (cinfo->process == JPROC_LOSSLESS) + huffd = (huffd_common_ptr) ((j_lossless_d_ptr) cinfo->codec)->entropy_private; + else + huffd = (huffd_common_ptr) ((j_lossy_d_ptr) cinfo->codec)->entropy_private; + if (! huffd->insufficient_data) { WARNMS(cinfo, JWRN_HIT_MARKER); - cinfo->entropy->insufficient_data = TRUE; + huffd->insufficient_data = TRUE; } /* Fill the buffer with zero bits */ get_buffer <<= MIN_GET_BITS - bits_left; @@ -434,221 +319,3 @@ jpeg_huff_decode (bitread_working_state * state, return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ]; } - - -/* - * Figure F.12: extend sign bit. - * On some machines, a shift and add will be faster than a table lookup. - */ - -#ifdef AVOID_TABLES - -#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) - -#else - -#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) - -static const int extend_test[16] = /* entry n is 2**(n-1) */ - { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, - 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; - -static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ - { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, - ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, - ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, - ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; - -#endif /* AVOID_TABLES */ - - -/* - * Check for a restart marker & resynchronize decoder. - * Returns FALSE if must suspend. - */ - -LOCAL(boolean) -process_restart (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int ci; - - /* Throw away any unused bits remaining in bit buffer; */ - /* include any full bytes in next_marker's count of discarded bytes */ - cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; - entropy->bitstate.bits_left = 0; - - /* Advance past the RSTn marker */ - if (! (*cinfo->marker->read_restart_marker) (cinfo)) - return FALSE; - - /* Re-initialize DC predictions to 0 */ - for (ci = 0; ci < cinfo->comps_in_scan; ci++) - entropy->saved.last_dc_val[ci] = 0; - - /* Reset restart counter */ - entropy->restarts_to_go = cinfo->restart_interval; - - /* Reset out-of-data flag, unless read_restart_marker left us smack up - * against a marker. In that case we will end up treating the next data - * segment as empty, and we can avoid producing bogus output pixels by - * leaving the flag set. - */ - if (cinfo->unread_marker == 0) - entropy->pub.insufficient_data = FALSE; - - return TRUE; -} - - -/* - * Decode and return one MCU's worth of Huffman-compressed coefficients. - * The coefficients are reordered from zigzag order into natural array order, - * but are not dequantized. - * - * The i'th block of the MCU is stored into the block pointed to by - * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. - * (Wholesale zeroing is usually a little faster than retail...) - * - * Returns FALSE if data source requested suspension. In that case no - * changes have been made to permanent state. (Exception: some output - * coefficients may already have been assigned. This is harmless for - * this module, since we'll just re-assign them on the next call.) - */ - -METHODDEF(boolean) -decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) -{ - huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy; - int blkn; - BITREAD_STATE_VARS; - savable_state state; - - /* Process restart marker if needed; may have to suspend */ - if (cinfo->restart_interval) { - if (entropy->restarts_to_go == 0) - if (! process_restart(cinfo)) - return FALSE; - } - - /* If we've run out of data, just leave the MCU set to zeroes. - * This way, we return uniform gray for the remainder of the segment. - */ - if (! entropy->pub.insufficient_data) { - - /* Load up working state */ - BITREAD_LOAD_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(state, entropy->saved); - - /* Outer loop handles each block in the MCU */ - - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { - JBLOCKROW block = MCU_data[blkn]; - d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; - d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; - register int s, k, r; - - /* Decode a single block's worth of coefficients */ - - /* Section F.2.2.1: decode the DC coefficient difference */ - HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); - if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - } - - if (entropy->dc_needed[blkn]) { - /* Convert DC difference to actual value, update last_dc_val */ - int ci = cinfo->MCU_membership[blkn]; - s += state.last_dc_val[ci]; - state.last_dc_val[ci] = s; - /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ - (*block)[0] = (JCOEF) s; - } - - if (entropy->ac_needed[blkn]) { - - /* Section F.2.2.2: decode the AC coefficients */ - /* Since zeroes are skipped, output area must be cleared beforehand */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label2); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Output coefficient in natural (dezigzagged) order. - * Note: the extra entries in jpeg_natural_order[] will save us - * if k >= DCTSIZE2, which could happen if the data is corrupted. - */ - (*block)[jpeg_natural_order[k]] = (JCOEF) s; - } else { - if (r != 15) - break; - k += 15; - } - } - - } else { - - /* Section F.2.2.2: decode the AC coefficients */ - /* In this path we just discard the values */ - for (k = 1; k < DCTSIZE2; k++) { - HUFF_DECODE(s, br_state, actbl, return FALSE, label3); - - r = s >> 4; - s &= 15; - - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - DROP_BITS(s); - } else { - if (r != 15) - break; - k += 15; - } - } - - } - } - - /* Completed MCU, so update state */ - BITREAD_SAVE_STATE(cinfo,entropy->bitstate); - ASSIGN_STATE(entropy->saved, state); - } - - /* Account for restart interval (no-op if not using restarts) */ - entropy->restarts_to_go--; - - return TRUE; -} - - -/* - * Module initialization routine for Huffman entropy decoding. - */ - -GLOBAL(void) -jinit_huff_decoder (j_decompress_ptr cinfo) -{ - huff_entropy_ptr entropy; - int i; - - entropy = (huff_entropy_ptr) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(huff_entropy_decoder)); - cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; - entropy->pub.start_pass = start_pass_huff_decoder; - entropy->pub.decode_mcu = decode_mcu; - - /* Mark tables unallocated */ - for (i = 0; i < NUM_HUFF_TBLS; i++) { - entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; - } -} diff --git a/src/jpeg/libijg/jdhuff.h b/src/jpeg/libijg/jdhuff.h index ae19b6ca..90746562 100644 --- a/src/jpeg/libijg/jdhuff.h +++ b/src/jpeg/libijg/jdhuff.h @@ -1,33 +1,34 @@ /* * jdhuff.h * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains declarations for Huffman entropy decoding routines - * that are shared between the sequential decoder (jdhuff.c) and the - * progressive decoder (jdphuff.c). No other modules need to see these. + * that are shared between the sequential decoder (jdhuff.c), the + * progressive decoder (jdphuff.c) and the lossless decoder (jdlhuff.c). + * No other modules need to see these. */ /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_make_d_derived_tbl jMkDDerived -#define jpeg_fill_bit_buffer jFilBitBuf -#define jpeg_huff_decode jHufDecode +#define jpeg_make_d_derived_tbl jMkDDerived +#define jpeg_fill_bit_buffer jFilBitBuf +#define jpeg_huff_decode jHufDecode #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Derived data constructed for each Huffman table */ -#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ +#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */ typedef struct { /* Basic tables: (element [0] of each array is unused) */ - INT32 maxcode[18]; /* largest code of length k (-1 if none) */ + INT32 maxcode[18]; /* largest code of length k (-1 if none) */ /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */ - INT32 valoffset[17]; /* huffval[] offset for codes of length k */ + INT32 valoffset[17]; /* huffval[] offset for codes of length k */ /* valoffset[k] = huffval[] index of 1st symbol of code length k, less * the smallest code of length k; so given a code of length k, the * corresponding symbol is huffval[code + valoffset[k]] @@ -47,8 +48,8 @@ typedef struct { /* Expand a Huffman table definition into the derived format */ EXTERN(void) jpeg_make_d_derived_tbl - JPP((j_decompress_ptr cinfo, boolean isDC, int tblno, - d_derived_tbl ** pdtbl)); + JPP((j_decompress_ptr cinfo, boolean isDC, int tblno, + d_derived_tbl ** pdtbl)); /* @@ -69,8 +70,8 @@ EXTERN(void) jpeg_make_d_derived_tbl * necessary. */ -typedef INT32 bit_buf_type; /* type of bit-extraction buffer */ -#define BIT_BUF_SIZE 32 /* size of buffer in bits */ +typedef INT32 bit_buf_type; /* type of bit-extraction buffer */ +#define BIT_BUF_SIZE 32 /* size of buffer in bits */ /* If long is > 32 bits on your machine, and shifting/masking longs is * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE @@ -79,43 +80,43 @@ typedef INT32 bit_buf_type; /* type of bit-extraction buffer */ * because not all machines measure sizeof in 8-bit bytes. */ -typedef struct { /* Bitreading state saved across MCUs */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ +typedef struct { /* Bitreading state saved across MCUs */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ } bitread_perm_state; -typedef struct { /* Bitreading working state within an MCU */ +typedef struct { /* Bitreading working state within an MCU */ /* Current data source location */ /* We need a copy, rather than munging the original, in case of suspension */ const JOCTET * next_input_byte; /* => next byte to read from source */ - size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ + size_t bytes_in_buffer; /* # of bytes remaining in source buffer */ /* Bit input buffer --- note these values are kept in register variables, * not in this struct, inside the inner loops. */ - bit_buf_type get_buffer; /* current bit-extraction buffer */ - int bits_left; /* # of unused bits in it */ + bit_buf_type get_buffer; /* current bit-extraction buffer */ + int bits_left; /* # of unused bits in it */ /* Pointer needed by jpeg_fill_bit_buffer. */ - j_decompress_ptr cinfo; /* back link to decompress master record */ + j_decompress_ptr cinfo; /* back link to decompress master record */ } bitread_working_state; /* Macros to declare and load/save bitread local variables. */ #define BITREAD_STATE_VARS \ - register bit_buf_type get_buffer; \ - register int bits_left; \ - bitread_working_state br_state + register bit_buf_type get_buffer; \ + register int bits_left; \ + bitread_working_state br_state #define BITREAD_LOAD_STATE(cinfop,permstate) \ - br_state.cinfo = cinfop; \ - br_state.next_input_byte = cinfop->src->next_input_byte; \ - br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ - get_buffer = permstate.get_buffer; \ - bits_left = permstate.bits_left; + br_state.cinfo = cinfop; \ + br_state.next_input_byte = cinfop->src->next_input_byte; \ + br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \ + get_buffer = permstate.get_buffer; \ + bits_left = permstate.bits_left; #define BITREAD_SAVE_STATE(cinfop,permstate) \ - cinfop->src->next_input_byte = br_state.next_input_byte; \ - cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ - permstate.get_buffer = get_buffer; \ - permstate.bits_left = bits_left + cinfop->src->next_input_byte = br_state.next_input_byte; \ + cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \ + permstate.get_buffer = get_buffer; \ + permstate.bits_left = bits_left /* * These macros provide the in-line portion of bit fetching. @@ -123,37 +124,37 @@ typedef struct { /* Bitreading working state within an MCU */ * before using GET_BITS, PEEK_BITS, or DROP_BITS. * The variables get_buffer and bits_left are assumed to be locals, * but the state struct might not be (jpeg_huff_decode needs this). - * CHECK_BIT_BUFFER(state,n,action); - * Ensure there are N bits in get_buffer; if suspend, take action. + * CHECK_BIT_BUFFER(state,n,action); + * Ensure there are N bits in get_buffer; if suspend, take action. * val = GET_BITS(n); - * Fetch next N bits. + * Fetch next N bits. * val = PEEK_BITS(n); - * Fetch next N bits without removing them from the buffer. - * DROP_BITS(n); - * Discard next N bits. + * Fetch next N bits without removing them from the buffer. + * DROP_BITS(n); + * Discard next N bits. * The value N should be a simple variable, not an expression, because it * is evaluated multiple times. */ #define CHECK_BIT_BUFFER(state,nbits,action) \ - { if (bits_left < (nbits)) { \ - if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ - { action; } \ - get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } + { if (bits_left < (nbits)) { \ + if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \ + { action; } \ + get_buffer = (state).get_buffer; bits_left = (state).bits_left; } } #define GET_BITS(nbits) \ - (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) + (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1)) #define PEEK_BITS(nbits) \ - (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) + (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1)) #define DROP_BITS(nbits) \ - (bits_left -= (nbits)) + (bits_left -= (nbits)) /* Load up the bit buffer to a depth of at least nbits */ EXTERN(boolean) jpeg_fill_bit_buffer - JPP((bitread_working_state * state, register bit_buf_type get_buffer, - register int bits_left, int nbits)); + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, int nbits)); /* @@ -190,12 +191,39 @@ EXTERN(boolean) jpeg_fill_bit_buffer nb = HUFF_LOOKAHEAD+1; \ slowlabel: \ if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \ - { failaction; } \ + { failaction; } \ get_buffer = state.get_buffer; bits_left = state.bits_left; \ } \ } /* Out-of-line case for Huffman code fetching */ EXTERN(int) jpeg_huff_decode - JPP((bitread_working_state * state, register bit_buf_type get_buffer, - register int bits_left, d_derived_tbl * htbl, int min_bits)); + JPP((bitread_working_state * state, register bit_buf_type get_buffer, + register int bits_left, d_derived_tbl * htbl, int min_bits)); + + +/* Common fields between sequential, progressive and lossless Huffman entropy + * decoder master structs. + */ + +#define huffd_common_fields \ + boolean insufficient_data; /* set TRUE after emmitting warning */ \ + /* These fields are loaded into local variables at start of each MCU. \ + * In case of suspension, we exit WITHOUT updating them. \ + */ \ + bitread_perm_state bitstate /* Bit buffer at start of MCU */ + +/* Routines that are to be used by any or all of the entropy decoders are + * declared to receive a pointer to this structure. There are no actual + * instances of huffd_common_struct, only of shuff_entropy_decoder, + * phuff_entropy_decoder and lhuff_entropy_decoder. + */ +struct huffd_common_struct { + huffd_common_fields; /* Fields common to all decoder struct types */ + /* Additional fields follow in an actual shuff_entropy_decoder, + * phuff_entropy_decoder or lhuff_entropy_decoder struct. All four structs + * must agree on these initial fields! (This would be a lot cleaner in C++.) + */ +}; + +typedef struct huffd_common_struct * huffd_common_ptr; diff --git a/src/jpeg/libijg/jdinput.c b/src/jpeg/libijg/jdinput.c index 0c2ac8f1..8cb0f22d 100644 --- a/src/jpeg/libijg/jdinput.c +++ b/src/jpeg/libijg/jdinput.c @@ -1,14 +1,15 @@ /* * jdinput.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains input control logic for the JPEG decompressor. * These routines are concerned with controlling the decompressor's input - * processing (marker reading and coefficient decoding). The actual input - * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c. + * processing (marker reading and coefficient/difference decoding). + * The actual input reading is done in jdmarker.c, jdhuff.c, jdphuff.c, + * and jdlhuff.c. */ #define JPEG_INTERNALS @@ -21,7 +22,7 @@ typedef struct { struct jpeg_input_controller pub; /* public fields */ - boolean inheaders; /* TRUE until first SOS is reached */ + boolean inheaders; /* TRUE until first SOS is reached */ } my_input_controller; typedef my_input_controller * my_inputctl_ptr; @@ -47,14 +48,22 @@ initial_setup (j_decompress_ptr cinfo) (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION) ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION); - /* For now, precision must match compiled-in value... */ - if (cinfo->data_precision != BITS_IN_JSAMPLE) - ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + if (cinfo->process == JPROC_LOSSLESS) { + /* If precision > compiled-in value, we must downscale */ + if (cinfo->data_precision > BITS_IN_JSAMPLE) + WARNMS2(cinfo, JWRN_MUST_DOWNSCALE, + cinfo->data_precision, BITS_IN_JSAMPLE); + } + else { /* Lossy processes */ + /* For now, precision must match compiled-in value... */ + if (cinfo->data_precision != BITS_IN_JSAMPLE) + ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision); + } /* 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; @@ -62,31 +71,31 @@ initial_setup (j_decompress_ptr cinfo) 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); } - /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE. + /* We initialize codec_data_unit and min_codec_data_unit to data_unit. * In the full decompressor, this will be overridden by jdmaster.c; * but in the transcoder, jdmaster.c is not used, so we must do it here. */ - cinfo->min_DCT_scaled_size = DCTSIZE; + cinfo->min_codec_data_unit = cinfo->data_unit; /* Compute dimensions of components */ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - compptr->DCT_scaled_size = DCTSIZE; - /* Size in DCT blocks */ - compptr->width_in_blocks = (JDIMENSION) + compptr->codec_data_unit = cinfo->data_unit; + /* Size in data units */ + compptr->width_in_data_units = (JDIMENSION) jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->height_in_blocks = (JDIMENSION) + (long) (cinfo->max_h_samp_factor * cinfo->data_unit)); + compptr->height_in_data_units = (JDIMENSION) jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * DCTSIZE)); + (long) (cinfo->max_v_samp_factor * cinfo->data_unit)); /* downsampled_width and downsampled_height will also be overridden by * jdmaster.c if we are doing full decompression. The transcoder library * doesn't use these values, but the calling application might. @@ -94,10 +103,10 @@ initial_setup (j_decompress_ptr cinfo) /* Size in samples */ compptr->downsampled_width = (JDIMENSION) jdiv_round_up((long) cinfo->image_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->image_height * (long) compptr->v_samp_factor, - (long) cinfo->max_v_samp_factor); + (long) cinfo->max_v_samp_factor); /* Mark component needed, until color conversion says otherwise */ compptr->component_needed = TRUE; /* Mark no quantization table yet saved for component */ @@ -107,10 +116,11 @@ initial_setup (j_decompress_ptr cinfo) /* Compute number of fully interleaved MCU rows. */ cinfo->total_iMCU_rows = (JDIMENSION) jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor*cinfo->data_unit)); /* Decide whether file contains multiple scans */ - if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode) + if (cinfo->comps_in_scan < cinfo->num_components || + cinfo->process == JPROC_PROGRESSIVE) cinfo->inputctl->has_multiple_scans = TRUE; else cinfo->inputctl->has_multiple_scans = FALSE; @@ -124,31 +134,31 @@ per_scan_setup (j_decompress_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; + cinfo->MCUs_per_row = compptr->width_in_data_units; + cinfo->MCU_rows_in_scan = compptr->height_in_data_units; - /* For noninterleaved scan, always one block per MCU */ + /* For noninterleaved scan, always one data unit per MCU */ compptr->MCU_width = 1; compptr->MCU_height = 1; - compptr->MCU_blocks = 1; - compptr->MCU_sample_width = compptr->DCT_scaled_size; + compptr->MCU_data_units = 1; + compptr->MCU_sample_width = compptr->codec_data_unit; compptr->last_col_width = 1; /* For noninterleaved scans, it is convenient to define last_row_height - * as the number of block rows present in the last iMCU row. + * as the number of data unit rows present in the last iMCU row. */ - tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor); + tmp = (int) (compptr->height_in_data_units % 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->data_units_in_MCU = 1; cinfo->MCU_membership[0] = 0; } else { @@ -156,38 +166,38 @@ per_scan_setup (j_decompress_ptr cinfo) /* 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->image_width, - (long) (cinfo->max_h_samp_factor*DCTSIZE)); + (long) (cinfo->max_h_samp_factor*cinfo->data_unit)); cinfo->MCU_rows_in_scan = (JDIMENSION) jdiv_round_up((long) cinfo->image_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor*cinfo->data_unit)); - cinfo->blocks_in_MCU = 0; + cinfo->data_units_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 */ + /* Sampling factors give # of data units of component in each MCU */ compptr->MCU_width = compptr->h_samp_factor; compptr->MCU_height = compptr->v_samp_factor; - compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height; - compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size; - /* Figure number of non-dummy blocks in last MCU column & row */ - tmp = (int) (compptr->width_in_blocks % compptr->MCU_width); + compptr->MCU_data_units = compptr->MCU_width * compptr->MCU_height; + compptr->MCU_sample_width = compptr->MCU_width * compptr->codec_data_unit; + /* Figure number of non-dummy data units in last MCU column & row */ + tmp = (int) (compptr->width_in_data_units % compptr->MCU_width); if (tmp == 0) tmp = compptr->MCU_width; compptr->last_col_width = tmp; - tmp = (int) (compptr->height_in_blocks % compptr->MCU_height); + tmp = (int) (compptr->height_in_data_units % compptr->MCU_height); if (tmp == 0) tmp = compptr->MCU_height; compptr->last_row_height = tmp; /* Prepare array describing MCU composition */ - mcublks = compptr->MCU_blocks; - if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU) - ERREXIT(cinfo, JERR_BAD_MCU_SIZE); + mcublks = compptr->MCU_data_units; + if (cinfo->data_units_in_MCU + mcublks > D_MAX_DATA_UNITS_IN_MCU) + ERREXIT(cinfo, JERR_BAD_MCU_SIZE); while (mcublks-- > 0) { - cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci; + cinfo->MCU_membership[cinfo->data_units_in_MCU++] = ci; } } @@ -195,54 +205,6 @@ per_scan_setup (j_decompress_ptr cinfo) } -/* - * Save away a copy of the Q-table referenced by each component present - * in the current scan, unless already saved during a prior scan. - * - * In a multiple-scan JPEG file, the encoder could assign different components - * the same Q-table slot number, but change table definitions between scans - * so that each component uses a different Q-table. (The IJG encoder is not - * currently capable of doing this, but other encoders might.) Since we want - * to be able to dequantize all the components at the end of the file, this - * means that we have to save away the table actually used for each component. - * We do this by copying the table at the start of the first scan containing - * the component. - * The JPEG spec prohibits the encoder from changing the contents of a Q-table - * slot between scans of a component using that slot. If the encoder does so - * anyway, this decoder will simply use the Q-table values that were current - * at the start of the first scan for the component. - * - * The decompressor output side looks only at the saved quant tables, - * not at the current Q-table slots. - */ - -LOCAL(void) -latch_quant_tables (j_decompress_ptr cinfo) -{ - int ci, qtblno; - jpeg_component_info *compptr; - JQUANT_TBL * qtbl; - - for (ci = 0; ci < cinfo->comps_in_scan; ci++) { - compptr = cinfo->cur_comp_info[ci]; - /* No work if we already saved Q-table for this component */ - if (compptr->quant_table != NULL) - continue; - /* Make sure specified quantization table is present */ - qtblno = compptr->quant_tbl_no; - if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || - cinfo->quant_tbl_ptrs[qtblno] == NULL) - ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); - /* OK, save away the quantization table */ - qtbl = (JQUANT_TBL *) - (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(JQUANT_TBL)); - MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); - compptr->quant_table = qtbl; - } -} - - /* * Initialize the input modules to read a scan of compressed data. * The first call to this is done by jdmaster.c after initializing @@ -254,10 +216,8 @@ METHODDEF(void) start_input_pass (j_decompress_ptr cinfo) { per_scan_setup(cinfo); - latch_quant_tables(cinfo); - (*cinfo->entropy->start_pass) (cinfo); - (*cinfo->coef->start_input_pass) (cinfo); - cinfo->inputctl->consume_input = cinfo->coef->consume_data; + (*cinfo->codec->start_input_pass) (cinfo); + cinfo->inputctl->consume_input = cinfo->codec->consume_data; } @@ -296,31 +256,37 @@ consume_markers (j_decompress_ptr cinfo) val = (*cinfo->marker->read_markers) (cinfo); switch (val) { - case JPEG_REACHED_SOS: /* Found SOS */ - if (inputctl->inheaders) { /* 1st SOS */ + case JPEG_REACHED_SOS: /* Found SOS */ + if (inputctl->inheaders) { /* 1st SOS */ initial_setup(cinfo); + /* + * Initialize the decompression codec. We need to do this here so that + * any codec-specific fields and function pointers are available to + * the rest of the library. + */ + jinit_d_codec(cinfo); inputctl->inheaders = FALSE; /* Note: start_input_pass must be called by jdmaster.c * before any more input can be consumed. jdapimin.c is * responsible for enforcing this sequencing. */ - } else { /* 2nd or later SOS marker */ + } else { /* 2nd or later SOS marker */ if (! inputctl->pub.has_multiple_scans) - ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ + ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */ start_input_pass(cinfo); } break; - case JPEG_REACHED_EOI: /* Found EOI */ + case JPEG_REACHED_EOI: /* Found EOI */ inputctl->pub.eoi_reached = TRUE; - if (inputctl->inheaders) { /* Tables-only datastream, apparently */ + if (inputctl->inheaders) { /* Tables-only datastream, apparently */ if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_NO_SOS); + ERREXIT(cinfo, JERR_SOF_NO_SOS); } else { /* Prevent infinite loop in coef ctlr's decompress_data routine * if user set output_scan_number larger than number of scans. */ if (cinfo->output_scan_number > cinfo->input_scan_number) - cinfo->output_scan_number = cinfo->input_scan_number; + cinfo->output_scan_number = cinfo->input_scan_number; } break; case JPEG_SUSPENDED: @@ -365,7 +331,7 @@ jinit_input_controller (j_decompress_ptr cinfo) /* Create subobject in permanent pool */ inputctl = (my_inputctl_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_input_controller)); + SIZEOF(my_input_controller)); cinfo->inputctl = (struct jpeg_input_controller *) inputctl; /* Initialize method pointers */ inputctl->pub.consume_input = consume_markers; diff --git a/src/jpeg/libijg/jdlhuff.c b/src/jpeg/libijg/jdlhuff.c new file mode 100644 index 00000000..2ee9f28a --- /dev/null +++ b/src/jpeg/libijg/jdlhuff.c @@ -0,0 +1,291 @@ +/* + * jdlhuff.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for lossless JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ +#include "jdhuff.h" /* Declarations shared with jd*huff.c */ + + +#ifdef D_LOSSLESS_SUPPORTED + +typedef struct { + int ci, yoffset, MCU_width; +} lhd_output_ptr_info; + +/* + * Private entropy decoder object for lossless Huffman decoding. + */ + +typedef struct { + huffd_common_fields; /* Fields shared with other entropy decoders */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcus: */ + + /* Pointers to derived tables to be used for each data unit within an MCU */ + d_derived_tbl * cur_tbls[D_MAX_DATA_UNITS_IN_MCU]; + + /* Pointers to the proper output difference row for each group of data units + * within an MCU. For each component, there are Vi groups of Hi data units. + */ + JDIFFROW output_ptr[D_MAX_DATA_UNITS_IN_MCU]; + + /* Number of output pointers in use for the current MCU. This is the sum + * of all Vi in the MCU. + */ + int num_output_ptrs; + + /* Information used for positioning the output pointers within the output + * difference rows. + */ + lhd_output_ptr_info output_ptr_info[D_MAX_DATA_UNITS_IN_MCU]; + + /* Index of the proper output pointer for each data unit within an MCU */ + int output_ptr_index[D_MAX_DATA_UNITS_IN_MCU]; + +} lhuff_entropy_decoder; + +typedef lhuff_entropy_decoder * lhuff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_lhuff_decoder (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsd->entropy_private; + int ci, dctbl, sampn, ptrn, yoffset, xoffset; + jpeg_component_info * compptr; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + /* Make sure requested tables are present */ + if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS || + cinfo->dc_huff_tbl_ptrs[dctbl] == NULL) + ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl); + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + & entropy->derived_tbls[dctbl]); + } + + /* Precalculate decoding info for each sample in an MCU of this scan */ + for (sampn = 0, ptrn = 0; sampn < cinfo->data_units_in_MCU;) { + compptr = cinfo->cur_comp_info[cinfo->MCU_membership[sampn]]; + ci = compptr->component_index; + for (yoffset = 0; yoffset < compptr->MCU_height; yoffset++, ptrn++) { + /* Precalculate the setup info for each output pointer */ + entropy->output_ptr_info[ptrn].ci = ci; + entropy->output_ptr_info[ptrn].yoffset = yoffset; + entropy->output_ptr_info[ptrn].MCU_width = compptr->MCU_width; + for (xoffset = 0; xoffset < compptr->MCU_width; xoffset++, sampn++) { + /* Precalculate the output pointer index for each sample */ + entropy->output_ptr_index[sampn] = ptrn; + /* Precalculate which table to use for each sample */ + entropy->cur_tbls[sampn] = entropy->derived_tbls[compptr->dc_tbl_no]; + } + } + } + entropy->num_output_ptrs = ptrn; + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->insufficient_data = FALSE; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +METHODDEF(boolean) +process_restart (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsd->entropy_private; + /* int ci; */ + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Decode and return nMCU's worth of Huffman-compressed differences. + * Each MCU is also disassembled and placed accordingly in diff_buf. + * + * MCU_col_num specifies the column of the first MCU being requested within + * the MCU-row. This tells us where to position the output row pointers in + * diff_buf. + * + * Returns the number of MCUs decoded. This may be less than nMCU if data + * source requested suspension. In that case no changes have been made to + * permanent state. (Exception: some output differences may already have + * been assigned. This is harmless for this module, since we'll just + * re-assign them on the next call.) + */ + +METHODDEF(JDIMENSION) +decode_mcus (j_decompress_ptr cinfo, JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, JDIMENSION MCU_col_num, JDIMENSION nMCU) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + lhuff_entropy_ptr entropy = (lhuff_entropy_ptr) losslsd->entropy_private; + unsigned int mcu_num; + int sampn, ci, yoffset, MCU_width, ptrn; + BITREAD_STATE_VARS; + + /* Set output pointer locations based on MCU_col_num */ + for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) { + ci = entropy->output_ptr_info[ptrn].ci; + yoffset = entropy->output_ptr_info[ptrn].yoffset; + MCU_width = entropy->output_ptr_info[ptrn].MCU_width; + entropy->output_ptr[ptrn] = + diff_buf[ci][MCU_row_num + yoffset] + (MCU_col_num * MCU_width); + } + + /* + * If we've run out of data, zero out the buffers and return. + * By resetting the undifferencer, the output samples will be CENTERJSAMPLE. + * + * NB: We should find a way to do this without interacting with the + * undifferencer module directly. + */ + if (entropy->insufficient_data) { + for (ptrn = 0; ptrn < entropy->num_output_ptrs; ptrn++) + jzero_far((void FAR *) entropy->output_ptr[ptrn], + nMCU * entropy->output_ptr_info[ptrn].MCU_width * SIZEOF(JDIFF)); + + (*losslsd->predict_process_restart) (cinfo); + } + + else { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + + /* Outer loop handles the number of MCU requested */ + + for (mcu_num = 0; mcu_num < nMCU; mcu_num++) { + + /* Inner loop handles the samples in the MCU */ + for (sampn = 0; sampn < cinfo->data_units_in_MCU; sampn++) { + d_derived_tbl * dctbl = entropy->cur_tbls[sampn]; + register int s, r; + + /* Section H.2.2: decode the sample difference */ + HUFF_DECODE(s, br_state, dctbl, return mcu_num, label1); + if (s) { + if (s == 16) /* special case: always output 32768 */ + s = 32768; + else { /* normal case: fetch subsequent bits */ + CHECK_BIT_BUFFER(br_state, s, return mcu_num); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + } + + /* Output the sample difference */ + *entropy->output_ptr[entropy->output_ptr_index[sampn]]++ = (JDIFF) s; + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + } + } + + return nMCU; +} + + +/* + * Module initialization routine for lossless Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_lhuff_decoder (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + lhuff_entropy_ptr entropy; + int i; + + entropy = (lhuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(lhuff_entropy_decoder)); + losslsd->entropy_private = (void *) entropy; + losslsd->entropy_start_pass = start_pass_lhuff_decoder; + losslsd->entropy_process_restart = process_restart; + losslsd->entropy_decode_mcus = decode_mcus; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->derived_tbls[i] = NULL; + } +} + +#endif /* D_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jdlossls.c b/src/jpeg/libijg/jdlossls.c new file mode 100644 index 00000000..046cd3b7 --- /dev/null +++ b/src/jpeg/libijg/jdlossls.c @@ -0,0 +1,94 @@ +/* + * jdlossls.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the control logic for the lossless JPEG decompressor. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" + + +#ifdef D_LOSSLESS_SUPPORTED + +/* + * Compute output image dimensions and related values. + */ + +METHODDEF(void) +calc_output_dimensions (j_decompress_ptr cinfo) +{ + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized codec_data_unit to 1, + * and has computed unscaled downsampled_width and downsampled_height. + */ +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + + (*losslsd->entropy_start_pass) (cinfo); + (*losslsd->predict_start_pass) (cinfo); + (*losslsd->scaler_start_pass) (cinfo); + (*losslsd->diff_start_input_pass) (cinfo); +} + + +/* + * Initialize the lossless decompression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_lossless_d_codec(j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd; + boolean use_c_buffer; + + /* Create subobject in permanent pool */ + losslsd = (j_lossless_d_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(jpeg_lossless_d_codec)); + cinfo->codec = (struct jpeg_d_codec *) losslsd; + + /* Initialize sub-modules */ + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + jinit_arith_decoder(cinfo); + } else { + jinit_lhuff_decoder(cinfo); + } + + /* Undifferencer */ + jinit_undifferencer(cinfo); + + /* Scaler */ + jinit_d_scaler(cinfo); + + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_diff_controller(cinfo, use_c_buffer); + + /* Initialize method pointers. + * + * Note: consume_data, start_output_pass and decompress_data are + * assigned in jddiffct.c. + */ + losslsd->pub.calc_output_dimensions = calc_output_dimensions; + losslsd->pub.start_input_pass = start_input_pass; +} + +#endif /* D_LOSSLESS_SUPPORTED */ diff --git a/src/jpeg/libijg/jdlossy.c b/src/jpeg/libijg/jdlossy.c new file mode 100644 index 00000000..637714fa --- /dev/null +++ b/src/jpeg/libijg/jdlossy.c @@ -0,0 +1,228 @@ +/* + * jdlossy.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains the control logic for the lossy JPEG decompressor. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossy.h" + + +/* + * Compute output image dimensions and related values. + */ + +METHODDEF(void) +calc_output_dimensions (j_decompress_ptr cinfo) +{ +#ifdef IDCT_SCALING_SUPPORTED + int ci; + jpeg_component_info *compptr; + + /* Compute actual output image dimensions and DCT scaling choices. */ + if (cinfo->scale_num * 8 <= cinfo->scale_denom) { + /* Provide 1/8 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 8L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 8L); + cinfo->min_codec_data_unit = 1; + } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { + /* Provide 1/4 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 4L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 4L); + cinfo->min_codec_data_unit = 2; + } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { + /* Provide 1/2 scaling */ + cinfo->output_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width, 2L); + cinfo->output_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height, 2L); + cinfo->min_codec_data_unit = 4; + } else { + /* Provide 1/1 scaling */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + cinfo->min_codec_data_unit = DCTSIZE; + } + /* In selecting the actual DCT scaling for each component, we try to + * scale up the chroma components via IDCT scaling rather than upsampling. + * This saves time if the upsampler gets to use 1:1 scaling. + * Note this code assumes that the supported DCT scalings are powers of 2. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + int ssize = cinfo->min_codec_data_unit; + while (ssize < DCTSIZE && + (compptr->h_samp_factor * ssize * 2 <= + cinfo->max_h_samp_factor * cinfo->min_codec_data_unit) && + (compptr->v_samp_factor * ssize * 2 <= + cinfo->max_v_samp_factor * cinfo->min_codec_data_unit)) { + ssize = ssize * 2; + } + compptr->codec_data_unit = ssize; + } + + /* Recompute downsampled dimensions of components; + * application needs to know these if using raw downsampled data. + */ + for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; + ci++, compptr++) { + /* Size in samples, after IDCT scaling */ + compptr->downsampled_width = (JDIMENSION) + jdiv_round_up((long) cinfo->image_width * + (long) (compptr->h_samp_factor * compptr->codec_data_unit), + (long) (cinfo->max_h_samp_factor * DCTSIZE)); + compptr->downsampled_height = (JDIMENSION) + jdiv_round_up((long) cinfo->image_height * + (long) (compptr->v_samp_factor * compptr->codec_data_unit), + (long) (cinfo->max_v_samp_factor * DCTSIZE)); + } + +#else /* !IDCT_SCALING_SUPPORTED */ + + /* Hardwire it to "no scaling" */ + cinfo->output_width = cinfo->image_width; + cinfo->output_height = cinfo->image_height; + /* jdinput.c has already initialized codec_data_unit to DCTSIZE, + * and has computed unscaled downsampled_width and downsampled_height. + */ + +#endif /* IDCT_SCALING_SUPPORTED */ +} + + +/* + * Save away a copy of the Q-table referenced by each component present + * in the current scan, unless already saved during a prior scan. + * + * In a multiple-scan JPEG file, the encoder could assign different components + * the same Q-table slot number, but change table definitions between scans + * so that each component uses a different Q-table. (The IJG encoder is not + * currently capable of doing this, but other encoders might.) Since we want + * to be able to dequantize all the components at the end of the file, this + * means that we have to save away the table actually used for each component. + * We do this by copying the table at the start of the first scan containing + * the component. + * The JPEG spec prohibits the encoder from changing the contents of a Q-table + * slot between scans of a component using that slot. If the encoder does so + * anyway, this decoder will simply use the Q-table values that were current + * at the start of the first scan for the component. + * + * The decompressor output side looks only at the saved quant tables, + * not at the current Q-table slots. + */ + +LOCAL(void) +latch_quant_tables (j_decompress_ptr cinfo) +{ + int ci, qtblno; + jpeg_component_info *compptr; + JQUANT_TBL * qtbl; + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + /* No work if we already saved Q-table for this component */ + if (compptr->quant_table != NULL) + continue; + /* Make sure specified quantization table is present */ + qtblno = compptr->quant_tbl_no; + if (qtblno < 0 || qtblno >= NUM_QUANT_TBLS || + cinfo->quant_tbl_ptrs[qtblno] == NULL) + ERREXIT1(cinfo, JERR_NO_QUANT_TABLE, qtblno); + /* OK, save away the quantization table */ + qtbl = (JQUANT_TBL *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(JQUANT_TBL)); + MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JQUANT_TBL)); + compptr->quant_table = qtbl; + } +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +start_input_pass (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + + latch_quant_tables(cinfo); + (*lossyd->entropy_start_pass) (cinfo); + (*lossyd->coef_start_input_pass) (cinfo); +} + + +/* + * Initialize for an output processing pass. + */ + +METHODDEF(void) +start_output_pass (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + + (*lossyd->idct_start_pass) (cinfo); + (*lossyd->coef_start_output_pass) (cinfo); +} + +/* + * Initialize the lossy decompression codec. + * This is called only once, during master selection. + */ + +GLOBAL(void) +jinit_lossy_d_codec (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd; + boolean use_c_buffer; + + /* Create subobject in permanent pool */ + lossyd = (j_lossy_d_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(jpeg_lossy_d_codec)); + cinfo->codec = (struct jpeg_d_codec *) lossyd; + + /* Initialize sub-modules */ + + /* Inverse DCT */ + jinit_inverse_dct(cinfo); + /* Entropy decoding: either Huffman or arithmetic coding. */ + if (cinfo->arith_code) { + jinit_arith_decoder(cinfo); + } else { + if (cinfo->process == JPROC_PROGRESSIVE) { +#ifdef D_PROGRESSIVE_SUPPORTED + jinit_phuff_decoder(cinfo); +#else + ERREXIT(cinfo, JERR_NOT_COMPILED); +#endif + } else + jinit_shuff_decoder(cinfo); + } + + use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; + jinit_d_coef_controller(cinfo, use_c_buffer); + + /* Initialize method pointers. + * + * Note: consume_data and decompress_data are assigned in jdcoefct.c. + */ + lossyd->pub.calc_output_dimensions = calc_output_dimensions; + lossyd->pub.start_input_pass = start_input_pass; + lossyd->pub.start_output_pass = start_output_pass; +} + + + + diff --git a/src/jpeg/libijg/jdmainct.c b/src/jpeg/libijg/jdmainct.c index 996d7b49..c3de1169 100644 --- a/src/jpeg/libijg/jdmainct.c +++ b/src/jpeg/libijg/jdmainct.c @@ -1,7 +1,7 @@ /* * jdmainct.c * - * Copyright (C) 1994-1996, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -26,18 +26,18 @@ * rescaling, and doing this in an efficient fashion is a bit tricky. * * Postprocessor input data is counted in "row groups". A row group - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) - * sample rows of each component. (We require DCT_scaled_size values to be - * chosen such that these numbers are integers. In practice DCT_scaled_size + * is defined to be (v_samp_factor * codec_data_unit / min_codec_data_unit) + * sample rows of each component. (We require codec_data_unit values to be + * chosen such that these numbers are integers. In practice codec_data_unit * values will likely be powers of two, so we actually have the stronger - * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.) + * condition that codec_data_unit / min_codec_data_unit is an integer.) * Upsampling will typically produce max_v_samp_factor pixel rows from each * row group (times any additional scale factor that the upsampler is * applying). * - * The coefficient controller will deliver data to us one iMCU row at a time; - * each iMCU row contains v_samp_factor * DCT_scaled_size sample rows, or - * exactly min_DCT_scaled_size row groups. (This amount of data corresponds + * The decompression codec will deliver data to us one iMCU row at a time; + * each iMCU row contains v_samp_factor * codec_data_unit sample rows, or + * exactly min_codec_data_unit row groups. (This amount of data corresponds * to one row of MCUs when the image is fully interleaved.) Note that the * number of sample rows varies across components, but the number of row * groups does not. Some garbage sample rows may be included in the last iMCU @@ -64,7 +64,7 @@ * supporting arbitrary output rescaling might wish for more than one row * group of context when shrinking the image; tough, we don't handle that. * (This is justified by the assumption that downsizing will be handled mostly - * by adjusting the DCT_scaled_size values, so that the actual scale factor at + * by adjusting the codec_data_unit values, so that the actual scale factor at * the upsample step needn't be much less than one.) * * To provide the desired context, we have to retain the last two row groups @@ -74,7 +74,7 @@ * We could do this most simply by copying data around in our buffer, but * that'd be very slow. We can avoid copying any data by creating a rather * strange pointer structure. Here's how it works. We allocate a workspace - * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number + * consisting of M+2 row groups (where M = min_codec_data_unit is the number * of row groups per iMCU row). We create two sets of redundant pointers to * the workspace. Labeling the physical row groups 0 to M+1, the synthesized * pointer lists look like this: @@ -99,11 +99,11 @@ * the first or last sample row as necessary (this is cheaper than copying * sample rows around). * - * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that + * This scheme breaks down if M < 2, ie, min_codec_data_unit is 1. In that * situation each iMCU row provides only one row group so the buffering logic * must be different (eg, we must read two iMCU rows before we can emit the * first row group). For now, we simply do not support providing context - * rows when min_DCT_scaled_size is 1. That combination seems unlikely to + * rows when min_codec_data_unit is 1. That combination seems unlikely to * be worth providing --- if someone wants a 1/8th-size preview, they probably * want it quick and dirty, so a context-free upsampler is sufficient. */ @@ -159,24 +159,24 @@ alloc_funny_pointers (j_decompress_ptr cinfo) * This is done only once, not once per pass. */ { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; int ci, rgroup; - int M = cinfo->min_DCT_scaled_size; + int M = cinfo->min_codec_data_unit; jpeg_component_info *compptr; JSAMPARRAY xbuf; /* Get top-level space for component array pointers. * We alloc both arrays with one call to save a few cycles. */ - mainPtr->xbuffer[0] = (JSAMPIMAGE) + main->xbuffer[0] = (JSAMPIMAGE) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, cinfo->num_components * 2 * SIZEOF(JSAMPARRAY)); - mainPtr->xbuffer[1] = mainPtr->xbuffer[0] + cinfo->num_components; + main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ + rgroup = (compptr->v_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; /* height of a row group of component */ /* Get space for pointer lists --- M+4 row groups in each list. * We alloc both pointer lists with one call to save a few cycles. */ @@ -184,9 +184,9 @@ alloc_funny_pointers (j_decompress_ptr cinfo) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW)); xbuf += rgroup; /* want one row group at negative offsets */ - mainPtr->xbuffer[0][ci] = xbuf; + main->xbuffer[0][ci] = xbuf; xbuf += rgroup * (M + 4); - mainPtr->xbuffer[1][ci] = xbuf; + main->xbuffer[1][ci] = xbuf; } } @@ -194,26 +194,26 @@ alloc_funny_pointers (j_decompress_ptr cinfo) LOCAL(void) make_funny_pointers (j_decompress_ptr cinfo) /* Create the funny pointer lists discussed in the comments above. - * The actual workspace is already allocated (in mainPtr->buffer), + * The actual workspace is already allocated (in main->buffer), * and the space for the pointer lists is allocated too. * This routine just fills in the curiously ordered lists. * This will be repeated at the beginning of each pass. */ { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; int ci, i, rgroup; - int M = cinfo->min_DCT_scaled_size; + int M = cinfo->min_codec_data_unit; jpeg_component_info *compptr; JSAMPARRAY buf, xbuf0, xbuf1; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - xbuf0 = mainPtr->xbuffer[0][ci]; - xbuf1 = mainPtr->xbuffer[1][ci]; + rgroup = (compptr->v_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; /* First copy the workspace pointers as-is */ - buf = mainPtr->buffer[ci]; + buf = main->buffer[ci]; for (i = 0; i < rgroup * (M + 2); i++) { xbuf0[i] = xbuf1[i] = buf[i]; } @@ -240,18 +240,18 @@ set_wraparound_pointers (j_decompress_ptr cinfo) * This changes the pointer list state from top-of-image to the normal state. */ { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; int ci, i, rgroup; - int M = cinfo->min_DCT_scaled_size; + int M = cinfo->min_codec_data_unit; jpeg_component_info *compptr; JSAMPARRAY xbuf0, xbuf1; for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - xbuf0 = mainPtr->xbuffer[0][ci]; - xbuf1 = mainPtr->xbuffer[1][ci]; + rgroup = (compptr->v_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; /* height of a row group of component */ + xbuf0 = main->xbuffer[0][ci]; + xbuf1 = main->xbuffer[1][ci]; for (i = 0; i < rgroup; i++) { xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i]; xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i]; @@ -269,7 +269,7 @@ set_bottom_pointers (j_decompress_ptr cinfo) * Also sets rowgroups_avail to indicate number of nondummy row groups in row. */ { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; int ci, i, rgroup, iMCUheight, rows_left; jpeg_component_info *compptr; JSAMPARRAY xbuf; @@ -277,8 +277,8 @@ set_bottom_pointers (j_decompress_ptr cinfo) for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { /* Count sample rows in one iMCU row and in one row group */ - iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size; - rgroup = iMCUheight / cinfo->min_DCT_scaled_size; + iMCUheight = compptr->v_samp_factor * compptr->codec_data_unit; + rgroup = iMCUheight / cinfo->min_codec_data_unit; /* Count nondummy sample rows remaining for this component */ rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight); if (rows_left == 0) rows_left = iMCUheight; @@ -286,12 +286,12 @@ set_bottom_pointers (j_decompress_ptr cinfo) * so we need only do it once. */ if (ci == 0) { - mainPtr->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); + main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1); } /* Duplicate the last real sample row rgroup*2 times; this pads out the * last partial rowgroup and ensures at least one full rowgroup of context. */ - xbuf = mainPtr->xbuffer[mainPtr->whichptr][ci]; + xbuf = main->xbuffer[main->whichptr][ci]; for (i = 0; i < rgroup * 2; i++) { xbuf[rows_left + i] = xbuf[rows_left-1]; } @@ -306,27 +306,27 @@ set_bottom_pointers (j_decompress_ptr cinfo) METHODDEF(void) start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; switch (pass_mode) { case JBUF_PASS_THRU: if (cinfo->upsample->need_context_rows) { - mainPtr->pub.process_data = process_data_context_main; + main->pub.process_data = process_data_context_main; make_funny_pointers(cinfo); /* Create the xbuffer[] lists */ - mainPtr->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ - mainPtr->context_state = CTX_PREPARE_FOR_IMCU; - mainPtr->iMCU_row_ctr = 0; + main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */ + main->context_state = CTX_PREPARE_FOR_IMCU; + main->iMCU_row_ctr = 0; } else { /* Simple case with no context needed */ - mainPtr->pub.process_data = process_data_simple_main; + main->pub.process_data = process_data_simple_main; } - mainPtr->buffer_full = FALSE; /* Mark buffer empty */ - mainPtr->rowgroup_ctr = 0; + main->buffer_full = FALSE; /* Mark buffer empty */ + main->rowgroup_ctr = 0; break; #ifdef QUANT_2PASS_SUPPORTED case JBUF_CRANK_DEST: /* For last pass of 2-pass quantization, just crank the postprocessor */ - mainPtr->pub.process_data = process_data_crank_post; + main->pub.process_data = process_data_crank_post; break; #endif default: @@ -346,32 +346,32 @@ process_data_simple_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; JDIMENSION rowgroups_avail; /* Read input data if we haven't filled the main buffer yet */ - if (! mainPtr->buffer_full) { - if (! (*cinfo->coef->decompress_data) (cinfo, mainPtr->buffer)) + if (! main->buffer_full) { + if (! (*cinfo->codec->decompress_data) (cinfo, main->buffer)) return; /* suspension forced, can do nothing more */ - mainPtr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ } - /* There are always min_DCT_scaled_size row groups in an iMCU row. */ - rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size; + /* There are always min_codec_data_unit row groups in an iMCU row. */ + rowgroups_avail = (JDIMENSION) cinfo->min_codec_data_unit; /* Note: at the bottom of the image, we may pass extra garbage row groups * to the postprocessor. The postprocessor has to check for bottom * of image anyway (at row resolution), so no point in us doing it too. */ /* Feed the postprocessor */ - (*cinfo->post->post_process_data) (cinfo, mainPtr->buffer, - &mainPtr->rowgroup_ctr, rowgroups_avail, + (*cinfo->post->post_process_data) (cinfo, main->buffer, + &main->rowgroup_ctr, rowgroups_avail, output_buf, out_row_ctr, out_rows_avail); /* Has postprocessor consumed all the data yet? If so, mark buffer empty */ - if (mainPtr->rowgroup_ctr >= rowgroups_avail) { - mainPtr->buffer_full = FALSE; - mainPtr->rowgroup_ctr = 0; + if (main->rowgroup_ctr >= rowgroups_avail) { + main->buffer_full = FALSE; + main->rowgroup_ctr = 0; } } @@ -386,15 +386,15 @@ process_data_context_main (j_decompress_ptr cinfo, JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail) { - my_main_ptr mainPtr = (my_main_ptr) cinfo->main; + my_main_ptr main = (my_main_ptr) cinfo->main; /* Read input data if we haven't filled the main buffer yet */ - if (! mainPtr->buffer_full) { - if (! (*cinfo->coef->decompress_data) (cinfo, - mainPtr->xbuffer[mainPtr->whichptr])) + if (! main->buffer_full) { + if (! (*cinfo->codec->decompress_data) (cinfo, + main->xbuffer[main->whichptr])) return; /* suspension forced, can do nothing more */ - mainPtr->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ - mainPtr->iMCU_row_ctr++; /* count rows received */ + main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */ + main->iMCU_row_ctr++; /* count rows received */ } /* Postprocessor typically will not swallow all the input data it is handed @@ -402,47 +402,47 @@ process_data_context_main (j_decompress_ptr cinfo, * to exit and restart. This switch lets us keep track of how far we got. * Note that each case falls through to the next on successful completion. */ - switch (mainPtr->context_state) { + switch (main->context_state) { case CTX_POSTPONED_ROW: /* Call postprocessor using previously set pointers for postponed row */ - (*cinfo->post->post_process_data) (cinfo, mainPtr->xbuffer[mainPtr->whichptr], - &mainPtr->rowgroup_ctr, mainPtr->rowgroups_avail, + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, output_buf, out_row_ctr, out_rows_avail); - if (mainPtr->rowgroup_ctr < mainPtr->rowgroups_avail) + if (main->rowgroup_ctr < main->rowgroups_avail) return; /* Need to suspend */ - mainPtr->context_state = CTX_PREPARE_FOR_IMCU; + main->context_state = CTX_PREPARE_FOR_IMCU; if (*out_row_ctr >= out_rows_avail) return; /* Postprocessor exactly filled output buf */ /*FALLTHROUGH*/ case CTX_PREPARE_FOR_IMCU: /* Prepare to process first M-1 row groups of this iMCU row */ - mainPtr->rowgroup_ctr = 0; - mainPtr->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1); + main->rowgroup_ctr = 0; + main->rowgroups_avail = (JDIMENSION) (cinfo->min_codec_data_unit - 1); /* Check for bottom of image: if so, tweak pointers to "duplicate" * the last sample row, and adjust rowgroups_avail to ignore padding rows. */ - if (mainPtr->iMCU_row_ctr == cinfo->total_iMCU_rows) + if (main->iMCU_row_ctr == cinfo->total_iMCU_rows) set_bottom_pointers(cinfo); - mainPtr->context_state = CTX_PROCESS_IMCU; + main->context_state = CTX_PROCESS_IMCU; /*FALLTHROUGH*/ case CTX_PROCESS_IMCU: /* Call postprocessor using previously set pointers */ - (*cinfo->post->post_process_data) (cinfo, mainPtr->xbuffer[mainPtr->whichptr], - &mainPtr->rowgroup_ctr, mainPtr->rowgroups_avail, + (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr], + &main->rowgroup_ctr, main->rowgroups_avail, output_buf, out_row_ctr, out_rows_avail); - if (mainPtr->rowgroup_ctr < mainPtr->rowgroups_avail) + if (main->rowgroup_ctr < main->rowgroups_avail) return; /* Need to suspend */ /* After the first iMCU, change wraparound pointers to normal state */ - if (mainPtr->iMCU_row_ctr == 1) + if (main->iMCU_row_ctr == 1) set_wraparound_pointers(cinfo); /* Prepare to load new iMCU row using other xbuffer list */ - mainPtr->whichptr ^= 1; /* 0=>1 or 1=>0 */ - mainPtr->buffer_full = FALSE; + main->whichptr ^= 1; /* 0=>1 or 1=>0 */ + main->buffer_full = FALSE; /* Still need to process last row group of this iMCU row, */ /* which is saved at index M+1 of the other xbuffer */ - mainPtr->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1); - mainPtr->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2); - mainPtr->context_state = CTX_POSTPONED_ROW; + main->rowgroup_ctr = (JDIMENSION) (cinfo->min_codec_data_unit + 1); + main->rowgroups_avail = (JDIMENSION) (cinfo->min_codec_data_unit + 2); + main->context_state = CTX_POSTPONED_ROW; } } @@ -475,15 +475,15 @@ process_data_crank_post (j_decompress_ptr cinfo, GLOBAL(void) jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) { - my_main_ptr mainPtr; + my_main_ptr main; int ci, rgroup, ngroups; jpeg_component_info *compptr; - mainPtr = (my_main_ptr) + main = (my_main_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(my_main_controller)); - cinfo->main = (struct jpeg_d_main_controller *) mainPtr; - mainPtr->pub.start_pass = start_pass_main; + cinfo->main = (struct jpeg_d_main_controller *) main; + main->pub.start_pass = start_pass_main; if (need_full_buffer) /* shouldn't happen */ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); @@ -492,21 +492,21 @@ jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer) * ngroups is the number of row groups we need. */ if (cinfo->upsample->need_context_rows) { - if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */ + if (cinfo->min_codec_data_unit < 2) /* unsupported, see comments above */ ERREXIT(cinfo, JERR_NOTIMPL); alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */ - ngroups = cinfo->min_DCT_scaled_size + 2; + ngroups = cinfo->min_codec_data_unit + 2; } else { - ngroups = cinfo->min_DCT_scaled_size; + ngroups = cinfo->min_codec_data_unit; } for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { - rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; /* height of a row group of component */ - mainPtr->buffer[ci] = (*cinfo->mem->alloc_sarray) + rgroup = (compptr->v_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; /* height of a row group of component */ + main->buffer[ci] = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo, JPOOL_IMAGE, - compptr->width_in_blocks * compptr->DCT_scaled_size, + compptr->width_in_data_units * compptr->codec_data_unit, (JDIMENSION) (rgroup * ngroups)); } } diff --git a/src/jpeg/libijg/jdmarker.c b/src/jpeg/libijg/jdmarker.c index f4cca8cc..e280621b 100644 --- a/src/jpeg/libijg/jdmarker.c +++ b/src/jpeg/libijg/jdmarker.c @@ -17,7 +17,7 @@ #include "jpeglib.h" -typedef enum { /* JPEG marker codes */ +typedef enum { /* JPEG marker codes */ M_SOF0 = 0xc0, M_SOF1 = 0xc1, M_SOF2 = 0xc2, @@ -99,8 +99,8 @@ typedef struct { unsigned int length_limit_APPn[16]; /* Status of COM/APPn marker saving */ - jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ - unsigned int bytes_read; /* data bytes read so far in marker */ + jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */ + unsigned int bytes_read; /* data bytes read so far in marker */ /* Note: cur_marker is not linked into marker_list until it's all read. */ } my_marker_reader; @@ -117,49 +117,49 @@ typedef my_marker_reader * my_marker_ptr; /* Declare and initialize local copies of input pointer/count */ #define INPUT_VARS(cinfo) \ - struct jpeg_source_mgr * datasrc = (cinfo)->src; \ - const JOCTET * next_input_byte = datasrc->next_input_byte; \ - size_t bytes_in_buffer = datasrc->bytes_in_buffer + struct jpeg_source_mgr * datasrc = (cinfo)->src; \ + const JOCTET * next_input_byte = datasrc->next_input_byte; \ + size_t bytes_in_buffer = datasrc->bytes_in_buffer /* Unload the local copies --- do this only at a restart boundary */ #define INPUT_SYNC(cinfo) \ - ( datasrc->next_input_byte = next_input_byte, \ - datasrc->bytes_in_buffer = bytes_in_buffer ) + ( datasrc->next_input_byte = next_input_byte, \ + datasrc->bytes_in_buffer = bytes_in_buffer ) /* Reload the local copies --- used only in MAKE_BYTE_AVAIL */ #define INPUT_RELOAD(cinfo) \ - ( next_input_byte = datasrc->next_input_byte, \ - bytes_in_buffer = datasrc->bytes_in_buffer ) + ( next_input_byte = datasrc->next_input_byte, \ + bytes_in_buffer = datasrc->bytes_in_buffer ) /* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available. * Note we do *not* do INPUT_SYNC before calling fill_input_buffer, * but we must reload the local copies after a successful fill. */ #define MAKE_BYTE_AVAIL(cinfo,action) \ - if (bytes_in_buffer == 0) { \ - if (! (*datasrc->fill_input_buffer) (cinfo)) \ - { action; } \ - INPUT_RELOAD(cinfo); \ - } + if (bytes_in_buffer == 0) { \ + if (! (*datasrc->fill_input_buffer) (cinfo)) \ + { action; } \ + INPUT_RELOAD(cinfo); \ + } /* Read a byte into variable V. * If must suspend, take the specified action (typically "return FALSE"). */ #define INPUT_BYTE(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V = GETJOCTET(*next_input_byte++); ) + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = GETJOCTET(*next_input_byte++); ) /* As above, but read two bytes interpreted as an unsigned 16-bit integer. * V should be declared unsigned int or perhaps INT32. */ #define INPUT_2BYTES(cinfo,V,action) \ - MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ - MAKE_BYTE_AVAIL(cinfo,action); \ - bytes_in_buffer--; \ - V += GETJOCTET(*next_input_byte++); ) + MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \ + MAKE_BYTE_AVAIL(cinfo,action); \ + bytes_in_buffer--; \ + V += GETJOCTET(*next_input_byte++); ) /* @@ -234,7 +234,8 @@ get_soi (j_decompress_ptr cinfo) LOCAL(boolean) -get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) +get_sof (j_decompress_ptr cinfo, J_CODEC_PROCESS process, boolean is_arith, + int data_unit) /* Process a SOFn marker */ { INT32 length; @@ -242,7 +243,8 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) jpeg_component_info * compptr; INPUT_VARS(cinfo); - cinfo->progressive_mode = is_prog; + cinfo->data_unit = data_unit; + cinfo->process = process; cinfo->arith_code = is_arith; INPUT_2BYTES(cinfo, length, return FALSE); @@ -255,8 +257,8 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) length -= 8; TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker, - (int) cinfo->image_width, (int) cinfo->image_height, - cinfo->num_components); + (int) cinfo->image_width, (int) cinfo->image_height, + cinfo->num_components); if (cinfo->marker->saw_SOF) ERREXIT(cinfo, JERR_SOF_DUPLICATE); @@ -271,10 +273,10 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) if (length != (cinfo->num_components * 3)) ERREXIT(cinfo, JERR_BAD_LENGTH); - if (cinfo->comp_info == NULL) /* do only once, even if suspend */ + if (cinfo->comp_info == NULL) /* do only once, even if suspend */ cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small) - ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components * SIZEOF(jpeg_component_info)); + ((j_common_ptr) cinfo, JPOOL_IMAGE, + cinfo->num_components * SIZEOF(jpeg_component_info)); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; ci++, compptr++) { @@ -286,8 +288,8 @@ get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith) INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE); TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT, - compptr->component_id, compptr->h_samp_factor, - compptr->v_samp_factor, compptr->quant_tbl_no); + compptr->component_id, compptr->h_samp_factor, + compptr->v_samp_factor, compptr->quant_tbl_no); } cinfo->marker->saw_SOF = TRUE; @@ -327,9 +329,9 @@ get_sos (j_decompress_ptr cinfo) INPUT_BYTE(cinfo, c, return FALSE); for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { + ci++, compptr++) { if (cc == compptr->component_id) - goto id_found; + goto id_found; } ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc); @@ -341,7 +343,7 @@ get_sos (j_decompress_ptr cinfo) compptr->ac_tbl_no = (c ) & 15; TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc, - compptr->dc_tbl_no, compptr->ac_tbl_no); + compptr->dc_tbl_no, compptr->ac_tbl_no); } /* Collect the additional scan parameters Ss, Se, Ah/Al. */ @@ -354,7 +356,7 @@ get_sos (j_decompress_ptr cinfo) cinfo->Al = (c ) & 15; TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se, - cinfo->Ah, cinfo->Al); + cinfo->Ah, cinfo->Al); /* Prepare to scan data & restart markers */ cinfo->marker->next_restart_num = 0; @@ -393,11 +395,11 @@ get_dac (j_decompress_ptr cinfo) if (index >= NUM_ARITH_TBLS) { /* define AC table */ cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val; - } else { /* define DC table */ + } else { /* define DC table */ cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F); cinfo->arith_dc_U[index] = (UINT8) (val >> 4); if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index]) - ERREXIT1(cinfo, JERR_DAC_VALUE, val); + ERREXIT1(cinfo, JERR_DAC_VALUE, val); } } @@ -444,11 +446,11 @@ get_dht (j_decompress_ptr cinfo) length -= 1 + 16; TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[1], bits[2], bits[3], bits[4], - bits[5], bits[6], bits[7], bits[8]); + bits[1], bits[2], bits[3], bits[4], + bits[5], bits[6], bits[7], bits[8]); TRACEMS8(cinfo, 2, JTRC_HUFFBITS, - bits[9], bits[10], bits[11], bits[12], - bits[13], bits[14], bits[15], bits[16]); + bits[9], bits[10], bits[11], bits[12], + bits[13], bits[14], bits[15], bits[16]); /* Here we just do minimal validation of the counts to avoid walking * off the end of our table space. jdhuff.c will check more carefully. @@ -461,10 +463,10 @@ get_dht (j_decompress_ptr cinfo) length -= count; - if (index & 0x10) { /* AC table definition */ + if (index & 0x10) { /* AC table definition */ index -= 0x10; htblptr = &cinfo->ac_huff_tbl_ptrs[index]; - } else { /* DC table definition */ + } else { /* DC table definition */ htblptr = &cinfo->dc_huff_tbl_ptrs[index]; } @@ -515,20 +517,20 @@ get_dqt (j_decompress_ptr cinfo) for (i = 0; i < DCTSIZE2; i++) { if (prec) - INPUT_2BYTES(cinfo, tmp, return FALSE); + INPUT_2BYTES(cinfo, tmp, return FALSE); else - INPUT_BYTE(cinfo, tmp, return FALSE); + INPUT_BYTE(cinfo, tmp, return FALSE); /* We convert the zigzag-order table to natural array order. */ quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp; } if (cinfo->err->trace_level >= 2) { for (i = 0; i < DCTSIZE2; i += 8) { - TRACEMS8(cinfo, 2, JTRC_QUANTVALS, - quant_ptr->quantval[i], quant_ptr->quantval[i+1], - quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], - quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], - quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); + TRACEMS8(cinfo, 2, JTRC_QUANTVALS, + quant_ptr->quantval[i], quant_ptr->quantval[i+1], + quant_ptr->quantval[i+2], quant_ptr->quantval[i+3], + quant_ptr->quantval[i+4], quant_ptr->quantval[i+5], + quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]); } } @@ -575,14 +577,14 @@ get_dri (j_decompress_ptr cinfo) * JFIF and Adobe markers, respectively. */ -#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ -#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ -#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ +#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */ +#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */ +#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */ LOCAL(void) examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, - unsigned int datalen, INT32 remaining) + unsigned int datalen, INT32 remaining) /* Examine first few bytes from an APP0. * Take appropriate action if it is a JFIF marker. * datalen is # of bytes at data[], remaining is length of rest of marker data. @@ -611,18 +613,18 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, */ if (cinfo->JFIF_major_version != 1) WARNMS2(cinfo, JWRN_JFIF_MAJOR, - cinfo->JFIF_major_version, cinfo->JFIF_minor_version); + cinfo->JFIF_major_version, cinfo->JFIF_minor_version); /* Generate trace messages */ TRACEMS5(cinfo, 1, JTRC_JFIF, - cinfo->JFIF_major_version, cinfo->JFIF_minor_version, - cinfo->X_density, cinfo->Y_density, cinfo->density_unit); + cinfo->JFIF_major_version, cinfo->JFIF_minor_version, + cinfo->X_density, cinfo->Y_density, cinfo->density_unit); /* Validate thumbnail dimensions and issue appropriate messages */ if (GETJOCTET(data[12]) | GETJOCTET(data[13])) TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL, - GETJOCTET(data[12]), GETJOCTET(data[13])); + GETJOCTET(data[12]), GETJOCTET(data[13])); totallen -= APP0_DATA_LEN; if (totallen != - ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) + ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3)) TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen); } else if (datalen >= 6 && GETJOCTET(data[0]) == 0x4A && @@ -646,7 +648,7 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, break; default: TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION, - GETJOCTET(data[5]), (int) totallen); + GETJOCTET(data[5]), (int) totallen); break; } } else { @@ -658,7 +660,7 @@ examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data, LOCAL(void) examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data, - unsigned int datalen, INT32 remaining) + unsigned int datalen, INT32 remaining) /* Examine first few bytes from an APP14. * Take appropriate action if it is an Adobe marker. * datalen is # of bytes at data[], remaining is length of rest of marker data. @@ -750,19 +752,19 @@ save_marker (j_decompress_ptr cinfo) /* begin reading a marker */ INPUT_2BYTES(cinfo, length, return FALSE); length -= 2; - if (length >= 0) { /* watch out for bogus length word */ + if (length >= 0) { /* watch out for bogus length word */ /* figure out how much we want to save */ unsigned int limit; if (cinfo->unread_marker == (int) M_COM) - limit = marker->length_limit_COM; + limit = marker->length_limit_COM; else - limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; + limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0]; if ((unsigned int) length < limit) - limit = (unsigned int) length; + limit = (unsigned int) length; /* allocate and initialize the marker item */ cur_marker = (jpeg_saved_marker_ptr) - (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(struct jpeg_marker_struct) + limit); + (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(struct jpeg_marker_struct) + limit); cur_marker->next = NULL; cur_marker->marker = (UINT8) cinfo->unread_marker; cur_marker->original_length = (unsigned int) length; @@ -786,7 +788,7 @@ save_marker (j_decompress_ptr cinfo) } while (bytes_read < data_length) { - INPUT_SYNC(cinfo); /* move the restart point to here */ + INPUT_SYNC(cinfo); /* move the restart point to here */ marker->bytes_read = bytes_read; /* If there's not at least one byte in buffer, suspend */ MAKE_BYTE_AVAIL(cinfo, return FALSE); @@ -799,14 +801,14 @@ save_marker (j_decompress_ptr cinfo) } /* Done reading what we want to read */ - if (cur_marker != NULL) { /* will be NULL if bogus length word */ + if (cur_marker != NULL) { /* will be NULL if bogus length word */ /* Add new marker to end of list */ if (cinfo->marker_list == NULL) { cinfo->marker_list = cur_marker; } else { jpeg_saved_marker_ptr prev = cinfo->marker_list; while (prev->next != NULL) - prev = prev->next; + prev = prev->next; prev->next = cur_marker; } /* Reset pointer & calc remaining data length */ @@ -826,12 +828,12 @@ save_marker (j_decompress_ptr cinfo) break; default: TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, - (int) (data_length + length)); + (int) (data_length + length)); break; } /* skip any remaining data -- could be lots */ - INPUT_SYNC(cinfo); /* do before skip_input_data */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ if (length > 0) (*cinfo->src->skip_input_data) (cinfo, (long) length); @@ -853,7 +855,7 @@ skip_variable (j_decompress_ptr cinfo) TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length); - INPUT_SYNC(cinfo); /* do before skip_input_data */ + INPUT_SYNC(cinfo); /* do before skip_input_data */ if (length > 0) (*cinfo->src->skip_input_data) (cinfo, (long) length); @@ -897,7 +899,7 @@ next_marker (j_decompress_ptr cinfo) INPUT_BYTE(cinfo, c, return FALSE); } while (c == 0xFF); if (c != 0) - break; /* found a valid marker, exit loop */ + break; /* found a valid marker, exit loop */ /* Reach here if we found a stuffed-zero data sequence (FF/00). * Discard it and loop back to try again. */ @@ -957,11 +959,11 @@ read_markers (j_decompress_ptr cinfo) /* NB: first_marker() enforces the requirement that SOI appear first. */ if (cinfo->unread_marker == 0) { if (! cinfo->marker->saw_SOI) { - if (! first_marker(cinfo)) - return JPEG_SUSPENDED; + if (! first_marker(cinfo)) + return JPEG_SUSPENDED; } else { - if (! next_marker(cinfo)) - return JPEG_SUSPENDED; + if (! next_marker(cinfo)) + return JPEG_SUSPENDED; } } /* At this point cinfo->unread_marker contains the marker code and the @@ -971,72 +973,80 @@ read_markers (j_decompress_ptr cinfo) switch (cinfo->unread_marker) { case M_SOI: if (! get_soi(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; + break; + + case M_SOF0: /* Baseline */ + case M_SOF1: /* Extended sequential, Huffman */ + if (! get_sof(cinfo, JPROC_SEQUENTIAL, FALSE, DCTSIZE)) + return JPEG_SUSPENDED; + break; + + case M_SOF2: /* Progressive, Huffman */ + if (! get_sof(cinfo, JPROC_PROGRESSIVE, FALSE, DCTSIZE)) + return JPEG_SUSPENDED; break; - case M_SOF0: /* Baseline */ - case M_SOF1: /* Extended sequential, Huffman */ - if (! get_sof(cinfo, FALSE, FALSE)) - return JPEG_SUSPENDED; + case M_SOF3: /* Lossless, Huffman */ + if (! get_sof(cinfo, JPROC_LOSSLESS, FALSE, 1)) + return JPEG_SUSPENDED; break; - case M_SOF2: /* Progressive, Huffman */ - if (! get_sof(cinfo, TRUE, FALSE)) - return JPEG_SUSPENDED; + case M_SOF9: /* Extended sequential, arithmetic */ + if (! get_sof(cinfo, JPROC_SEQUENTIAL, TRUE, DCTSIZE)) + return JPEG_SUSPENDED; break; - case M_SOF9: /* Extended sequential, arithmetic */ - if (! get_sof(cinfo, FALSE, TRUE)) - return JPEG_SUSPENDED; + case M_SOF10: /* Progressive, arithmetic */ + if (! get_sof(cinfo, JPROC_PROGRESSIVE, TRUE, DCTSIZE)) + return JPEG_SUSPENDED; break; - case M_SOF10: /* Progressive, arithmetic */ - if (! get_sof(cinfo, TRUE, TRUE)) - return JPEG_SUSPENDED; + case M_SOF11: /* Lossless, arithmetic */ + if (! get_sof(cinfo, JPROC_LOSSLESS, TRUE, 1)) + return JPEG_SUSPENDED; break; /* Currently unsupported SOFn types */ - case M_SOF3: /* Lossless, Huffman */ - case M_SOF5: /* Differential sequential, Huffman */ - case M_SOF6: /* Differential progressive, Huffman */ - case M_SOF7: /* Differential lossless, Huffman */ - case M_JPG: /* Reserved for JPEG extensions */ - case M_SOF11: /* Lossless, arithmetic */ - case M_SOF13: /* Differential sequential, arithmetic */ - case M_SOF14: /* Differential progressive, arithmetic */ - case M_SOF15: /* Differential lossless, arithmetic */ + case M_SOF5: /* Differential sequential, Huffman */ + case M_SOF6: /* Differential progressive, Huffman */ + case M_SOF7: /* Differential lossless, Huffman */ + case M_JPG: /* Reserved for JPEG extensions */ + case M_SOF13: /* Differential sequential, arithmetic */ + case M_SOF14: /* Differential progressive, arithmetic */ + case M_SOF15: /* Differential lossless, arithmetic */ ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker); break; case M_SOS: if (! get_sos(cinfo)) - return JPEG_SUSPENDED; - cinfo->unread_marker = 0; /* processed the marker */ + return JPEG_SUSPENDED; + cinfo->unread_marker = 0; /* processed the marker */ return JPEG_REACHED_SOS; case M_EOI: TRACEMS(cinfo, 1, JTRC_EOI); - cinfo->unread_marker = 0; /* processed the marker */ + cinfo->unread_marker = 0; /* processed the marker */ return JPEG_REACHED_EOI; case M_DAC: if (! get_dac(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; case M_DHT: if (! get_dht(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; case M_DQT: if (! get_dqt(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; case M_DRI: if (! get_dri(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; case M_APP0: @@ -1056,16 +1066,16 @@ read_markers (j_decompress_ptr cinfo) case M_APP14: case M_APP15: if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[ - cinfo->unread_marker - (int) M_APP0]) (cinfo)) - return JPEG_SUSPENDED; + cinfo->unread_marker - (int) M_APP0]) (cinfo)) + return JPEG_SUSPENDED; break; case M_COM: if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; - case M_RST0: /* these are all parameterless */ + case M_RST0: /* these are all parameterless */ case M_RST1: case M_RST2: case M_RST3: @@ -1077,12 +1087,12 @@ read_markers (j_decompress_ptr cinfo) TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker); break; - case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ + case M_DNL: /* Ignore DNL ... perhaps the wrong thing */ if (! skip_variable(cinfo)) - return JPEG_SUSPENDED; + return JPEG_SUSPENDED; break; - default: /* must be DHP, EXP, JPGn, or RESn */ + default: /* must be DHP, EXP, JPGn, or RESn */ /* For now, we treat the reserved markers as fatal errors since they are * likely to be used to signal incompatible JPEG Part 3 extensions. * Once the JPEG 3 version-number marker is well defined, this code @@ -1128,7 +1138,7 @@ read_restart_marker (j_decompress_ptr cinfo) /* Uh-oh, the restart markers have been messed up. */ /* Let the data source manager determine how to resync. */ if (! (*cinfo->src->resync_to_restart) (cinfo, - cinfo->marker->next_restart_num)) + cinfo->marker->next_restart_num)) return FALSE; } @@ -1200,18 +1210,18 @@ jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) /* Outer loop handles repeated decision after scanning forward. */ for (;;) { if (marker < (int) M_SOF0) - action = 2; /* invalid marker */ + action = 2; /* invalid marker */ else if (marker < (int) M_RST0 || marker > (int) M_RST7) - action = 3; /* valid non-restart marker */ + action = 3; /* valid non-restart marker */ else { if (marker == ((int) M_RST0 + ((desired+1) & 7)) || - marker == ((int) M_RST0 + ((desired+2) & 7))) - action = 3; /* one of the next two expected restarts */ + marker == ((int) M_RST0 + ((desired+2) & 7))) + action = 3; /* one of the next two expected restarts */ else if (marker == ((int) M_RST0 + ((desired-1) & 7)) || - marker == ((int) M_RST0 + ((desired-2) & 7))) - action = 2; /* a prior restart, so advance */ + marker == ((int) M_RST0 + ((desired-2) & 7))) + action = 2; /* a prior restart, so advance */ else - action = 1; /* desired restart or too far away */ + action = 1; /* desired restart or too far away */ } TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action); switch (action) { @@ -1222,7 +1232,7 @@ jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired) case 2: /* Scan to the next marker, and repeat the decision loop. */ if (! next_marker(cinfo)) - return FALSE; + return FALSE; marker = cinfo->unread_marker; break; case 3: @@ -1243,10 +1253,10 @@ reset_marker_reader (j_decompress_ptr cinfo) { my_marker_ptr marker = (my_marker_ptr) cinfo->marker; - cinfo->comp_info = NULL; /* until allocated by get_sof */ - cinfo->input_scan_number = 0; /* no SOS seen yet */ - cinfo->unread_marker = 0; /* no pending marker */ - marker->pub.saw_SOI = FALSE; /* set internal state too */ + cinfo->comp_info = NULL; /* until allocated by get_sof */ + cinfo->input_scan_number = 0; /* no SOS seen yet */ + cinfo->unread_marker = 0; /* no pending marker */ + marker->pub.saw_SOI = FALSE; /* set internal state too */ marker->pub.saw_SOF = FALSE; marker->pub.discarded_bytes = 0; marker->cur_marker = NULL; @@ -1267,7 +1277,7 @@ jinit_marker_reader (j_decompress_ptr cinfo) /* Create subobject in permanent pool */ marker = (my_marker_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, - SIZEOF(my_marker_reader)); + SIZEOF(my_marker_reader)); cinfo->marker = (struct jpeg_marker_reader *) marker; /* Initialize public method pointers */ marker->pub.reset_marker_reader = reset_marker_reader; @@ -1298,7 +1308,7 @@ jinit_marker_reader (j_decompress_ptr cinfo) GLOBAL(void) jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit) + unsigned int length_limit) { my_marker_ptr marker = (my_marker_ptr) cinfo->marker; long maxlength; @@ -1347,7 +1357,7 @@ jpeg_save_markers (j_decompress_ptr cinfo, int marker_code, GLOBAL(void) jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine) + jpeg_marker_parser_method routine) { my_marker_ptr marker = (my_marker_ptr) cinfo->marker; diff --git a/src/jpeg/libijg/jdmaster.c b/src/jpeg/libijg/jdmaster.c index 2802c5b7..cb06e011 100644 --- a/src/jpeg/libijg/jdmaster.c +++ b/src/jpeg/libijg/jdmaster.c @@ -1,7 +1,7 @@ /* * jdmaster.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -21,7 +21,7 @@ typedef struct { struct jpeg_decomp_master pub; /* public fields */ - int pass_number; /* # of passes completed */ + int pass_number; /* # of passes completed */ boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */ @@ -60,13 +60,14 @@ use_merged_upsample (j_decompress_ptr cinfo) cinfo->comp_info[1].v_samp_factor != 1 || cinfo->comp_info[2].v_samp_factor != 1) return FALSE; - /* furthermore, it doesn't work if we've scaled the IDCTs differently */ - if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size || - cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size || - cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size) + /* furthermore, it doesn't work if each component has been + processed differently */ + if (cinfo->comp_info[0].codec_data_unit != cinfo->min_codec_data_unit || + cinfo->comp_info[1].codec_data_unit != cinfo->min_codec_data_unit || + cinfo->comp_info[2].codec_data_unit != cinfo->min_codec_data_unit) return FALSE; /* ??? also need to test for upsample-time rescaling, when & if supported */ - return TRUE; /* by golly, it'll work... */ + return TRUE; /* by golly, it'll work... */ #else return FALSE; #endif @@ -84,89 +85,11 @@ GLOBAL(void) jpeg_calc_output_dimensions (j_decompress_ptr cinfo) /* Do computations that are needed before master selection phase */ { -#ifdef IDCT_SCALING_SUPPORTED - int ci; - jpeg_component_info *compptr; -#endif - /* Prevent application from calling me at wrong times */ if (cinfo->global_state != DSTATE_READY) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); -#ifdef IDCT_SCALING_SUPPORTED - - /* Compute actual output image dimensions and DCT scaling choices. */ - if (cinfo->scale_num * 8 <= cinfo->scale_denom) { - /* Provide 1/8 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 8L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 8L); - cinfo->min_DCT_scaled_size = 1; - } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) { - /* Provide 1/4 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 4L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 4L); - cinfo->min_DCT_scaled_size = 2; - } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) { - /* Provide 1/2 scaling */ - cinfo->output_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width, 2L); - cinfo->output_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height, 2L); - cinfo->min_DCT_scaled_size = 4; - } else { - /* Provide 1/1 scaling */ - cinfo->output_width = cinfo->image_width; - cinfo->output_height = cinfo->image_height; - cinfo->min_DCT_scaled_size = DCTSIZE; - } - /* In selecting the actual DCT scaling for each component, we try to - * scale up the chroma components via IDCT scaling rather than upsampling. - * This saves time if the upsampler gets to use 1:1 scaling. - * Note this code assumes that the supported DCT scalings are powers of 2. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - int ssize = cinfo->min_DCT_scaled_size; - while (ssize < DCTSIZE && - (compptr->h_samp_factor * ssize * 2 <= - cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) && - (compptr->v_samp_factor * ssize * 2 <= - cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) { - ssize = ssize * 2; - } - compptr->DCT_scaled_size = ssize; - } - - /* Recompute downsampled dimensions of components; - * application needs to know these if using raw downsampled data. - */ - for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; - ci++, compptr++) { - /* Size in samples, after IDCT scaling */ - compptr->downsampled_width = (JDIMENSION) - jdiv_round_up((long) cinfo->image_width * - (long) (compptr->h_samp_factor * compptr->DCT_scaled_size), - (long) (cinfo->max_h_samp_factor * DCTSIZE)); - compptr->downsampled_height = (JDIMENSION) - jdiv_round_up((long) cinfo->image_height * - (long) (compptr->v_samp_factor * compptr->DCT_scaled_size), - (long) (cinfo->max_v_samp_factor * DCTSIZE)); - } - -#else /* !IDCT_SCALING_SUPPORTED */ - - /* Hardwire it to "no scaling" */ - cinfo->output_width = cinfo->image_width; - cinfo->output_height = cinfo->image_height; - /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE, - * and has computed unscaled downsampled_width and downsampled_height. - */ - -#endif /* IDCT_SCALING_SUPPORTED */ + (*cinfo->codec->calc_output_dimensions) (cinfo); /* Report number of components in selected colorspace. */ /* Probably this should be in the color conversion module... */ @@ -186,12 +109,12 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) case JCS_YCCK: cinfo->out_color_components = 4; break; - default: /* else must be same colorspace as in file */ + default: /* else must be same colorspace as in file */ cinfo->out_color_components = cinfo->num_components; break; } cinfo->output_components = (cinfo->quantize_colors ? 1 : - cinfo->out_color_components); + cinfo->out_color_components); /* See if upsampler will want to emit more than one row at a time */ if (use_merged_upsample(cinfo)) @@ -208,10 +131,10 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) * processes are inner loops and need to be as fast as possible. On most * machines, particularly CPUs with pipelines or instruction prefetch, * a (subscript-check-less) C table lookup - * x = sample_range_limit[x]; + * x = sample_range_limit[x]; * is faster than explicit tests - * if (x < 0) x = 0; - * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; + * if (x < 0) x = 0; + * else if (x > MAXJSAMPLE) x = MAXJSAMPLE; * These processes all use a common table prepared by the routine below. * * For most steps we can mathematically guarantee that the initial value @@ -221,7 +144,7 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) * possible if the input data is corrupt. To avoid any chance of indexing * off the end of memory and getting a bad-pointer trap, we perform the * post-IDCT limiting thus: - * x = range_limit[x & MASK]; + * x = range_limit[x & MASK]; * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit * samples. Under normal circumstances this is more than enough range and * a correct output will be generated; with bogus input data the mask will @@ -253,23 +176,23 @@ prepare_range_limit_table (j_decompress_ptr cinfo) table = (JSAMPLE *) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); - table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ + (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */ cinfo->sample_range_limit = table; /* First segment of "simple" table: limit[x] = 0 for x < 0 */ MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE)); /* Main part of "simple" table: limit[x] = x */ for (i = 0; i <= MAXJSAMPLE; i++) table[i] = (JSAMPLE) i; - table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ + table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */ /* End of simple table, rest of first half of post-IDCT table */ for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++) table[i] = MAXJSAMPLE; /* Second half of post-IDCT table */ MEMZERO(table + (2 * (MAXJSAMPLE+1)), - (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); + (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE)); MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE), - cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); + cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE)); } @@ -288,7 +211,6 @@ LOCAL(void) master_selection (j_decompress_ptr cinfo) { my_master_ptr master = (my_master_ptr) cinfo->master; - boolean use_c_buffer; long samplesperrow; JDIMENSION jd_samplesperrow; @@ -369,26 +291,8 @@ master_selection (j_decompress_ptr cinfo) } jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant); } - /* Inverse DCT */ - jinit_inverse_dct(cinfo); - /* Entropy decoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef D_PROGRESSIVE_SUPPORTED - jinit_phuff_decoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_decoder(cinfo); - } /* Initialize principal buffer controllers. */ - use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image; - jinit_d_coef_controller(cinfo, use_c_buffer); - if (! cinfo->raw_data_out) jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */); @@ -407,7 +311,7 @@ master_selection (j_decompress_ptr cinfo) cinfo->inputctl->has_multiple_scans) { int nscans; /* Estimate number of scans to set pass_limit. */ - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_PROGRESSIVE) { /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ nscans = 2 + 3 * cinfo->num_components; } else { @@ -453,24 +357,23 @@ prepare_for_output_pass (j_decompress_ptr cinfo) if (cinfo->quantize_colors && cinfo->colormap == NULL) { /* Select new quantization method */ if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) { - cinfo->cquantize = master->quantizer_2pass; - master->pub.is_dummy_pass = TRUE; + cinfo->cquantize = master->quantizer_2pass; + master->pub.is_dummy_pass = TRUE; } else if (cinfo->enable_1pass_quant) { - cinfo->cquantize = master->quantizer_1pass; + cinfo->cquantize = master->quantizer_1pass; } else { - ERREXIT(cinfo, JERR_MODE_CHANGE); + ERREXIT(cinfo, JERR_MODE_CHANGE); } } - (*cinfo->idct->start_pass) (cinfo); - (*cinfo->coef->start_output_pass) (cinfo); + (*cinfo->codec->start_output_pass) (cinfo); if (! cinfo->raw_data_out) { if (! master->using_merged_upsample) - (*cinfo->cconvert->start_pass) (cinfo); + (*cinfo->cconvert->start_pass) (cinfo); (*cinfo->upsample->start_pass) (cinfo); if (cinfo->quantize_colors) - (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); + (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass); (*cinfo->post->start_pass) (cinfo, - (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); + (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU)); (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU); } } @@ -479,7 +382,7 @@ prepare_for_output_pass (j_decompress_ptr cinfo) if (cinfo->progress != NULL) { cinfo->progress->completed_passes = master->pass_number; cinfo->progress->total_passes = master->pass_number + - (master->pub.is_dummy_pass ? 2 : 1); + (master->pub.is_dummy_pass ? 2 : 1); /* In buffered-image mode, we assume one more output pass if EOI not * yet reached, but no more passes if EOI has been reached. */ @@ -546,7 +449,7 @@ jinit_master_decompress (j_decompress_ptr cinfo) master = (my_master_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(my_decomp_master)); + SIZEOF(my_decomp_master)); cinfo->master = (struct jpeg_decomp_master *) master; master->pub.prepare_for_output_pass = prepare_for_output_pass; master->pub.finish_output_pass = finish_output_pass; diff --git a/src/jpeg/libijg/jdmerge.c b/src/jpeg/libijg/jdmerge.c index d5508698..3474595f 100644 --- a/src/jpeg/libijg/jdmerge.c +++ b/src/jpeg/libijg/jdmerge.c @@ -152,8 +152,6 @@ merged_2v_upsample (j_decompress_ptr cinfo, JSAMPROW work_ptrs[2]; JDIMENSION num_rows; /* number of rows returned to caller */ - in_row_groups_avail = 0; - if (upsample->spare_full) { /* If we have a spare row saved from a previous cycle, just return it. */ jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0, @@ -201,9 +199,6 @@ merged_1v_upsample (j_decompress_ptr cinfo, { my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample; - in_row_groups_avail = 0; - out_rows_avail = 0; - /* Just do the upsampling. */ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, output_buf + *out_row_ctr); diff --git a/src/jpeg/libijg/jdphuff.c b/src/jpeg/libijg/jdphuff.c index 22678099..7baaff92 100644 --- a/src/jpeg/libijg/jdphuff.c +++ b/src/jpeg/libijg/jdphuff.c @@ -1,7 +1,7 @@ /* * jdphuff.c * - * Copyright (C) 1995-1997, Thomas G. Lane. + * Copyright (C) 1995-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -17,21 +17,22 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" -#include "jdhuff.h" /* Declarations shared with jdhuff.c */ +#include "jlossy.h" /* Private declarations for lossy subsystem */ +#include "jdhuff.h" /* Declarations shared with jd*huff.c */ #ifdef D_PROGRESSIVE_SUPPORTED /* - * Expanded entropy decoder object for progressive Huffman decoding. + * Private entropy decoder object for progressive Huffman decoding. * * The savable_state subrecord contains fields that change within an MCU, * but must not be updated permanently until we complete the MCU. */ typedef struct { - unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ - int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ + unsigned int EOBRUN; /* remaining EOBs in EOBRUN */ + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ } savable_state; /* This macro is to work around compilers with missing or broken @@ -44,26 +45,25 @@ typedef struct { #else #if MAX_COMPS_IN_SCAN == 4 #define ASSIGN_STATE(dest,src) \ - ((dest).EOBRUN = (src).EOBRUN, \ - (dest).last_dc_val[0] = (src).last_dc_val[0], \ - (dest).last_dc_val[1] = (src).last_dc_val[1], \ - (dest).last_dc_val[2] = (src).last_dc_val[2], \ - (dest).last_dc_val[3] = (src).last_dc_val[3]) + ((dest).EOBRUN = (src).EOBRUN, \ + (dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) #endif #endif typedef struct { - struct jpeg_entropy_decoder pub; /* public fields */ + huffd_common_fields; /* Fields shared with other entropy decoders */ /* These fields are loaded into local variables at start of each MCU. * In case of suspension, we exit WITHOUT updating them. */ - bitread_perm_state bitstate; /* Bit buffer at start of MCU */ - savable_state saved; /* Other state at start of MCU */ + savable_state saved; /* Other state at start of MCU */ /* These fields are NOT loaded into local working state. */ - unsigned int restarts_to_go; /* MCUs left in this restart interval */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ /* Pointers to derived tables (these workspaces have image lifespan) */ d_derived_tbl * derived_tbls[NUM_HUFF_TBLS]; @@ -75,13 +75,13 @@ typedef phuff_entropy_decoder * phuff_entropy_ptr; /* Forward declarations */ METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); + JBLOCKROW *MCU_data)); /* @@ -91,7 +91,8 @@ METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo, METHODDEF(void) start_pass_phuff_decoder (j_decompress_ptr cinfo) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; boolean is_DC_band, bad; int ci, coefi, tbl; int *coef_bit_ptr; @@ -117,7 +118,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) if (cinfo->Al != cinfo->Ah-1) bad = TRUE; } - if (cinfo->Al > 13) /* need not check for < 0 */ + if (cinfo->Al > 13) /* need not check for < 0 */ bad = TRUE; /* Arguably the maximum Al value should be less than 13 for 8-bit precision, * but the spec doesn't say so, and we try to be liberal about what we @@ -127,7 +128,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) */ if (bad) ERREXIT4(cinfo, JERR_BAD_PROGRESSION, - cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); /* Update progression status, and verify that scan order is legal. * Note that inter-scan inconsistencies are treated as warnings * not fatal errors ... not clear if this is right way to behave. @@ -140,7 +141,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) { int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi]; if (cinfo->Ah != expected) - WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); + WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi); coef_bit_ptr[coefi] = cinfo->Al; } } @@ -148,14 +149,14 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) /* Select MCU decoding routine */ if (cinfo->Ah == 0) { if (is_DC_band) - entropy->pub.decode_mcu = decode_mcu_DC_first; + lossyd->entropy_decode_mcu = decode_mcu_DC_first; else - entropy->pub.decode_mcu = decode_mcu_AC_first; + lossyd->entropy_decode_mcu = decode_mcu_AC_first; } else { if (is_DC_band) - entropy->pub.decode_mcu = decode_mcu_DC_refine; + lossyd->entropy_decode_mcu = decode_mcu_DC_refine; else - entropy->pub.decode_mcu = decode_mcu_AC_refine; + lossyd->entropy_decode_mcu = decode_mcu_AC_refine; } for (ci = 0; ci < cinfo->comps_in_scan; ci++) { @@ -164,15 +165,15 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) * We may build same derived table more than once, but it's not expensive. */ if (is_DC_band) { - if (cinfo->Ah == 0) { /* DC refinement needs no table */ - tbl = compptr->dc_tbl_no; - jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, - & entropy->derived_tbls[tbl]); + if (cinfo->Ah == 0) { /* DC refinement needs no table */ + tbl = compptr->dc_tbl_no; + jpeg_make_d_derived_tbl(cinfo, TRUE, tbl, + & entropy->derived_tbls[tbl]); } } else { tbl = compptr->ac_tbl_no; jpeg_make_d_derived_tbl(cinfo, FALSE, tbl, - & entropy->derived_tbls[tbl]); + & entropy->derived_tbls[tbl]); /* remember the single active table */ entropy->ac_derived_tbl = entropy->derived_tbls[tbl]; } @@ -183,7 +184,7 @@ start_pass_phuff_decoder (j_decompress_ptr cinfo) /* Initialize bitread state variables */ entropy->bitstate.bits_left = 0; entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ - entropy->pub.insufficient_data = FALSE; + entropy->insufficient_data = FALSE; /* Initialize private state variables */ entropy->saved.EOBRUN = 0; @@ -227,7 +228,8 @@ static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ LOCAL(boolean) process_restart (j_decompress_ptr cinfo) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; int ci; /* Throw away any unused bits remaining in bit buffer; */ @@ -254,7 +256,7 @@ process_restart (j_decompress_ptr cinfo) * leaving the flag set. */ if (cinfo->unread_marker == 0) - entropy->pub.insufficient_data = FALSE; + entropy->insufficient_data = FALSE; return TRUE; } @@ -285,7 +287,8 @@ process_restart (j_decompress_ptr cinfo) METHODDEF(boolean) decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; int Al = cinfo->Al; register int s, r; int blkn, ci; @@ -299,13 +302,13 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (cinfo->restart_interval) { if (entropy->restarts_to_go == 0) if (! process_restart(cinfo)) - return FALSE; + return FALSE; } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ - if (! entropy->pub.insufficient_data) { + if (! entropy->insufficient_data) { /* Load up working state */ BITREAD_LOAD_STATE(cinfo,entropy->bitstate); @@ -313,7 +316,7 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Outer loop handles each block in the MCU */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { block = MCU_data[blkn]; ci = cinfo->MCU_membership[blkn]; compptr = cinfo->cur_comp_info[ci]; @@ -324,9 +327,9 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Section F.2.2.1: decode the DC coefficient difference */ HUFF_DECODE(s, br_state, tbl, return FALSE, label1); if (s) { - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); } /* Convert DC difference to actual value, update last_dc_val */ @@ -356,7 +359,8 @@ decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; int Se = cinfo->Se; int Al = cinfo->Al; register int s, k, r; @@ -369,60 +373,60 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (cinfo->restart_interval) { if (entropy->restarts_to_go == 0) if (! process_restart(cinfo)) - return FALSE; + return FALSE; } /* If we've run out of data, just leave the MCU set to zeroes. * This way, we return uniform gray for the remainder of the segment. */ - if (! entropy->pub.insufficient_data) { + if (! entropy->insufficient_data) { /* Load up working state. * We can avoid loading/saving bitread state if in an EOB run. */ - EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ + EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */ /* There is always only one block per MCU */ - if (EOBRUN > 0) /* if it's a band of zeroes... */ - EOBRUN--; /* ...process it now (we do nothing) */ + if (EOBRUN > 0) /* if it's a band of zeroes... */ + EOBRUN--; /* ...process it now (we do nothing) */ else { BITREAD_LOAD_STATE(cinfo,entropy->bitstate); block = MCU_data[0]; tbl = entropy->ac_derived_tbl; for (k = cinfo->Ss; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, return FALSE, label2); - r = s >> 4; - s &= 15; - if (s) { - k += r; - CHECK_BIT_BUFFER(br_state, s, return FALSE); - r = GET_BITS(s); - s = HUFF_EXTEND(r, s); - /* Scale and output coefficient in natural (dezigzagged) order */ - (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); - } else { - if (r == 15) { /* ZRL */ - k += 15; /* skip 15 zeroes in band */ - } else { /* EOBr, run length is 2^r + appended bits */ - EOBRUN = 1 << r; - if (r) { /* EOBr, r > 0 */ - CHECK_BIT_BUFFER(br_state, r, return FALSE); - r = GET_BITS(r); - EOBRUN += r; - } - EOBRUN--; /* this band is processed at this moment */ - break; /* force end-of-band */ - } - } + HUFF_DECODE(s, br_state, tbl, return FALSE, label2); + r = s >> 4; + s &= 15; + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Scale and output coefficient in natural (dezigzagged) order */ + (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al); + } else { + if (r == 15) { /* ZRL */ + k += 15; /* skip 15 zeroes in band */ + } else { /* EOBr, run length is 2^r + appended bits */ + EOBRUN = 1 << r; + if (r) { /* EOBr, r > 0 */ + CHECK_BIT_BUFFER(br_state, r, return FALSE); + r = GET_BITS(r); + EOBRUN += r; + } + EOBRUN--; /* this band is processed at this moment */ + break; /* force end-of-band */ + } + } } BITREAD_SAVE_STATE(cinfo,entropy->bitstate); } /* Completed MCU, so update state */ - entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ + entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */ } /* Account for restart interval (no-op if not using restarts) */ @@ -441,8 +445,9 @@ decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; - int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ int blkn; JBLOCKROW block; BITREAD_STATE_VARS; @@ -451,7 +456,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (cinfo->restart_interval) { if (entropy->restarts_to_go == 0) if (! process_restart(cinfo)) - return FALSE; + return FALSE; } /* Not worth the cycles to check insufficient_data here, @@ -463,7 +468,7 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) /* Outer loop handles each block in the MCU */ - for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) { + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { block = MCU_data[blkn]; /* Encoded data is simply the next bit of the two's-complement DC value */ @@ -490,10 +495,11 @@ decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) METHODDEF(boolean) decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) { - phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy; + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + phuff_entropy_ptr entropy = (phuff_entropy_ptr) lossyd->entropy_private; int Se = cinfo->Se; - int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ - int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ + int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */ + int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */ register int s, k, r; unsigned int EOBRUN; JBLOCKROW block; @@ -507,12 +513,12 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (cinfo->restart_interval) { if (entropy->restarts_to_go == 0) if (! process_restart(cinfo)) - return FALSE; + return FALSE; } /* If we've run out of data, don't modify the MCU. */ - if (! entropy->pub.insufficient_data) { + if (! entropy->insufficient_data) { /* Load up working state */ BITREAD_LOAD_STATE(cinfo,entropy->bitstate); @@ -535,58 +541,58 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) if (EOBRUN == 0) { for (; k <= Se; k++) { - HUFF_DECODE(s, br_state, tbl, goto undoit, label3); - r = s >> 4; - s &= 15; - if (s) { - if (s != 1) /* size of new coef should always be 1 */ - WARNMS(cinfo, JWRN_HUFF_BAD_CODE); - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) - s = p1; /* newly nonzero coef is positive */ - else - s = m1; /* newly nonzero coef is negative */ - } else { - if (r != 15) { - EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ - if (r) { - CHECK_BIT_BUFFER(br_state, r, goto undoit); - r = GET_BITS(r); - EOBRUN += r; - } - break; /* rest of block is handled by EOB logic */ - } - /* note s = 0 for processing ZRL */ - } - /* Advance over already-nonzero coefs and r still-zero coefs, - * appending correction bits to the nonzeroes. A correction bit is 1 - * if the absolute value of the coefficient must be increased. - */ - do { - thiscoef = *block + jpeg_natural_order[k]; - if (*thiscoef != 0) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } else { - if (--r < 0) - break; /* reached target zero coefficient */ - } - k++; - } while (k <= Se); - if (s) { - int pos = jpeg_natural_order[k]; - /* Output newly nonzero coefficient */ - (*block)[pos] = (JCOEF) s; - /* Remember its position in case we have to suspend */ - newnz_pos[num_newnz++] = pos; - } + HUFF_DECODE(s, br_state, tbl, goto undoit, label3); + r = s >> 4; + s &= 15; + if (s) { + if (s != 1) /* size of new coef should always be 1 */ + WARNMS(cinfo, JWRN_HUFF_BAD_CODE); + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) + s = p1; /* newly nonzero coef is positive */ + else + s = m1; /* newly nonzero coef is negative */ + } else { + if (r != 15) { + EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */ + if (r) { + CHECK_BIT_BUFFER(br_state, r, goto undoit); + r = GET_BITS(r); + EOBRUN += r; + } + break; /* rest of block is handled by EOB logic */ + } + /* note s = 0 for processing ZRL */ + } + /* Advance over already-nonzero coefs and r still-zero coefs, + * appending correction bits to the nonzeroes. A correction bit is 1 + * if the absolute value of the coefficient must be increased. + */ + do { + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already set it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } else { + if (--r < 0) + break; /* reached target zero coefficient */ + } + k++; + } while (k <= Se); + if (s) { + int pos = jpeg_natural_order[k]; + /* Output newly nonzero coefficient */ + (*block)[pos] = (JCOEF) s; + /* Remember its position in case we have to suspend */ + newnz_pos[num_newnz++] = pos; + } } } @@ -597,18 +603,18 @@ decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) * if the absolute value of the coefficient must be increased. */ for (; k <= Se; k++) { - thiscoef = *block + jpeg_natural_order[k]; - if (*thiscoef != 0) { - CHECK_BIT_BUFFER(br_state, 1, goto undoit); - if (GET_BITS(1)) { - if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ - if (*thiscoef >= 0) - *thiscoef += p1; - else - *thiscoef += m1; - } - } - } + thiscoef = *block + jpeg_natural_order[k]; + if (*thiscoef != 0) { + CHECK_BIT_BUFFER(br_state, 1, goto undoit); + if (GET_BITS(1)) { + if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */ + if (*thiscoef >= 0) + *thiscoef += p1; + else + *thiscoef += m1; + } + } + } } /* Count one block completed in EOB run */ EOBRUN--; @@ -640,15 +646,16 @@ undoit: GLOBAL(void) jinit_phuff_decoder (j_decompress_ptr cinfo) { + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; phuff_entropy_ptr entropy; int *coef_bit_ptr; int ci, i; entropy = (phuff_entropy_ptr) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - SIZEOF(phuff_entropy_decoder)); - cinfo->entropy = (struct jpeg_entropy_decoder *) entropy; - entropy->pub.start_pass = start_pass_phuff_decoder; + SIZEOF(phuff_entropy_decoder)); + lossyd->entropy_private = (void *) entropy; + lossyd->entropy_start_pass = start_pass_phuff_decoder; /* Mark derived tables unallocated */ for (i = 0; i < NUM_HUFF_TBLS; i++) { @@ -658,7 +665,7 @@ jinit_phuff_decoder (j_decompress_ptr cinfo) /* Create progression status table */ cinfo->coef_bits = (int (*)[DCTSIZE2]) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, - cinfo->num_components*DCTSIZE2*SIZEOF(int)); + cinfo->num_components*DCTSIZE2*SIZEOF(int)); coef_bit_ptr = & cinfo->coef_bits[0][0]; for (ci = 0; ci < cinfo->num_components; ci++) for (i = 0; i < DCTSIZE2; i++) diff --git a/src/jpeg/libijg/jdpostct.c b/src/jpeg/libijg/jdpostct.c index 4226077b..3fdb290c 100644 --- a/src/jpeg/libijg/jdpostct.c +++ b/src/jpeg/libijg/jdpostct.c @@ -163,8 +163,6 @@ post_process_prepass (j_decompress_ptr cinfo, { my_post_ptr post = (my_post_ptr) cinfo->post; JDIMENSION old_next_row, num_rows; - output_buf = 0; - out_rows_avail = 0; /* Reposition virtual buffer if at start of strip. */ if (post->next_row == 0) { @@ -210,9 +208,6 @@ post_process_2pass (j_decompress_ptr cinfo, my_post_ptr post = (my_post_ptr) cinfo->post; JDIMENSION num_rows, max_rows; - input_buf = 0; - in_row_group_ctr = 0; - in_row_groups_avail = 0; /* Reposition virtual buffer if at start of strip. */ if (post->next_row == 0) { post->buffer = (*cinfo->mem->access_virt_sarray) diff --git a/src/jpeg/libijg/jdpred.c b/src/jpeg/libijg/jdpred.c new file mode 100644 index 00000000..d8f9f876 --- /dev/null +++ b/src/jpeg/libijg/jdpred.c @@ -0,0 +1,250 @@ +/* + * jdpred.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains sample undifferencing (reconstruction) for lossless JPEG. + * + * In order to avoid paying the performance penalty of having to check the + * predictor being used and the row being processed for each call of the + * undifferencer, and to promote optimization, we have separate undifferencing + * functions for each case. + * + * We are able to avoid duplicating source code by implementing the predictors + * and undifferencers as macros. Each of the undifferencing functions are + * simply wrappers around an UNDIFFERENCE macro with the appropriate PREDICTOR + * macro passed as an argument. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ + + +#ifdef D_LOSSLESS_SUPPORTED + +/* Predictor for the first column of the first row: 2^(P-Pt-1) */ +#define INITIAL_PREDICTORx (1 << (cinfo->data_precision - cinfo->Al - 1)) + +/* Predictor for the first column of the remaining rows: Rb */ +#define INITIAL_PREDICTOR2 GETJSAMPLE(prev_row[0]) + + +/* + * 1-Dimensional undifferencer routine. + * + * This macro implements the 1-D horizontal predictor (1). INITIAL_PREDICTOR + * is used as the special case predictor for the first column, which must be + * either INITIAL_PREDICTOR2 or INITIAL_PREDICTORx. The remaining samples + * use PREDICTOR1. + * + * The reconstructed sample is supposed to be calculated modulo 2^16, so we + * logically AND the result with 0xFFFF. +*/ + +#define UNDIFFERENCE_1D(INITIAL_PREDICTOR) \ + unsigned int xindex; \ + int Ra; \ + \ + Ra = (diff_buf[0] + INITIAL_PREDICTOR) & 0xFFFF; \ + undiff_buf[0] = Ra; \ + \ + for (xindex = 1; xindex < width; xindex++) { \ + Ra = (diff_buf[xindex] + PREDICTOR1) & 0xFFFF; \ + undiff_buf[xindex] = Ra; \ + } + +/* + * 2-Dimensional undifferencer routine. + * + * This macro implements the 2-D horizontal predictors (#2-7). PREDICTOR2 is + * used as the special case predictor for the first column. The remaining + * samples use PREDICTOR, which is a function of Ra, Rb, Rc. + * + * Because prev_row and output_buf may point to the same storage area (in an + * interleaved image with Vi=1, for example), we must take care to buffer Rb/Rc + * before writing the current reconstructed sample value into output_buf. + * + * The reconstructed sample is supposed to be calculated modulo 2^16, so we + * logically AND the result with 0xFFFF. + */ + +#define UNDIFFERENCE_2D(PREDICTOR) \ + unsigned int xindex; \ + int Ra, Rb, Rc; \ + \ + Rb = GETJSAMPLE(prev_row[0]); \ + Ra = (diff_buf[0] + PREDICTOR2) & 0xFFFF; \ + undiff_buf[0] = Ra; \ + \ + for (xindex = 1; xindex < width; xindex++) { \ + Rc = Rb; \ + Rb = GETJSAMPLE(prev_row[xindex]); \ + Ra = (diff_buf[xindex] + PREDICTOR) & 0xFFFF; \ + undiff_buf[xindex] = Ra; \ + } + + +/* + * Undifferencers for the all rows but the first in a scan or restart interval. + * The first sample in the row is undifferenced using the vertical + * predictor (2). The rest of the samples are undifferenced using the + * predictor specified in the scan header. + */ + +METHODDEF(void) +jpeg_undifference1(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + UNDIFFERENCE_1D(INITIAL_PREDICTOR2); +} + +METHODDEF(void) +jpeg_undifference2(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + UNDIFFERENCE_2D(PREDICTOR2); +} + +METHODDEF(void) +jpeg_undifference3(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + UNDIFFERENCE_2D(PREDICTOR3); +} + +METHODDEF(void) +jpeg_undifference4(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + UNDIFFERENCE_2D(PREDICTOR4); +} + +METHODDEF(void) +jpeg_undifference5(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + UNDIFFERENCE_2D(PREDICTOR5); +} + +METHODDEF(void) +jpeg_undifference6(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + UNDIFFERENCE_2D(PREDICTOR6); +} + +METHODDEF(void) +jpeg_undifference7(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + SHIFT_TEMPS + UNDIFFERENCE_2D(PREDICTOR7); +} + + +/* + * Undifferencer for the first row in a scan or restart interval. The first + * sample in the row is undifferenced using the special predictor constant + * x=2^(P-Pt-1). The rest of the samples are undifferenced using the + * 1-D horizontal predictor (1). + */ + +METHODDEF(void) +jpeg_undifference_first_row(j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + + UNDIFFERENCE_1D(INITIAL_PREDICTORx); + + /* + * Now that we have undifferenced the first row, we want to use the + * undifferencer which corresponds to the predictor specified in the + * scan header. + */ + switch (cinfo->Ss) { + case 1: + losslsd->predict_undifference[comp_index] = jpeg_undifference1; + break; + case 2: + losslsd->predict_undifference[comp_index] = jpeg_undifference2; + break; + case 3: + losslsd->predict_undifference[comp_index] = jpeg_undifference3; + break; + case 4: + losslsd->predict_undifference[comp_index] = jpeg_undifference4; + break; + case 5: + losslsd->predict_undifference[comp_index] = jpeg_undifference5; + break; + case 6: + losslsd->predict_undifference[comp_index] = jpeg_undifference6; + break; + case 7: + losslsd->predict_undifference[comp_index] = jpeg_undifference7; + break; + } +} + + +/* + * Initialize for an input processing pass. + */ + +METHODDEF(void) +predict_start_pass (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + int ci; + + /* Check that the scan parameters Ss, Se, Ah, Al are OK for lossless JPEG. + * + * Ss is the predictor selection value (psv). Legal values for sequential + * lossless JPEG are: 1 <= psv <= 7. + * + * Se and Ah are not used and should be zero. + * + * Al specifies the point transform (Pt). Legal values are: 0 <= Pt <= 15. + */ + if (cinfo->Ss < 1 || cinfo->Ss > 7 || + cinfo->Se != 0 || cinfo->Ah != 0 || + cinfo->Al > 15) /* need not check for < 0 */ + ERREXIT4(cinfo, JERR_BAD_LOSSLESS, + cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al); + + /* Set undifference functions to first row function */ + for (ci = 0; ci < cinfo->num_components; ci++) + losslsd->predict_undifference[ci] = jpeg_undifference_first_row; +} + + +/* + * Module initialization routine for the undifferencer. + */ + +GLOBAL(void) +jinit_undifferencer (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + + losslsd->predict_start_pass = predict_start_pass; + losslsd->predict_process_restart = predict_start_pass; +} + +#endif /* D_LOSSLESS_SUPPORTED */ + diff --git a/src/jpeg/libijg/jdsample.c b/src/jpeg/libijg/jdsample.c index f42cc333..738e19c3 100644 --- a/src/jpeg/libijg/jdsample.c +++ b/src/jpeg/libijg/jdsample.c @@ -1,14 +1,14 @@ /* * jdsample.c * - * Copyright (C) 1991-1996, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * * This file contains upsampling routines. * * Upsampling input data is counted in "row groups". A row group - * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size) + * is defined to be (v_samp_factor * codec_data_unit / min_codec_data_unit) * sample rows of each component. Upsampling will normally produce * max_v_samp_factor pixel rows from each row group (but this could vary * if the upsampler is applying a scale factor of its own). @@ -97,7 +97,6 @@ sep_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr; JDIMENSION num_rows; - in_row_groups_avail = 0; /* Fill the conversion buffer, if it's empty */ if (upsample->next_row_out >= cinfo->max_v_samp_factor) { for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components; @@ -158,8 +157,6 @@ METHODDEF(void) fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { - cinfo = 0; - compptr = 0; *output_data_ptr = input_data; } @@ -173,9 +170,6 @@ METHODDEF(void) noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr) { - cinfo = 0; - compptr = 0; - input_data = 0; *output_data_ptr = NULL; /* safety check */ } @@ -245,7 +239,6 @@ h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outend; int inrow; - compptr = 0; for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) { inptr = input_data[inrow]; outptr = output_data[inrow]; @@ -274,7 +267,6 @@ h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outend; int inrow, outrow; - compptr = 0; inrow = outrow = 0; while (outrow < cinfo->max_v_samp_factor) { inptr = input_data[inrow]; @@ -423,10 +415,10 @@ jinit_upsampler (j_decompress_ptr cinfo) if (cinfo->CCIR601_sampling) /* this isn't supported */ ERREXIT(cinfo, JERR_CCIR601_NOTIMPL); - /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1, + /* jdmainct.c doesn't support context rows when min_codec_data_unit = 1, * so don't ask for it. */ - do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1; + do_fancy = cinfo->do_fancy_upsampling && cinfo->min_codec_data_unit > 1; /* Verify we can handle the sampling factors, select per-component methods, * and create storage as needed. @@ -436,10 +428,10 @@ jinit_upsampler (j_decompress_ptr cinfo) /* Compute size of an "input group" after IDCT scaling. This many samples * are to be converted to max_h_samp_factor * max_v_samp_factor pixels. */ - h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; - v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) / - cinfo->min_DCT_scaled_size; + h_in_group = (compptr->h_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; + v_in_group = (compptr->v_samp_factor * compptr->codec_data_unit) / + cinfo->min_codec_data_unit; h_out_group = cinfo->max_h_samp_factor; v_out_group = cinfo->max_v_samp_factor; upsample->rowgroup_height[ci] = v_in_group; /* save for use later */ diff --git a/src/jpeg/libijg/jdscale.c b/src/jpeg/libijg/jdscale.c new file mode 100644 index 00000000..b546b19d --- /dev/null +++ b/src/jpeg/libijg/jdscale.c @@ -0,0 +1,119 @@ +/* + * jdscale.c + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains sample scaling for lossless JPEG. This is a + * combination of upscaling the undifferenced sample by 2^Pt and downscaling + * the sample to fit into JSAMPLE. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossls.h" /* Private declarations for lossless codec */ + + +#ifdef D_LOSSLESS_SUPPORTED + +/* + * Private scaler object for lossless decoding. + */ + +typedef struct { + int scale_factor; +} scaler; + +typedef scaler * scaler_ptr; + + +/* + * Scalers for packing sample differences into JSAMPLEs. + */ + +METHODDEF(void) +simple_upscale(j_decompress_ptr cinfo, + JDIFFROW diff_buf, JSAMPROW output_buf, + JDIMENSION width) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private; + int scale_factor = scaler->scale_factor; + unsigned int xindex; + + for (xindex = 0; xindex < width; xindex++) + output_buf[xindex] = (JSAMPLE) (diff_buf[xindex] << scale_factor); +} + +METHODDEF(void) +simple_downscale(j_decompress_ptr cinfo, + JDIFFROW diff_buf, JSAMPROW output_buf, + JDIMENSION width) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private; + int scale_factor = scaler->scale_factor; + unsigned int xindex; + SHIFT_TEMPS + + for (xindex = 0; xindex < width; xindex++) + output_buf[xindex] = (JSAMPLE) RIGHT_SHIFT(diff_buf[xindex], scale_factor); +} + +METHODDEF(void) +noscale(j_decompress_ptr cinfo, + JDIFFROW diff_buf, JSAMPROW output_buf, + JDIMENSION width) +{ + unsigned int xindex; + + for (xindex = 0; xindex < width; xindex++) + output_buf[xindex] = (JSAMPLE) diff_buf[xindex]; +} + + +METHODDEF(void) +scaler_start_pass (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + scaler_ptr scaler = (scaler_ptr) losslsd->scaler_private; + int downscale; + + /* + * Downscale by the difference in the input vs. output precision. If the + * output precision >= input precision, then do not downscale. + */ + downscale = BITS_IN_JSAMPLE < cinfo->data_precision ? + cinfo->data_precision - BITS_IN_JSAMPLE : 0; + + scaler->scale_factor = cinfo->Al - downscale; + + /* Set scaler functions based on scale_factor (positive = left shift) */ + if (scaler->scale_factor > 0) + losslsd->scaler_scale = simple_upscale; + else if (scaler->scale_factor < 0) { + scaler->scale_factor = -scaler->scale_factor; + losslsd->scaler_scale = simple_downscale; + } + else + losslsd->scaler_scale = noscale; +} + + +GLOBAL(void) +jinit_d_scaler (j_decompress_ptr cinfo) +{ + j_lossless_d_ptr losslsd = (j_lossless_d_ptr) cinfo->codec; + scaler_ptr scaler; + + scaler = (scaler_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(scaler)); + losslsd->scaler_private = (void *) scaler; + losslsd->scaler_start_pass = scaler_start_pass; +} + +#endif /* D_LOSSLESS_SUPPORTED */ + diff --git a/src/jpeg/libijg/jdshuff.c b/src/jpeg/libijg/jdshuff.c new file mode 100644 index 00000000..326220c4 --- /dev/null +++ b/src/jpeg/libijg/jdshuff.c @@ -0,0 +1,360 @@ +/* + * jdshuff.c + * + * Copyright (C) 1991-1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains Huffman entropy decoding routines for sequential JPEG. + * + * Much of the complexity here has to do with supporting input suspension. + * If the data source module demands suspension, we want to be able to back + * up to the start of the current MCU. To do this, we copy state variables + * into local working storage, and update them back to the permanent + * storage only upon successful completion of an MCU. + */ + +#define JPEG_INTERNALS +#include "jinclude.h" +#include "jpeglib.h" +#include "jlossy.h" /* Private declarations for lossy codec */ +#include "jdhuff.h" /* Declarations shared with jd*huff.c */ + + +/* + * Private entropy decoder object for Huffman decoding. + * + * The savable_state subrecord contains fields that change within an MCU, + * but must not be updated permanently until we complete the MCU. + */ + +typedef struct { + int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */ +} savable_state; + +/* This macro is to work around compilers with missing or broken + * structure assignment. You'll need to fix this code if you have + * such a compiler and you change MAX_COMPS_IN_SCAN. + */ + +#ifndef NO_STRUCT_ASSIGN +#define ASSIGN_STATE(dest,src) ((dest) = (src)) +#else +#if MAX_COMPS_IN_SCAN == 4 +#define ASSIGN_STATE(dest,src) \ + ((dest).last_dc_val[0] = (src).last_dc_val[0], \ + (dest).last_dc_val[1] = (src).last_dc_val[1], \ + (dest).last_dc_val[2] = (src).last_dc_val[2], \ + (dest).last_dc_val[3] = (src).last_dc_val[3]) +#endif +#endif + + +typedef struct { + huffd_common_fields; /* Fields shared with other entropy decoders */ + + /* These fields are loaded into local variables at start of each MCU. + * In case of suspension, we exit WITHOUT updating them. + */ + savable_state saved; /* Other state at start of MCU */ + + /* These fields are NOT loaded into local working state. */ + unsigned int restarts_to_go; /* MCUs left in this restart interval */ + + /* Pointers to derived tables (these workspaces have image lifespan) */ + d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS]; + d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS]; + + /* Precalculated info set up by start_pass for use in decode_mcu: */ + + /* Pointers to derived tables to be used for each block within an MCU */ + d_derived_tbl * dc_cur_tbls[D_MAX_DATA_UNITS_IN_MCU]; + d_derived_tbl * ac_cur_tbls[D_MAX_DATA_UNITS_IN_MCU]; + /* Whether we care about the DC and AC coefficient values for each block */ + boolean dc_needed[D_MAX_DATA_UNITS_IN_MCU]; + boolean ac_needed[D_MAX_DATA_UNITS_IN_MCU]; +} shuff_entropy_decoder; + +typedef shuff_entropy_decoder * shuff_entropy_ptr; + + +/* + * Initialize for a Huffman-compressed scan. + */ + +METHODDEF(void) +start_pass_huff_decoder (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyd->entropy_private; + int ci, blkn, dctbl, actbl; + jpeg_component_info * compptr; + + /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG. + * This ought to be an error condition, but we make it a warning because + * there are some baseline files out there with all zeroes in these bytes. + */ + if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 || + cinfo->Ah != 0 || cinfo->Al != 0) + WARNMS(cinfo, JWRN_NOT_SEQUENTIAL); + + for (ci = 0; ci < cinfo->comps_in_scan; ci++) { + compptr = cinfo->cur_comp_info[ci]; + dctbl = compptr->dc_tbl_no; + actbl = compptr->ac_tbl_no; + /* Compute derived values for Huffman tables */ + /* We may do this more than once for a table, but it's not expensive */ + jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl, + & entropy->dc_derived_tbls[dctbl]); + jpeg_make_d_derived_tbl(cinfo, FALSE, actbl, + & entropy->ac_derived_tbls[actbl]); + /* Initialize DC predictions to 0 */ + entropy->saved.last_dc_val[ci] = 0; + } + + /* Precalculate decoding info for each block in an MCU of this scan */ + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { + ci = cinfo->MCU_membership[blkn]; + compptr = cinfo->cur_comp_info[ci]; + /* Precalculate which table to use for each block */ + entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no]; + entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no]; + /* Decide whether we really care about the coefficient values */ + if (compptr->component_needed) { + entropy->dc_needed[blkn] = TRUE; + /* we don't need the ACs if producing a 1/8th-size image */ + entropy->ac_needed[blkn] = (compptr->codec_data_unit > 1); + } else { + entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE; + } + } + + /* Initialize bitread state variables */ + entropy->bitstate.bits_left = 0; + entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */ + entropy->insufficient_data = FALSE; + + /* Initialize restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; +} + + +/* + * Figure F.12: extend sign bit. + * On some machines, a shift and add will be faster than a table lookup. + */ + +#ifdef AVOID_TABLES + +#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x)) + +#else + +#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x)) + +static const int extend_test[16] = /* entry n is 2**(n-1) */ + { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, + 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 }; + +static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */ + { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, + ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, + ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, + ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 }; + +#endif /* AVOID_TABLES */ + + +/* + * Check for a restart marker & resynchronize decoder. + * Returns FALSE if must suspend. + */ + +LOCAL(boolean) +process_restart (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyd->entropy_private; + int ci; + + /* Throw away any unused bits remaining in bit buffer; */ + /* include any full bytes in next_marker's count of discarded bytes */ + cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8; + entropy->bitstate.bits_left = 0; + + /* Advance past the RSTn marker */ + if (! (*cinfo->marker->read_restart_marker) (cinfo)) + return FALSE; + + /* Re-initialize DC predictions to 0 */ + for (ci = 0; ci < cinfo->comps_in_scan; ci++) + entropy->saved.last_dc_val[ci] = 0; + + /* Reset restart counter */ + entropy->restarts_to_go = cinfo->restart_interval; + + /* Reset out-of-data flag, unless read_restart_marker left us smack up + * against a marker. In that case we will end up treating the next data + * segment as empty, and we can avoid producing bogus output pixels by + * leaving the flag set. + */ + if (cinfo->unread_marker == 0) + entropy->insufficient_data = FALSE; + + return TRUE; +} + + +/* + * Decode and return one MCU's worth of Huffman-compressed coefficients. + * The coefficients are reordered from zigzag order into natural array order, + * but are not dequantized. + * + * The i'th block of the MCU is stored into the block pointed to by + * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER. + * (Wholesale zeroing is usually a little faster than retail...) + * + * Returns FALSE if data source requested suspension. In that case no + * changes have been made to permanent state. (Exception: some output + * coefficients may already have been assigned. This is harmless for + * this module, since we'll just re-assign them on the next call.) + */ + +METHODDEF(boolean) +decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + shuff_entropy_ptr entropy = (shuff_entropy_ptr) lossyd->entropy_private; + int blkn; + BITREAD_STATE_VARS; + savable_state state; + + /* Process restart marker if needed; may have to suspend */ + if (cinfo->restart_interval) { + if (entropy->restarts_to_go == 0) + if (! process_restart(cinfo)) + return FALSE; + } + + /* If we've run out of data, just leave the MCU set to zeroes. + * This way, we return uniform gray for the remainder of the segment. + */ + if (! entropy->insufficient_data) { + + /* Load up working state */ + BITREAD_LOAD_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(state, entropy->saved); + + /* Outer loop handles each block in the MCU */ + + for (blkn = 0; blkn < cinfo->data_units_in_MCU; blkn++) { + JBLOCKROW block = MCU_data[blkn]; + d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn]; + d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn]; + register int s, k, r; + + /* Decode a single block's worth of coefficients */ + + /* Section F.2.2.1: decode the DC coefficient difference */ + HUFF_DECODE(s, br_state, dctbl, return FALSE, label1); + if (s) { + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + } + + if (entropy->dc_needed[blkn]) { + /* Convert DC difference to actual value, update last_dc_val */ + int ci = cinfo->MCU_membership[blkn]; + s += state.last_dc_val[ci]; + state.last_dc_val[ci] = s; + /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */ + (*block)[0] = (JCOEF) s; + } + + if (entropy->ac_needed[blkn]) { + + /* Section F.2.2.2: decode the AC coefficients */ + /* Since zeroes are skipped, output area must be cleared beforehand */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label2); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + r = GET_BITS(s); + s = HUFF_EXTEND(r, s); + /* Output coefficient in natural (dezigzagged) order. + * Note: the extra entries in jpeg_natural_order[] will save us + * if k >= DCTSIZE2, which could happen if the data is corrupted. + */ + (*block)[jpeg_natural_order[k]] = (JCOEF) s; + } else { + if (r != 15) + break; + k += 15; + } + } + + } else { + + /* Section F.2.2.2: decode the AC coefficients */ + /* In this path we just discard the values */ + for (k = 1; k < DCTSIZE2; k++) { + HUFF_DECODE(s, br_state, actbl, return FALSE, label3); + + r = s >> 4; + s &= 15; + + if (s) { + k += r; + CHECK_BIT_BUFFER(br_state, s, return FALSE); + DROP_BITS(s); + } else { + if (r != 15) + break; + k += 15; + } + } + + } + } + + /* Completed MCU, so update state */ + BITREAD_SAVE_STATE(cinfo,entropy->bitstate); + ASSIGN_STATE(entropy->saved, state); + } + + /* Account for restart interval (no-op if not using restarts) */ + entropy->restarts_to_go--; + + return TRUE; +} + + +/* + * Module initialization routine for Huffman entropy decoding. + */ + +GLOBAL(void) +jinit_shuff_decoder (j_decompress_ptr cinfo) +{ + j_lossy_d_ptr lossyd = (j_lossy_d_ptr) cinfo->codec; + shuff_entropy_ptr entropy; + int i; + + entropy = (shuff_entropy_ptr) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, + SIZEOF(shuff_entropy_decoder)); + lossyd->entropy_private = (void *) entropy; + lossyd->entropy_start_pass = start_pass_huff_decoder; + lossyd->entropy_decode_mcu = decode_mcu; + + /* Mark tables unallocated */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL; + } +} diff --git a/src/jpeg/libijg/jdtrans.c b/src/jpeg/libijg/jdtrans.c index 6c0ab715..af35263c 100644 --- a/src/jpeg/libijg/jdtrans.c +++ b/src/jpeg/libijg/jdtrans.c @@ -1,7 +1,7 @@ /* * jdtrans.c * - * Copyright (C) 1995-1997, Thomas G. Lane. + * Copyright (C) 1995-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -13,6 +13,7 @@ #define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" +#include "jlossy.h" /* Forward declarations */ @@ -44,6 +45,14 @@ LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo)); GLOBAL(jvirt_barray_ptr *) jpeg_read_coefficients (j_decompress_ptr cinfo) { + /* j_lossy_d_ptr decomp; */ + + /* Can't read coefficients from lossless streams */ + if (cinfo->process == JPROC_LOSSLESS) { + ERREXIT(cinfo, JERR_CANT_TRANSCODE); + return NULL; + } + if (cinfo->global_state == DSTATE_READY) { /* First call: initialize active modules */ transdecode_master_selection(cinfo); @@ -55,20 +64,20 @@ jpeg_read_coefficients (j_decompress_ptr cinfo) int retcode; /* Call progress monitor hook if present */ if (cinfo->progress != NULL) - (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); + (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo); /* Absorb some more input */ retcode = (*cinfo->inputctl->consume_input) (cinfo); if (retcode == JPEG_SUSPENDED) - return NULL; + return NULL; if (retcode == JPEG_REACHED_EOI) - break; + break; /* Advance progress counter if appropriate */ if (cinfo->progress != NULL && - (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { - if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { - /* startup underestimated number of scans; ratchet up one scan */ - cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; - } + (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) { + if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) { + /* startup underestimated number of scans; ratchet up one scan */ + cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows; + } } } /* Set state so that jpeg_finish_decompress does the right thing */ @@ -80,11 +89,11 @@ jpeg_read_coefficients (j_decompress_ptr cinfo) */ if ((cinfo->global_state == DSTATE_STOPPING || cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) { - return cinfo->coef->coef_arrays; + return ((j_lossy_d_ptr) cinfo->codec)->coef_arrays; } /* Oops, improper usage */ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); - return NULL; /* keep compiler happy */ + return NULL; /* keep compiler happy */ } @@ -99,22 +108,8 @@ transdecode_master_selection (j_decompress_ptr cinfo) /* This is effectively a buffered-image operation. */ cinfo->buffered_image = TRUE; - /* Entropy decoding: either Huffman or arithmetic coding. */ - if (cinfo->arith_code) { - ERREXIT(cinfo, JERR_ARITH_NOTIMPL); - } else { - if (cinfo->progressive_mode) { -#ifdef D_PROGRESSIVE_SUPPORTED - jinit_phuff_decoder(cinfo); -#else - ERREXIT(cinfo, JERR_NOT_COMPILED); -#endif - } else - jinit_huff_decoder(cinfo); - } - - /* Always get a full-image coefficient buffer. */ - jinit_d_coef_controller(cinfo, TRUE); + /* Initialize decompression codec */ + jinit_d_codec(cinfo); /* We can now tell the memory manager to allocate virtual arrays. */ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); @@ -126,7 +121,7 @@ transdecode_master_selection (j_decompress_ptr cinfo) if (cinfo->progress != NULL) { int nscans; /* Estimate number of scans to set pass_limit. */ - if (cinfo->progressive_mode) { + if (cinfo->process == JPROC_PROGRESSIVE) { /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */ nscans = 2 + 3 * cinfo->num_components; } else if (cinfo->inputctl->has_multiple_scans) { diff --git a/src/jpeg/libijg/jerror.c b/src/jpeg/libijg/jerror.c index 3da7be86..4e6e2e35 100644 --- a/src/jpeg/libijg/jerror.c +++ b/src/jpeg/libijg/jerror.c @@ -28,7 +28,7 @@ #include #endif -#ifndef EXIT_FAILURE /* define exit() codes if not provided */ +#ifndef EXIT_FAILURE /* define exit() codes if not provided */ #define EXIT_FAILURE 1 #endif @@ -42,10 +42,10 @@ */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_message_table jMsgTable +#define jpeg_std_message_table jMsgTable #endif -#define JMESSAGE(code,string) string , +#define JMESSAGE(code,string) string , const char * const jpeg_std_message_table[] = { #include "jerror.h" @@ -105,7 +105,7 @@ output_message (j_common_ptr cinfo) #ifdef USE_WINDOWS_MESSAGEBOX /* Display it in a message dialog box */ MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", - MB_OK | MB_ICONERROR); + MB_OK | MB_ICONERROR); #else /* Send it to stderr, adding a newline */ fprintf(stderr, "%s\n", buffer); @@ -167,8 +167,8 @@ format_message (j_common_ptr cinfo, char * buffer) if (msg_code > 0 && msg_code <= err->last_jpeg_message) { msgtext = err->jpeg_message_table[msg_code]; } else if (err->addon_message_table != NULL && - msg_code >= err->first_addon_message && - msg_code <= err->last_addon_message) { + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { msgtext = err->addon_message_table[msg_code - err->first_addon_message]; } @@ -193,10 +193,10 @@ format_message (j_common_ptr cinfo, char * buffer) sprintf(buffer, msgtext, err->msg_parm.s); else sprintf(buffer, msgtext, - err->msg_parm.i[0], err->msg_parm.i[1], - err->msg_parm.i[2], err->msg_parm.i[3], - err->msg_parm.i[4], err->msg_parm.i[5], - err->msg_parm.i[6], err->msg_parm.i[7]); + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); } @@ -213,17 +213,17 @@ reset_error_mgr (j_common_ptr cinfo) { cinfo->err->num_warnings = 0; /* trace_level is not reset since it is an application-supplied parameter */ - cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ } /* * Fill in the standard error-handling methods in a jpeg_error_mgr object. * Typical call is: - * struct jpeg_compress_struct cinfo; - * struct jpeg_error_mgr err; + * struct jpeg_compress_struct cinfo; + * struct jpeg_error_mgr err; * - * cinfo.err = jpeg_std_error(&err); + * cinfo.err = jpeg_std_error(&err); * after which the application may override some of the methods. */ @@ -236,16 +236,16 @@ jpeg_std_error (struct jpeg_error_mgr * err) err->format_message = format_message; err->reset_error_mgr = reset_error_mgr; - err->trace_level = 0; /* default = no tracing */ - err->num_warnings = 0; /* no warnings emitted yet */ - err->msg_code = 0; /* may be useful as a flag for "no error" */ + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ /* Initialize message table pointers */ err->jpeg_message_table = jpeg_std_message_table; err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; err->addon_message_table = NULL; - err->first_addon_message = 0; /* for safety */ + err->first_addon_message = 0; /* for safety */ err->last_addon_message = 0; return err; diff --git a/src/jpeg/libijg/jerror.h b/src/jpeg/libijg/jerror.h index fc2fffea..d48ccfad 100644 --- a/src/jpeg/libijg/jerror.h +++ b/src/jpeg/libijg/jerror.h @@ -1,7 +1,7 @@ /* * jerror.h * - * Copyright (C) 1994-1997, Thomas G. Lane. + * Copyright (C) 1994-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -32,7 +32,7 @@ typedef enum { -#define JMESSAGE(code,string) code , +#define JMESSAGE(code,string) code , #endif /* JMAKE_ENUM_LIST */ @@ -40,34 +40,42 @@ JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */ /* For maintenance convenience, list is alphabetical by message code name */ JMESSAGE(JERR_ARITH_NOTIMPL, - "Sorry, there are legal restrictions on arithmetic coding") + "Sorry, there are legal restrictions on arithmetic coding") JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix") JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix") JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode") JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS") JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range") JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported") +JMESSAGE(JERR_BAD_DIFF, "spatial difference out of range") JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition") JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace") JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace") JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length") JMESSAGE(JERR_BAD_LIB_VERSION, - "Wrong JPEG library version: library is %d, caller expects %d") + "Wrong JPEG library version: library is %d, caller expects %d") +JMESSAGE(JERR_BAD_LOSSLESS, + "Invalid lossless parameters Ss=%d Se=%d Ah=%d Al=%d") +JMESSAGE(JERR_BAD_LOSSLESS_SCRIPT, + "Invalid lossless parameters at scan script entry %d") JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan") JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d") JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d") JMESSAGE(JERR_BAD_PROGRESSION, - "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") + "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d") JMESSAGE(JERR_BAD_PROG_SCRIPT, - "Invalid progressive parameters at scan script entry %d") + "Invalid progressive parameters at scan script entry %d") +JMESSAGE(JERR_BAD_RESTART, "Invalid restart interval: %d, must be an integer multiple of the number of MCUs in an MCU_row (%d)") JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors") JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d") JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d") JMESSAGE(JERR_BAD_STRUCT_SIZE, - "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") + "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u") JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access") JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small") JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here") +JMESSAGE(JERR_CANT_TRANSCODE, + "Cannot transcode to/from lossless JPEG datastreams") JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet") JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d") JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request") @@ -88,19 +96,21 @@ JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels") JMESSAGE(JERR_INPUT_EMPTY, "Empty input file") JMESSAGE(JERR_INPUT_EOF, "Premature end of input file") JMESSAGE(JERR_MISMATCHED_QUANT_TABLE, - "Cannot transcode due to multiple use of quantization table %d") + "Cannot transcode due to multiple use of quantization table %d") JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data") JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change") JMESSAGE(JERR_NOTIMPL, "Not implemented yet") JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") +JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") +JMESSAGE(JERR_NO_LOSSLESS_SCRIPT, "Lossless encoding was requested but no scan script was supplied") JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x") JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)") JMESSAGE(JERR_QUANT_COMPONENTS, - "Cannot quantize more than %d color components") + "Cannot quantize more than %d color components") JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors") JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers") @@ -112,7 +122,7 @@ JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s") JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") JMESSAGE(JERR_TFILE_WRITE, - "Write failed on temporary file --- out of disk space?") + "Write failed on temporary file --- out of disk space?") JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines") JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x") JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up") @@ -122,9 +132,9 @@ JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed") JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT) JMESSAGE(JMSG_VERSION, JVERSION) JMESSAGE(JTRC_16BIT_TABLES, - "Caution: quantization tables are too coarse for baseline JPEG") + "Caution: quantization tables are too coarse for baseline JPEG") JMESSAGE(JTRC_ADOBE, - "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") + "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d") JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u") JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u") JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x") @@ -137,9 +147,9 @@ JMESSAGE(JTRC_EOI, "End Of Image") JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d") JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d") JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE, - "Warning: thumbnail image size does not match data length %u") + "Warning: thumbnail image size does not match data length %u") JMESSAGE(JTRC_JFIF_EXTENSION, - "JFIF extension marker: type 0x%02x, length %u") + "JFIF extension marker: type 0x%02x, length %u") JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image") JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u") JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x") @@ -150,7 +160,7 @@ JMESSAGE(JTRC_QUANT_SELECTED, "Selected %d colors for quantization") JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d") JMESSAGE(JTRC_RST, "RST%d") JMESSAGE(JTRC_SMOOTH_NOTIMPL, - "Smoothing not supported with nonstandard sampling ratios") + "Smoothing not supported with nonstandard sampling ratios") JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d") JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d") JMESSAGE(JTRC_SOI, "Start of Image") @@ -160,26 +170,31 @@ JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d") JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s") JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s") JMESSAGE(JTRC_THUMB_JPEG, - "JFIF extension marker: JPEG-compressed thumbnail image, length %u") + "JFIF extension marker: JPEG-compressed thumbnail image, length %u") JMESSAGE(JTRC_THUMB_PALETTE, - "JFIF extension marker: palette thumbnail image, length %u") + "JFIF extension marker: palette thumbnail image, length %u") JMESSAGE(JTRC_THUMB_RGB, - "JFIF extension marker: RGB thumbnail image, length %u") -JMESSAGE(JTRC_UNKNOWN_IDS, - "Unrecognized component IDs %d %d %d, assuming YCbCr") + "JFIF extension marker: RGB thumbnail image, length %u") +JMESSAGE(JTRC_UNKNOWN_LOSSLESS_IDS, + "Unrecognized component IDs %d %d %d, assuming RGB") +JMESSAGE(JTRC_UNKNOWN_LOSSY_IDS, + "Unrecognized component IDs %d %d %d, assuming YCbCr") JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u") JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u") JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d") +JMESSAGE(JWRN_ARITH_BAD_CODE, "Corrupt JPEG data: bad arithmetic code") JMESSAGE(JWRN_BOGUS_PROGRESSION, - "Inconsistent progression sequence for component %d coefficient %d") + "Inconsistent progression sequence for component %d coefficient %d") JMESSAGE(JWRN_EXTRANEOUS_DATA, - "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") + "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x") JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment") JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code") JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d") JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file") +JMESSAGE(JWRN_MUST_DOWNSCALE, + "Must downscale data from %d bits to %d") JMESSAGE(JWRN_MUST_RESYNC, - "Corrupt JPEG data: found marker 0x%02x instead of RST%d") + "Corrupt JPEG data: found marker 0x%02x instead of RST%d") JMESSAGE(JWRN_NOT_SEQUENTIAL, "Invalid SOS parameters for sequential JPEG") JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") @@ -232,7 +247,7 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo))) -#define MAKESTMT(stuff) do { stuff } while (0) +#define MAKESTMT(stuff) do { stuff } while (0) /* Nonfatal errors (we can keep going, but the data is probably corrupt) */ #define WARNMS(cinfo,code) \ @@ -263,26 +278,26 @@ JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines") (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl))) #define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) #define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) #define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) #define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \ - _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ - _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ - (cinfo)->err->msg_code = (code); \ - (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) + _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \ + _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \ + (cinfo)->err->msg_code = (code); \ + (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); ) #define TRACEMSS(cinfo,lvl,code,str) \ ((cinfo)->err->msg_code = (code), \ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \ diff --git a/src/jpeg/libijg/jfdctflt.c b/src/jpeg/libijg/jfdctflt.c index 79d7a007..f0297a25 100644 --- a/src/jpeg/libijg/jfdctflt.c +++ b/src/jpeg/libijg/jfdctflt.c @@ -37,7 +37,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 */ #ifdef DCT_FLOAT_SUPPORTED @@ -79,7 +79,7 @@ jpeg_fdct_float (FAST_FLOAT * data) /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; @@ -88,12 +88,12 @@ jpeg_fdct_float (FAST_FLOAT * data) dataptr[4] = tmp10 - tmp11; z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */ - dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ dataptr[6] = tmp13 - z1; /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; @@ -103,15 +103,15 @@ jpeg_fdct_float (FAST_FLOAT * data) z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ - z11 = tmp7 + z3; /* phase 5 */ + z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3; - dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[5] = z13 + z2; /* phase 6 */ dataptr[3] = z13 - z2; dataptr[1] = z11 + z4; dataptr[7] = z11 - z4; - dataptr += DCTSIZE; /* advance pointer to next row */ + dataptr += DCTSIZE; /* advance pointer to next row */ } /* Pass 2: process columns. */ @@ -129,7 +129,7 @@ jpeg_fdct_float (FAST_FLOAT * data) /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; @@ -143,7 +143,7 @@ jpeg_fdct_float (FAST_FLOAT * data) /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; @@ -153,7 +153,7 @@ jpeg_fdct_float (FAST_FLOAT * data) z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */ - z11 = tmp7 + z3; /* phase 5 */ + z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3; dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ @@ -161,7 +161,7 @@ jpeg_fdct_float (FAST_FLOAT * data) dataptr[DCTSIZE*1] = z11 + z4; dataptr[DCTSIZE*7] = z11 - z4; - dataptr++; /* advance pointer to next column */ + dataptr++; /* advance pointer to next column */ } } diff --git a/src/jpeg/libijg/jfdctfst.c b/src/jpeg/libijg/jfdctfst.c index ccb378a3..5d51e3c1 100644 --- a/src/jpeg/libijg/jfdctfst.c +++ b/src/jpeg/libijg/jfdctfst.c @@ -33,7 +33,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 */ #ifdef DCT_IFAST_SUPPORTED @@ -76,10 +76,10 @@ */ #if CONST_BITS == 8 -#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ -#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ -#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ -#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ +#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */ +#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */ +#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */ +#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */ #else #define FIX_0_382683433 FIX(0.382683433) #define FIX_0_541196100 FIX(0.541196100) @@ -135,7 +135,7 @@ jpeg_fdct_ifast (DCTELEM * data) /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; @@ -144,12 +144,12 @@ jpeg_fdct_ifast (DCTELEM * data) dataptr[4] = tmp10 - tmp11; z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */ - dataptr[2] = tmp13 + z1; /* phase 5 */ + dataptr[2] = tmp13 + z1; /* phase 5 */ dataptr[6] = tmp13 - z1; /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; @@ -159,15 +159,15 @@ jpeg_fdct_ifast (DCTELEM * data) z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - z11 = tmp7 + z3; /* phase 5 */ + z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3; - dataptr[5] = z13 + z2; /* phase 6 */ + dataptr[5] = z13 + z2; /* phase 6 */ dataptr[3] = z13 - z2; dataptr[1] = z11 + z4; dataptr[7] = z11 - z4; - dataptr += DCTSIZE; /* advance pointer to next row */ + dataptr += DCTSIZE; /* advance pointer to next row */ } /* Pass 2: process columns. */ @@ -185,7 +185,7 @@ jpeg_fdct_ifast (DCTELEM * data) /* Even part */ - tmp10 = tmp0 + tmp3; /* phase 2 */ + tmp10 = tmp0 + tmp3; /* phase 2 */ tmp13 = tmp0 - tmp3; tmp11 = tmp1 + tmp2; tmp12 = tmp1 - tmp2; @@ -199,7 +199,7 @@ jpeg_fdct_ifast (DCTELEM * data) /* Odd part */ - tmp10 = tmp4 + tmp5; /* phase 2 */ + tmp10 = tmp4 + tmp5; /* phase 2 */ tmp11 = tmp5 + tmp6; tmp12 = tmp6 + tmp7; @@ -209,7 +209,7 @@ jpeg_fdct_ifast (DCTELEM * data) z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */ - z11 = tmp7 + z3; /* phase 5 */ + z11 = tmp7 + z3; /* phase 5 */ z13 = tmp7 - z3; dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */ @@ -217,7 +217,7 @@ jpeg_fdct_ifast (DCTELEM * data) dataptr[DCTSIZE*1] = z11 + z4; dataptr[DCTSIZE*7] = z11 - z4; - dataptr++; /* advance pointer to next column */ + dataptr++; /* advance pointer to next column */ } } diff --git a/src/jpeg/libijg/jfdctint.c b/src/jpeg/libijg/jfdctint.c index 0a78b64a..8f6c73db 100644 --- a/src/jpeg/libijg/jfdctint.c +++ b/src/jpeg/libijg/jfdctint.c @@ -26,7 +26,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 */ #ifdef DCT_ISLOW_SUPPORTED @@ -79,7 +79,7 @@ #define PASS1_BITS 2 #else #define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ #endif /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus @@ -90,18 +90,18 @@ */ #if CONST_BITS == 13 -#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ #else #define FIX_0_298631336 FIX(0.298631336) #define FIX_0_390180644 FIX(0.390180644) @@ -175,9 +175,9 @@ jpeg_fdct_islow (DCTELEM * data) z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS-PASS1_BITS); + CONST_BITS-PASS1_BITS); dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS-PASS1_BITS); + CONST_BITS-PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). @@ -207,7 +207,7 @@ jpeg_fdct_islow (DCTELEM * data) dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS); dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS); - dataptr += DCTSIZE; /* advance pointer to next row */ + dataptr += DCTSIZE; /* advance pointer to next row */ } /* Pass 2: process columns. @@ -240,9 +240,9 @@ jpeg_fdct_islow (DCTELEM * data) z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100); dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865), - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065), - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); /* Odd part per figure 8 --- note paper omits factor of sqrt(2). * cK represents cos(K*pi/16). @@ -268,15 +268,15 @@ jpeg_fdct_islow (DCTELEM * data) z4 += z5; dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, - CONST_BITS+PASS1_BITS); + CONST_BITS+PASS1_BITS); - dataptr++; /* advance pointer to next column */ + dataptr++; /* advance pointer to next column */ } } diff --git a/src/jpeg/libijg/jidctflt.c b/src/jpeg/libijg/jidctflt.c index 0188ce3d..0d72de89 100644 --- a/src/jpeg/libijg/jidctflt.c +++ b/src/jpeg/libijg/jidctflt.c @@ -39,7 +39,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 */ #ifdef DCT_FLOAT_SUPPORTED @@ -66,8 +66,8 @@ GLOBAL(void) jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; FAST_FLOAT tmp10, tmp11, tmp12, tmp13; @@ -97,9 +97,9 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, */ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ FAST_FLOAT dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); @@ -112,7 +112,7 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*6] = dcval; wsptr[DCTSIZE*7] = dcval; - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; continue; @@ -125,13 +125,13 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp10 = tmp0 + tmp2; /* phase 3 */ tmp11 = tmp0 - tmp2; - tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp13 = tmp1 + tmp3; /* phases 5-3 */ tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */ - tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp0 = tmp10 + tmp13; /* phase 2 */ tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; @@ -143,19 +143,19 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - z13 = tmp6 + tmp5; /* phase 6 */ + z13 = tmp6 + tmp5; /* phase 6 */ z10 = tmp6 - tmp5; z11 = tmp4 + tmp7; z12 = tmp4 - tmp7; - tmp7 = z11 + z13; /* phase 5 */ + tmp7 = z11 + z13; /* phase 5 */ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */ - tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp6 = tmp12 - tmp7; /* phase 2 */ tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; @@ -168,7 +168,7 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*4] = tmp3 + tmp4; wsptr[DCTSIZE*3] = tmp3 - tmp4; - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; } @@ -219,23 +219,23 @@ jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* Final output stage: scale down by a factor of 8 and range-limit */ outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3) - & RANGE_MASK]; + & RANGE_MASK]; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ } } diff --git a/src/jpeg/libijg/jidctfst.c b/src/jpeg/libijg/jidctfst.c index dba4216f..3245decc 100644 --- a/src/jpeg/libijg/jidctfst.c +++ b/src/jpeg/libijg/jidctfst.c @@ -35,7 +35,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 */ #ifdef DCT_IFAST_SUPPORTED @@ -78,7 +78,7 @@ #define PASS1_BITS 2 #else #define CONST_BITS 8 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ #endif /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus @@ -89,10 +89,10 @@ */ #if CONST_BITS == 8 -#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ -#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ -#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ -#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ +#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */ +#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */ +#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */ +#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */ #else #define FIX_1_082392200 FIX(1.082392200) #define FIX_1_414213562 FIX(1.414213562) @@ -129,7 +129,7 @@ #define DEQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval)) #else #define DEQUANTIZE(coef,quantval) \ - DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) + DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS) #endif @@ -138,11 +138,11 @@ */ #ifdef RIGHT_SHIFT_IS_UNSIGNED -#define ISHIFT_TEMPS DCTELEM ishift_temp; +#define ISHIFT_TEMPS DCTELEM ishift_temp; #if BITS_IN_JSAMPLE == 8 -#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ +#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */ #else -#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ +#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */ #endif #define IRIGHT_SHIFT(x,shft) \ ((ishift_temp = (x)) < 0 ? \ @@ -150,7 +150,7 @@ (ishift_temp >> (shft))) #else #define ISHIFT_TEMPS -#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) +#define IRIGHT_SHIFT(x,shft) ((x) >> (shft)) #endif #ifdef USE_ACCURATE_ROUNDING @@ -166,8 +166,8 @@ GLOBAL(void) jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; DCTELEM tmp10, tmp11, tmp12, tmp13; @@ -178,9 +178,9 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outptr; JSAMPLE *range_limit = IDCT_range_limit(cinfo); int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ - SHIFT_TEMPS /* for DESCALE */ - ISHIFT_TEMPS /* for IDESCALE */ + int workspace[DCTSIZE2]; /* buffers data between passes */ + SHIFT_TEMPS /* for DESCALE */ + ISHIFT_TEMPS /* for IDESCALE */ /* Pass 1: process columns from input, store into work array. */ @@ -198,9 +198,9 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, */ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ int dcval = (int) DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]); @@ -213,7 +213,7 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*6] = dcval; wsptr[DCTSIZE*7] = dcval; - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; continue; @@ -226,13 +226,13 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp2 = DEQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]); tmp3 = DEQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]); - tmp10 = tmp0 + tmp2; /* phase 3 */ + tmp10 = tmp0 + tmp2; /* phase 3 */ tmp11 = tmp0 - tmp2; - tmp13 = tmp1 + tmp3; /* phases 5-3 */ + tmp13 = tmp1 + tmp3; /* phases 5-3 */ tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */ - tmp0 = tmp10 + tmp13; /* phase 2 */ + tmp0 = tmp10 + tmp13; /* phase 2 */ tmp3 = tmp10 - tmp13; tmp1 = tmp11 + tmp12; tmp2 = tmp11 - tmp12; @@ -244,19 +244,19 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp6 = DEQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]); tmp7 = DEQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]); - z13 = tmp6 + tmp5; /* phase 6 */ + z13 = tmp6 + tmp5; /* phase 6 */ z10 = tmp6 - tmp5; z11 = tmp4 + tmp7; z12 = tmp4 - tmp7; - tmp7 = z11 + z13; /* phase 5 */ + tmp7 = z11 + z13; /* phase 5 */ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ - tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp6 = tmp12 - tmp7; /* phase 2 */ tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; @@ -269,7 +269,7 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4); wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4); - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; } @@ -291,10 +291,10 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, #ifndef NO_ZERO_ROW_TEST if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && - wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[0] = dcval; outptr[1] = dcval; @@ -305,7 +305,7 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, outptr[6] = dcval; outptr[7] = dcval; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ continue; } #endif @@ -317,7 +317,7 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]); tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562) - - tmp13; + - tmp13; tmp0 = tmp10 + tmp13; tmp3 = tmp10 - tmp13; @@ -331,37 +331,37 @@ jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr, z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7]; z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7]; - tmp7 = z11 + z13; /* phase 5 */ + tmp7 = z11 + z13; /* phase 5 */ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */ - tmp6 = tmp12 - tmp7; /* phase 2 */ + tmp6 = tmp12 - tmp7; /* phase 2 */ tmp5 = tmp11 - tmp6; tmp4 = tmp10 + tmp5; /* Final output stage: scale down by a factor of 8 and range-limit */ outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ } } diff --git a/src/jpeg/libijg/jidctint.c b/src/jpeg/libijg/jidctint.c index a72b3207..e8a8b7af 100644 --- a/src/jpeg/libijg/jidctint.c +++ b/src/jpeg/libijg/jidctint.c @@ -28,7 +28,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 */ #ifdef DCT_ISLOW_SUPPORTED @@ -79,7 +79,7 @@ #define PASS1_BITS 2 #else #define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ #endif /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus @@ -90,18 +90,18 @@ */ #if CONST_BITS == 13 -#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ -#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ -#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ -#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ -#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ +#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */ +#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */ +#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */ +#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */ +#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */ #else #define FIX_0_298631336 FIX(0.298631336) #define FIX_0_390180644 FIX(0.390180644) @@ -146,8 +146,8 @@ GLOBAL(void) jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { INT32 tmp0, tmp1, tmp2, tmp3; INT32 tmp10, tmp11, tmp12, tmp13; @@ -158,7 +158,7 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outptr; JSAMPLE *range_limit = IDCT_range_limit(cinfo); int ctr; - int workspace[DCTSIZE2]; /* buffers data between passes */ + int workspace[DCTSIZE2]; /* buffers data between passes */ SHIFT_TEMPS /* Pass 1: process columns from input, store into work array. */ @@ -179,9 +179,9 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, */ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && - inptr[DCTSIZE*7] == 0) { + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 && + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 && + inptr[DCTSIZE*7] == 0) { /* AC terms all zero */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -194,7 +194,7 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*6] = dcval; wsptr[DCTSIZE*7] = dcval; - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; continue; @@ -264,7 +264,7 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS); wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS); - inptr++; /* advance pointers to next column */ + inptr++; /* advance pointers to next column */ quantptr++; wsptr++; } @@ -286,10 +286,10 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, #ifndef NO_ZERO_ROW_TEST if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 && - wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[0] = dcval; outptr[1] = dcval; @@ -300,7 +300,7 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, outptr[6] = dcval; outptr[7] = dcval; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ continue; } #endif @@ -358,31 +358,31 @@ jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0, - CONST_BITS+PASS1_BITS+3) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3) + & RANGE_MASK]; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ } } diff --git a/src/jpeg/libijg/jidctred.c b/src/jpeg/libijg/jidctred.c index 421f3c7c..5df040c1 100644 --- a/src/jpeg/libijg/jidctred.c +++ b/src/jpeg/libijg/jidctred.c @@ -23,7 +23,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 */ #ifdef IDCT_SCALING_SUPPORTED @@ -44,7 +44,7 @@ #define PASS1_BITS 2 #else #define CONST_BITS 13 -#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ +#define PASS1_BITS 1 /* lose a little precision to avoid overflow */ #endif /* Some C compilers fail to reduce "FIX(constant)" at compile time, thus @@ -55,20 +55,20 @@ */ #if CONST_BITS == 13 -#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ -#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ -#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ -#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ -#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ -#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ -#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ -#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ -#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ -#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ -#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ -#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ -#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ -#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ +#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */ +#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */ +#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */ +#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */ +#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */ +#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */ +#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */ +#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */ +#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */ +#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */ +#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */ +#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */ +#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */ +#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */ #else #define FIX_0_211164243 FIX(0.211164243) #define FIX_0_509795579 FIX(0.509795579) @@ -116,8 +116,8 @@ GLOBAL(void) jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { INT32 tmp0, tmp2, tmp10, tmp12; INT32 z1, z2, z3, z4; @@ -127,7 +127,7 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outptr; JSAMPLE *range_limit = IDCT_range_limit(cinfo); int ctr; - int workspace[DCTSIZE*4]; /* buffers data between passes */ + int workspace[DCTSIZE*4]; /* buffers data between passes */ SHIFT_TEMPS /* Pass 1: process columns from input, store into work array. */ @@ -140,8 +140,8 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, if (ctr == DCTSIZE-4) continue; if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 && - inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && - inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { + inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 && + inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) { /* AC terms all zero; we need not examine term 4 for 4x4 output */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -174,14 +174,14 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, z4 = DEQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]); tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ - + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ - + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ - + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ - + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ - + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ - + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ /* Final output stage */ @@ -200,17 +200,17 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, #ifndef NO_ZERO_ROW_TEST if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && - wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { + wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[0] = dcval; outptr[1] = dcval; outptr[2] = dcval; outptr[3] = dcval; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ continue; } #endif @@ -220,7 +220,7 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1); tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065) - + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); + + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865); tmp10 = tmp0 + tmp2; tmp12 = tmp0 - tmp2; @@ -233,31 +233,31 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, z4 = (INT32) wsptr[1]; tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */ - + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ - + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ - + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ + + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */ + + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */ + + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */ - + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ - + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ - + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ + + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */ + + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */ + + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */ /* Final output stage */ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0, - CONST_BITS+PASS1_BITS+3+1) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+1) + & RANGE_MASK]; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ } } @@ -269,8 +269,8 @@ jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr, GLOBAL(void) jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { INT32 tmp0, tmp10, z1; JCOEFPTR inptr; @@ -279,7 +279,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, JSAMPROW outptr; JSAMPLE *range_limit = IDCT_range_limit(cinfo); int ctr; - int workspace[DCTSIZE*2]; /* buffers data between passes */ + int workspace[DCTSIZE*2]; /* buffers data between passes */ SHIFT_TEMPS /* Pass 1: process columns from input, store into work array. */ @@ -292,7 +292,7 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6) continue; if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 && - inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { + inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) { /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */ int dcval = DEQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS; @@ -335,12 +335,12 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) { /* AC terms all zero */ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3) - & RANGE_MASK]; + & RANGE_MASK]; outptr[0] = dcval; outptr[1] = dcval; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ continue; } #endif @@ -352,20 +352,20 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, /* Odd part */ tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */ - + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ - + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ - + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */ + + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */ + + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */ /* Final output stage */ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0, - CONST_BITS+PASS1_BITS+3+2) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0, - CONST_BITS+PASS1_BITS+3+2) - & RANGE_MASK]; + CONST_BITS+PASS1_BITS+3+2) + & RANGE_MASK]; - wsptr += DCTSIZE; /* advance pointer to next row */ + wsptr += DCTSIZE; /* advance pointer to next row */ } } @@ -377,8 +377,8 @@ jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr, GLOBAL(void) jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col) + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col) { int dcval; ISLOW_MULT_TYPE * quantptr; diff --git a/src/jpeg/libijg/jinclude.h b/src/jpeg/libijg/jinclude.h index 0a4f1514..5d554f37 100644 --- a/src/jpeg/libijg/jinclude.h +++ b/src/jpeg/libijg/jinclude.h @@ -17,8 +17,8 @@ /* Include auto-config file to find out which system include files we need. */ -#include "jconfig.h" /* auto configuration options */ -#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ +#include "jconfig.h" /* auto configuration options */ +#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */ /* * We need the NULL macro and size_t typedef. @@ -58,14 +58,14 @@ #ifdef NEED_BSD_STRINGS #include -#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) -#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) +#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size)) +#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size)) #else /* not BSD, assume ANSI/SysV string lib */ #include -#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) -#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) +#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size)) +#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size)) #endif @@ -77,7 +77,7 @@ * we always use this SIZEOF() macro in place of using sizeof() directly. */ -#define SIZEOF(object) ((size_t) sizeof(object)) +#define SIZEOF(object) ((size_t) sizeof(object)) /* * The modules that use fread() and fwrite() always invoke them through diff --git a/src/jpeg/libijg/jlossls.h b/src/jpeg/libijg/jlossls.h new file mode 100644 index 00000000..2feccd6d --- /dev/null +++ b/src/jpeg/libijg/jlossls.h @@ -0,0 +1,151 @@ +/* + * jlossls.h + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the lossless JPEG + * codec modules. + */ + +#ifndef JLOSSLS_H +#define JLOSSLS_H + + +/* + * Table H.1: Predictors for lossless coding. + */ + +#define PREDICTOR1 Ra +#define PREDICTOR2 Rb +#define PREDICTOR3 Rc +#define PREDICTOR4 (int) ((INT32) Ra + (INT32) Rb - (INT32) Rc) +#define PREDICTOR5 (int) ((INT32) Ra + RIGHT_SHIFT((INT32) Rb - (INT32) Rc, 1)) +#define PREDICTOR6 (int) ((INT32) Rb + RIGHT_SHIFT((INT32) Ra - (INT32) Rc, 1)) +#define PREDICTOR7 (int) RIGHT_SHIFT((INT32) Ra + (INT32) Rb, 1) + + +typedef JMETHOD(void, predict_difference_method_ptr, + (j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW prev_row, + JDIFFROW diff_buf, JDIMENSION width)); + +typedef JMETHOD(void, scaler_method_ptr, + (j_compress_ptr cinfo, int ci, + JSAMPROW input_buf, JSAMPROW output_buf, + JDIMENSION width)); + +/* Lossless-specific compression codec (compressor proper) */ +typedef struct { + struct jpeg_c_codec pub; /* public fields */ + + + /* Difference buffer control */ + JMETHOD(void, diff_start_pass, (j_compress_ptr cinfo, + J_BUF_MODE pass_mode)); + + /* Pointer to data which is private to diff controller */ + void *diff_private; + + + /* Entropy encoding */ + JMETHOD(JDIMENSION, entropy_encode_mcus, (j_compress_ptr cinfo, + JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, + JDIMENSION MCU_col_num, + JDIMENSION nMCU)); + + /* Pointer to data which is private to entropy module */ + void *entropy_private; + + + /* Prediction, differencing */ + JMETHOD(void, predict_start_pass, (j_compress_ptr cinfo)); + + /* It is useful to allow each component to have a separate diff method. */ + predict_difference_method_ptr predict_difference[MAX_COMPONENTS]; + + /* Pointer to data which is private to predictor module */ + void *pred_private; + + /* Sample scaling */ + JMETHOD(void, scaler_start_pass, (j_compress_ptr cinfo)); + JMETHOD(void, scaler_scale, (j_compress_ptr cinfo, + JSAMPROW input_buf, JSAMPROW output_buf, + JDIMENSION width)); + + /* Pointer to data which is private to scaler module */ + void *scaler_private; + +} jpeg_lossless_c_codec; + +typedef jpeg_lossless_c_codec * j_lossless_c_ptr; + + +typedef JMETHOD(void, predict_undifference_method_ptr, + (j_decompress_ptr cinfo, int comp_index, + JDIFFROW diff_buf, JDIFFROW prev_row, + JDIFFROW undiff_buf, JDIMENSION width)); + +/* Lossless-specific decompression codec (decompressor proper) */ +typedef struct { + struct jpeg_d_codec pub; /* public fields */ + + + /* Difference buffer control */ + JMETHOD(void, diff_start_input_pass, (j_decompress_ptr cinfo)); + + /* Pointer to data which is private to diff controller */ + void *diff_private; + + + /* Entropy decoding */ + JMETHOD(void, entropy_start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, entropy_process_restart, (j_decompress_ptr cinfo)); + JMETHOD(JDIMENSION, entropy_decode_mcus, (j_decompress_ptr cinfo, + JDIFFIMAGE diff_buf, + JDIMENSION MCU_row_num, + JDIMENSION MCU_col_num, + JDIMENSION nMCU)); + + /* Pointer to data which is private to entropy module */ + void *entropy_private; + + + /* Prediction, undifferencing */ + JMETHOD(void, predict_start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, predict_process_restart, (j_decompress_ptr cinfo)); + + /* It is useful to allow each component to have a separate undiff method. */ + predict_undifference_method_ptr predict_undifference[MAX_COMPONENTS]; + + /* Pointer to data which is private to predictor module */ + void *pred_private; + + /* Sample scaling */ + JMETHOD(void, scaler_start_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, scaler_scale, (j_decompress_ptr cinfo, + JDIFFROW diff_buf, JSAMPROW output_buf, + JDIMENSION width)); + + /* Pointer to data which is private to scaler module */ + void *scaler_private; + +} jpeg_lossless_d_codec; + +typedef jpeg_lossless_d_codec * j_lossless_d_ptr; + + +/* Compression module initialization routines */ +EXTERN(void) jinit_lossless_c_codec JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_lhuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_differencer JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_scaler JPP((j_compress_ptr cinfo)); +/* Decompression module initialization routines */ +EXTERN(void) jinit_lossless_d_codec JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_lhuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_undifferencer JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_scaler JPP((j_decompress_ptr cinfo)); + +#endif /* JLOSSLS_H */ diff --git a/src/jpeg/libijg/jlossy.h b/src/jpeg/libijg/jlossy.h new file mode 100644 index 00000000..83c43f04 --- /dev/null +++ b/src/jpeg/libijg/jlossy.h @@ -0,0 +1,120 @@ +/* + * jlossy.h + * + * Copyright (C) 1998, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This include file contains common declarations for the lossy (DCT-based) + * JPEG codec modules. + */ + +#ifndef JLOSSY_H +#define JLOSSY_H + + +/* Lossy-specific compression codec (compressor proper) */ +typedef struct { + struct jpeg_c_codec pub; /* public fields */ + + + /* Coefficient buffer control */ + JMETHOD(void, coef_start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); + /* JMETHOD(boolean, coef_compress_data, (j_compress_ptr cinfo, + JSAMPIMAGE input_buf));*/ + + /* Pointer to data which is private to coef module */ + void *coef_private; + + + /* Forward DCT (also controls coefficient quantization) */ + JMETHOD(void, fdct_start_pass, (j_compress_ptr cinfo)); + /* perhaps this should be an array??? */ + JMETHOD(void, fdct_forward_DCT, (j_compress_ptr cinfo, + jpeg_component_info * compptr, + JSAMPARRAY sample_data, JBLOCKROW coef_blocks, + JDIMENSION start_row, JDIMENSION start_col, + JDIMENSION num_blocks)); + + /* Pointer to data which is private to fdct module */ + void *fdct_private; + + + /* Entropy encoding */ + JMETHOD(boolean, entropy_encode_mcu, (j_compress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* Pointer to data which is private to entropy module */ + void *entropy_private; + +} jpeg_lossy_c_codec; + +typedef jpeg_lossy_c_codec * j_lossy_c_ptr; + + + +typedef JMETHOD(void, inverse_DCT_method_ptr, + (j_decompress_ptr cinfo, jpeg_component_info * compptr, + JCOEFPTR coef_block, + JSAMPARRAY output_buf, JDIMENSION output_col)); + +/* Lossy-specific decompression codec (decompressor proper) */ +typedef struct { + struct jpeg_d_codec pub; /* public fields */ + + + /* Coefficient buffer control */ + JMETHOD(void, coef_start_input_pass, (j_decompress_ptr cinfo)); + JMETHOD(void, coef_start_output_pass, (j_decompress_ptr cinfo)); + + /* Pointer to array of coefficient virtual arrays, or NULL if none */ + jvirt_barray_ptr *coef_arrays; + + /* Pointer to data which is private to coef module */ + void *coef_private; + + + /* Entropy decoding */ + JMETHOD(void, entropy_start_pass, (j_decompress_ptr cinfo)); + JMETHOD(boolean, entropy_decode_mcu, (j_decompress_ptr cinfo, + JBLOCKROW *MCU_data)); + + /* This is here to share code between baseline and progressive decoders; */ + /* other modules probably should not use it */ + boolean entropy_insufficient_data; /* set TRUE after emitting warning */ + + /* Pointer to data which is private to entropy module */ + void *entropy_private; + + + /* Inverse DCT (also performs dequantization) */ + JMETHOD(void, idct_start_pass, (j_decompress_ptr cinfo)); + + /* It is useful to allow each component to have a separate IDCT method. */ + inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; + + /* Pointer to data which is private to idct module */ + void *idct_private; + +} jpeg_lossy_d_codec; + +typedef jpeg_lossy_d_codec * j_lossy_d_ptr; + + +/* Compression module initialization routines */ +EXTERN(void) jinit_lossy_c_codec JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_shuff_encoder JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); + +/* Decompression module initialization routines */ +EXTERN(void) jinit_lossy_d_codec JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, + boolean need_full_buffer)); +EXTERN(void) jinit_shuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); + +#endif /* JLOSSY_H */ diff --git a/src/jpeg/libijg/jmemmgr.c b/src/jpeg/libijg/jmemmgr.c index d801b322..7e2db9d9 100644 --- a/src/jpeg/libijg/jmemmgr.c +++ b/src/jpeg/libijg/jmemmgr.c @@ -1,7 +1,7 @@ /* * jmemmgr.c * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -25,13 +25,13 @@ */ #define JPEG_INTERNALS -#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ +#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */ #include "jinclude.h" #include "jpeglib.h" -#include "jmemsys.h" /* import the system-dependent declarations */ +#include "jmemsys.h" /* import the system-dependent declarations */ #ifndef NO_GETENV -#ifndef HAVE_STDLIB_H /* should declare getenv() */ +#ifndef HAVE_STDLIB_H /* should declare getenv() */ extern char * getenv JPP((const char * name)); #endif #endif @@ -42,11 +42,12 @@ extern char * getenv JPP((const char * name)); * The allocation routines provided here must never return NULL. * They should exit to error_exit if unsuccessful. * - * It's not a good idea to try to merge the sarray and barray routines, - * even though they are textually almost the same, because samples are - * usually stored as bytes while coefficients are shorts or ints. Thus, - * in machines where byte pointers have a different representation from - * word pointers, the resulting machine code could not be the same. + * It's not a good idea to try to merge the sarray, barray and darray + * routines, even though they are textually almost the same, because + * samples are usually stored as bytes while coefficients and differenced + * are shorts or ints. Thus, in machines where byte pointers have a + * different representation from word pointers, the resulting machine + * code could not be the same. */ @@ -69,7 +70,7 @@ extern char * getenv JPP((const char * name)); * such a compiler. */ -#ifndef ALIGN_TYPE /* so can override from jconfig.h */ +#ifndef ALIGN_TYPE /* so can override from jconfig.h */ #define ALIGN_TYPE double #endif @@ -90,22 +91,22 @@ typedef union small_pool_struct * small_pool_ptr; typedef union small_pool_struct { struct { - small_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ + small_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ + ALIGN_TYPE dummy; /* included in union to ensure alignment */ } small_pool_hdr; typedef union large_pool_struct FAR * large_pool_ptr; typedef union large_pool_struct { struct { - large_pool_ptr next; /* next in list of pools */ - size_t bytes_used; /* how many bytes already used within pool */ - size_t bytes_left; /* bytes still available in this pool */ + large_pool_ptr next; /* next in list of pools */ + size_t bytes_used; /* how many bytes already used within pool */ + size_t bytes_left; /* bytes still available in this pool */ } hdr; - ALIGN_TYPE dummy; /* included in union to ensure alignment */ + ALIGN_TYPE dummy; /* included in union to ensure alignment */ } large_pool_hdr; @@ -114,7 +115,7 @@ typedef union large_pool_struct { */ typedef struct { - struct jpeg_memory_mgr pub; /* public fields */ + struct jpeg_memory_mgr pub; /* public fields */ /* Each pool identifier (lifetime class) names a linked list of pools. */ small_pool_ptr small_list[JPOOL_NUMPOOLS]; @@ -134,7 +135,7 @@ typedef struct { /* alloc_sarray and alloc_barray set this value for use by virtual * array routines. */ - JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ + JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */ } my_memory_mgr; typedef my_memory_mgr * my_mem_ptr; @@ -148,39 +149,39 @@ typedef my_memory_mgr * my_mem_ptr; */ struct jvirt_sarray_control { - JSAMPARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_sarray_ptr next; /* link to next virtual sarray control block */ - backing_store_info b_s_info; /* System-dependent control info */ + JSAMPARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION samplesperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_sarray_ptr next; /* link to next virtual sarray control block */ + backing_store_info b_s_info; /* System-dependent control info */ }; struct jvirt_barray_control { - JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ - JDIMENSION rows_in_array; /* total virtual array height */ - JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ - JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ - JDIMENSION rows_in_mem; /* height of memory buffer */ - JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ - JDIMENSION cur_start_row; /* first logical row # in the buffer */ - JDIMENSION first_undef_row; /* row # of first uninitialized row */ - boolean pre_zero; /* pre-zero mode requested? */ - boolean dirty; /* do current buffer contents need written? */ - boolean b_s_open; /* is backing-store data valid? */ - jvirt_barray_ptr next; /* link to next virtual barray control block */ - backing_store_info b_s_info; /* System-dependent control info */ + JBLOCKARRAY mem_buffer; /* => the in-memory buffer */ + JDIMENSION rows_in_array; /* total virtual array height */ + JDIMENSION blocksperrow; /* width of array (and of memory buffer) */ + JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */ + JDIMENSION rows_in_mem; /* height of memory buffer */ + JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */ + JDIMENSION cur_start_row; /* first logical row # in the buffer */ + JDIMENSION first_undef_row; /* row # of first uninitialized row */ + boolean pre_zero; /* pre-zero mode requested? */ + boolean dirty; /* do current buffer contents need written? */ + boolean b_s_open; /* is backing-store data valid? */ + jvirt_barray_ptr next; /* link to next virtual barray control block */ + backing_store_info b_s_info; /* System-dependent control info */ }; -#ifdef MEM_STATS /* optional extra stuff for statistics */ +#ifdef MEM_STATS /* optional extra stuff for statistics */ LOCAL(void) print_mem_stats (j_common_ptr cinfo, int pool_id) @@ -194,19 +195,19 @@ print_mem_stats (j_common_ptr cinfo, int pool_id) * This is helpful because message parm array can't handle longs. */ fprintf(stderr, "Freeing pool %d, total space = %ld\n", - pool_id, mem->total_space_allocated); + pool_id, mem->total_space_allocated); for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL; lhdr_ptr = lhdr_ptr->hdr.next) { fprintf(stderr, " Large chunk used %ld\n", - (long) lhdr_ptr->hdr.bytes_used); + (long) lhdr_ptr->hdr.bytes_used); } for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL; shdr_ptr = shdr_ptr->hdr.next) { fprintf(stderr, " Small chunk used %ld free %ld\n", - (long) shdr_ptr->hdr.bytes_used, - (long) shdr_ptr->hdr.bytes_left); + (long) shdr_ptr->hdr.bytes_used, + (long) shdr_ptr->hdr.bytes_left); } } @@ -219,7 +220,7 @@ out_of_memory (j_common_ptr cinfo, int which) /* If we compiled MEM_STATS support, report alloc requests before dying */ { #ifdef MEM_STATS - cinfo->err->trace_level = 2; /* force self_destruct to report stats */ + cinfo->err->trace_level = 2; /* force self_destruct to report stats */ #endif ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which); } @@ -240,17 +241,17 @@ out_of_memory (j_common_ptr cinfo, int which) static const size_t first_pool_slop[JPOOL_NUMPOOLS] = { - 1600, /* first PERMANENT pool */ - 16000 /* first IMAGE pool */ + 1600, /* first PERMANENT pool */ + 16000 /* first IMAGE pool */ }; static const size_t extra_pool_slop[JPOOL_NUMPOOLS] = { - 0, /* additional PERMANENT pools */ - 5000 /* additional IMAGE pools */ + 0, /* additional PERMANENT pools */ + 5000 /* additional IMAGE pools */ }; -#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ +#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */ METHODDEF(void *) @@ -264,7 +265,7 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* Check for unsatisfiable request (do now to ensure no overflow below) */ if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr))) - out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ + out_of_memory(cinfo, 1); /* request exceeds malloc's ability */ /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); @@ -273,12 +274,12 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* See if space is available in any existing pool */ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ prev_hdr_ptr = NULL; hdr_ptr = mem->small_list[pool_id]; while (hdr_ptr != NULL) { if (hdr_ptr->hdr.bytes_left >= sizeofobject) - break; /* found pool with enough space */ + break; /* found pool with enough space */ prev_hdr_ptr = hdr_ptr; hdr_ptr = hdr_ptr->hdr.next; } @@ -287,7 +288,7 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) if (hdr_ptr == NULL) { /* min_request is what we need now, slop is what will be leftover */ min_request = sizeofobject + SIZEOF(small_pool_hdr); - if (prev_hdr_ptr == NULL) /* first pool in class? */ + if (prev_hdr_ptr == NULL) /* first pool in class? */ slop = first_pool_slop[pool_id]; else slop = extra_pool_slop[pool_id]; @@ -298,17 +299,17 @@ alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject) for (;;) { hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop); if (hdr_ptr != NULL) - break; + break; slop /= 2; - if (slop < MIN_SLOP) /* give up when it gets real small */ - out_of_memory(cinfo, 2); /* jpeg_get_small failed */ + if (slop < MIN_SLOP) /* give up when it gets real small */ + out_of_memory(cinfo, 2); /* jpeg_get_small failed */ } mem->total_space_allocated += min_request + slop; /* Success, initialize the new pool header and add to end of list */ hdr_ptr->hdr.next = NULL; hdr_ptr->hdr.bytes_used = 0; hdr_ptr->hdr.bytes_left = sizeofobject + slop; - if (prev_hdr_ptr == NULL) /* first pool in class? */ + if (prev_hdr_ptr == NULL) /* first pool in class? */ mem->small_list[pool_id] = hdr_ptr; else prev_hdr_ptr->hdr.next = hdr_ptr; @@ -348,7 +349,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* Check for unsatisfiable request (do now to ensure no overflow below) */ if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr))) - out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ + out_of_memory(cinfo, 3); /* request exceeds malloc's ability */ /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */ odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE); @@ -357,12 +358,12 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) /* Always make a new pool */ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject + - SIZEOF(large_pool_hdr)); + SIZEOF(large_pool_hdr)); if (hdr_ptr == NULL) - out_of_memory(cinfo, 4); /* jpeg_get_large failed */ + out_of_memory(cinfo, 4); /* jpeg_get_large failed */ mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr); /* Success, initialize the new pool header and add to list */ @@ -393,7 +394,7 @@ alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject) METHODDEF(JSAMPARRAY) alloc_sarray (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, JDIMENSION numrows) + JDIMENSION samplesperrow, JDIMENSION numrows) /* Allocate a 2-D sample array */ { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -404,7 +405,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id, /* Calculate max # of rows allowed in one allocation chunk */ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) samplesperrow * SIZEOF(JSAMPLE)); + ((long) samplesperrow * SIZEOF(JSAMPLE)); if (ltemp <= 0) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); if (ltemp < (long) numrows) @@ -415,15 +416,15 @@ alloc_sarray (j_common_ptr cinfo, int pool_id, /* Get space for row pointers (small object) */ result = (JSAMPARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JSAMPROW))); + (size_t) (numrows * SIZEOF(JSAMPROW))); /* Get the rows themselves (large objects) */ currow = 0; while (currow < numrows) { rowsperchunk = MIN(rowsperchunk, numrows - currow); workspace = (JSAMPROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow - * SIZEOF(JSAMPLE))); + (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow + * SIZEOF(JSAMPLE))); for (i = rowsperchunk; i > 0; i--) { result[currow++] = workspace; workspace += samplesperrow; @@ -441,7 +442,7 @@ alloc_sarray (j_common_ptr cinfo, int pool_id, METHODDEF(JBLOCKARRAY) alloc_barray (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, JDIMENSION numrows) + JDIMENSION blocksperrow, JDIMENSION numrows) /* Allocate a 2-D coefficient-block array */ { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -452,7 +453,7 @@ alloc_barray (j_common_ptr cinfo, int pool_id, /* Calculate max # of rows allowed in one allocation chunk */ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / - ((long) blocksperrow * SIZEOF(JBLOCK)); + ((long) blocksperrow * SIZEOF(JBLOCK)); if (ltemp <= 0) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); if (ltemp < (long) numrows) @@ -463,15 +464,15 @@ alloc_barray (j_common_ptr cinfo, int pool_id, /* Get space for row pointers (small object) */ result = (JBLOCKARRAY) alloc_small(cinfo, pool_id, - (size_t) (numrows * SIZEOF(JBLOCKROW))); + (size_t) (numrows * SIZEOF(JBLOCKROW))); /* Get the rows themselves (large objects) */ currow = 0; while (currow < numrows) { rowsperchunk = MIN(rowsperchunk, numrows - currow); workspace = (JBLOCKROW) alloc_large(cinfo, pool_id, - (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow - * SIZEOF(JBLOCK))); + (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow + * SIZEOF(JBLOCK))); for (i = rowsperchunk; i > 0; i--) { result[currow++] = workspace; workspace += blocksperrow; @@ -482,6 +483,58 @@ alloc_barray (j_common_ptr cinfo, int pool_id, } +#ifdef NEED_DARRAY + +/* + * Creation of 2-D difference arrays. + * This is essentially the same as the code for sample arrays, above. + */ + +METHODDEF(JDIFFARRAY) +alloc_darray (j_common_ptr cinfo, int pool_id, + JDIMENSION diffsperrow, JDIMENSION numrows) +/* Allocate a 2-D difference array */ +{ + my_mem_ptr mem = (my_mem_ptr) cinfo->mem; + JDIFFARRAY result; + JDIFFROW workspace; + JDIMENSION rowsperchunk, currow, i; + long ltemp; + + /* Calculate max # of rows allowed in one allocation chunk */ + ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) / + ((long) diffsperrow * SIZEOF(JDIFF)); + if (ltemp <= 0) + ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); + if (ltemp < (long) numrows) + rowsperchunk = (JDIMENSION) ltemp; + else + rowsperchunk = numrows; + mem->last_rowsperchunk = rowsperchunk; + + /* Get space for row pointers (small object) */ + result = (JDIFFARRAY) alloc_small(cinfo, pool_id, + (size_t) (numrows * SIZEOF(JDIFFROW))); + + /* Get the rows themselves (large objects) */ + currow = 0; + while (currow < numrows) { + rowsperchunk = MIN(rowsperchunk, numrows - currow); + workspace = (JDIFFROW) alloc_large(cinfo, pool_id, + (size_t) ((size_t) rowsperchunk * (size_t) diffsperrow + * SIZEOF(JDIFF))); + for (i = rowsperchunk; i > 0; i--) { + result[currow++] = workspace; + workspace += diffsperrow; + } + } + + return result; +} + +#endif + + /* * About virtual array management: * @@ -521,8 +574,8 @@ alloc_barray (j_common_ptr cinfo, int pool_id, METHODDEF(jvirt_sarray_ptr) request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION samplesperrow, JDIMENSION numrows, - JDIMENSION maxaccess) + JDIMENSION samplesperrow, JDIMENSION numrows, + JDIMENSION maxaccess) /* Request a virtual 2-D sample array */ { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -530,18 +583,18 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, /* Only IMAGE-lifetime virtual arrays are currently supported */ if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ /* get control block */ result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_sarray_control)); + SIZEOF(struct jvirt_sarray_control)); - result->mem_buffer = NULL; /* marks array not yet realized */ + result->mem_buffer = NULL; /* marks array not yet realized */ result->rows_in_array = numrows; result->samplesperrow = samplesperrow; result->maxaccess = maxaccess; result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ + result->b_s_open = FALSE; /* no associated backing-store object */ result->next = mem->virt_sarray_list; /* add to list of virtual arrays */ mem->virt_sarray_list = result; @@ -551,8 +604,8 @@ request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero, METHODDEF(jvirt_barray_ptr) request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, - JDIMENSION blocksperrow, JDIMENSION numrows, - JDIMENSION maxaccess) + JDIMENSION blocksperrow, JDIMENSION numrows, + JDIMENSION maxaccess) /* Request a virtual 2-D coefficient-block array */ { my_mem_ptr mem = (my_mem_ptr) cinfo->mem; @@ -560,18 +613,18 @@ request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero, /* Only IMAGE-lifetime virtual arrays are currently supported */ if (pool_id != JPOOL_IMAGE) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ /* get control block */ result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id, - SIZEOF(struct jvirt_barray_control)); + SIZEOF(struct jvirt_barray_control)); - result->mem_buffer = NULL; /* marks array not yet realized */ + result->mem_buffer = NULL; /* marks array not yet realized */ result->rows_in_array = numrows; result->blocksperrow = blocksperrow; result->maxaccess = maxaccess; result->pre_zero = pre_zero; - result->b_s_open = FALSE; /* no associated backing-store object */ + result->b_s_open = FALSE; /* no associated backing-store object */ result->next = mem->virt_barray_list; /* add to list of virtual arrays */ mem->virt_barray_list = result; @@ -598,26 +651,26 @@ realize_virt_arrays (j_common_ptr cinfo) for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { if (sptr->mem_buffer == NULL) { /* if not realized yet */ space_per_minheight += (long) sptr->maxaccess * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); maximum_space += (long) sptr->rows_in_array * - (long) sptr->samplesperrow * SIZEOF(JSAMPLE); + (long) sptr->samplesperrow * SIZEOF(JSAMPLE); } } for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { if (bptr->mem_buffer == NULL) { /* if not realized yet */ space_per_minheight += (long) bptr->maxaccess * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); + (long) bptr->blocksperrow * SIZEOF(JBLOCK); maximum_space += (long) bptr->rows_in_array * - (long) bptr->blocksperrow * SIZEOF(JBLOCK); + (long) bptr->blocksperrow * SIZEOF(JBLOCK); } } if (space_per_minheight <= 0) - return; /* no unrealized arrays, no work */ + return; /* no unrealized arrays, no work */ /* Determine amount of memory to actually use; this is system-dependent. */ avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space, - mem->total_space_allocated); + mem->total_space_allocated); /* If the maximum space needed is available, make all the buffers full * height; otherwise parcel it out with the same number of minheights @@ -640,19 +693,19 @@ realize_virt_arrays (j_common_ptr cinfo) if (sptr->mem_buffer == NULL) { /* if not realized yet */ minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L; if (minheights <= max_minheights) { - /* This buffer fits in memory */ - sptr->rows_in_mem = sptr->rows_in_array; + /* This buffer fits in memory */ + sptr->rows_in_mem = sptr->rows_in_array; } else { - /* It doesn't fit in memory, create backing store. */ - sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); - jpeg_open_backing_store(cinfo, & sptr->b_s_info, - (long) sptr->rows_in_array * - (long) sptr->samplesperrow * - (long) SIZEOF(JSAMPLE)); - sptr->b_s_open = TRUE; + /* It doesn't fit in memory, create backing store. */ + sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess); + jpeg_open_backing_store(cinfo, & sptr->b_s_info, + (long) sptr->rows_in_array * + (long) sptr->samplesperrow * + (long) SIZEOF(JSAMPLE)); + sptr->b_s_open = TRUE; } sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE, - sptr->samplesperrow, sptr->rows_in_mem); + sptr->samplesperrow, sptr->rows_in_mem); sptr->rowsperchunk = mem->last_rowsperchunk; sptr->cur_start_row = 0; sptr->first_undef_row = 0; @@ -664,19 +717,19 @@ realize_virt_arrays (j_common_ptr cinfo) if (bptr->mem_buffer == NULL) { /* if not realized yet */ minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L; if (minheights <= max_minheights) { - /* This buffer fits in memory */ - bptr->rows_in_mem = bptr->rows_in_array; + /* This buffer fits in memory */ + bptr->rows_in_mem = bptr->rows_in_array; } else { - /* It doesn't fit in memory, create backing store. */ - bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); - jpeg_open_backing_store(cinfo, & bptr->b_s_info, - (long) bptr->rows_in_array * - (long) bptr->blocksperrow * - (long) SIZEOF(JBLOCK)); - bptr->b_s_open = TRUE; + /* It doesn't fit in memory, create backing store. */ + bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess); + jpeg_open_backing_store(cinfo, & bptr->b_s_info, + (long) bptr->rows_in_array * + (long) bptr->blocksperrow * + (long) SIZEOF(JBLOCK)); + bptr->b_s_open = TRUE; } bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE, - bptr->blocksperrow, bptr->rows_in_mem); + bptr->blocksperrow, bptr->rows_in_mem); bptr->rowsperchunk = mem->last_rowsperchunk; bptr->cur_start_row = 0; bptr->first_undef_row = 0; @@ -703,17 +756,17 @@ do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing) rows = MIN(rows, (long) ptr->first_undef_row - thisrow); /* Transfer no more than fits in file */ rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ + if (rows <= 0) /* this chunk might be past end of file! */ break; byte_count = rows * bytesperrow; if (writing) (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); else (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); file_offset += byte_count; } } @@ -736,17 +789,17 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) rows = MIN(rows, (long) ptr->first_undef_row - thisrow); /* Transfer no more than fits in file */ rows = MIN(rows, (long) ptr->rows_in_array - thisrow); - if (rows <= 0) /* this chunk might be past end of file! */ + if (rows <= 0) /* this chunk might be past end of file! */ break; byte_count = rows * bytesperrow; if (writing) (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); else (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info, - (void FAR *) ptr->mem_buffer[i], - file_offset, byte_count); + (void FAR *) ptr->mem_buffer[i], + file_offset, byte_count); file_offset += byte_count; } } @@ -754,8 +807,8 @@ do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing) METHODDEF(JSAMPARRAY) access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) /* Access the part of a virtual sample array starting at start_row */ /* and extending for num_rows rows. writable is true if */ /* caller intends to modify the accessed area. */ @@ -793,7 +846,7 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, ltemp = (long) end_row - (long) ptr->rows_in_mem; if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ + ltemp = 0; /* don't fall off front end of file */ ptr->cur_start_row = (JDIMENSION) ltemp; } /* Read in the selected part of the array. @@ -808,9 +861,9 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, */ if (ptr->first_undef_row < end_row) { if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ } else { undef_row = ptr->first_undef_row; } @@ -821,12 +874,12 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ end_row -= ptr->cur_start_row; while (undef_row < end_row) { - jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; } } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); } } /* Flag the buffer dirty if caller will write in it */ @@ -839,8 +892,8 @@ access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr, METHODDEF(JBLOCKARRAY) access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, - JDIMENSION start_row, JDIMENSION num_rows, - boolean writable) + JDIMENSION start_row, JDIMENSION num_rows, + boolean writable) /* Access the part of a virtual block array starting at start_row */ /* and extending for num_rows rows. writable is true if */ /* caller intends to modify the accessed area. */ @@ -878,7 +931,7 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, ltemp = (long) end_row - (long) ptr->rows_in_mem; if (ltemp < 0) - ltemp = 0; /* don't fall off front end of file */ + ltemp = 0; /* don't fall off front end of file */ ptr->cur_start_row = (JDIMENSION) ltemp; } /* Read in the selected part of the array. @@ -893,9 +946,9 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, */ if (ptr->first_undef_row < end_row) { if (ptr->first_undef_row < start_row) { - if (writable) /* writer skipped over a section of array */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); - undef_row = start_row; /* but reader is allowed to read ahead */ + if (writable) /* writer skipped over a section of array */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + undef_row = start_row; /* but reader is allowed to read ahead */ } else { undef_row = ptr->first_undef_row; } @@ -906,12 +959,12 @@ access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr, undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */ end_row -= ptr->cur_start_row; while (undef_row < end_row) { - jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); - undef_row++; + jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow); + undef_row++; } } else { - if (! writable) /* reader looking at undefined data */ - ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); + if (! writable) /* reader looking at undefined data */ + ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS); } } /* Flag the buffer dirty if caller will write in it */ @@ -935,7 +988,7 @@ free_pool (j_common_ptr cinfo, int pool_id) size_t space_freed; if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS) - ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ + ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */ #ifdef MEM_STATS if (cinfo->err->trace_level > 1) @@ -948,16 +1001,16 @@ free_pool (j_common_ptr cinfo, int pool_id) jvirt_barray_ptr bptr; for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) { - if (sptr->b_s_open) { /* there may be no backing store */ - sptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); + if (sptr->b_s_open) { /* there may be no backing store */ + sptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info); } } mem->virt_sarray_list = NULL; for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) { - if (bptr->b_s_open) { /* there may be no backing store */ - bptr->b_s_open = FALSE; /* prevent recursive close if error */ - (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); + if (bptr->b_s_open) { /* there may be no backing store */ + bptr->b_s_open = FALSE; /* prevent recursive close if error */ + (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info); } } mem->virt_barray_list = NULL; @@ -970,8 +1023,8 @@ free_pool (j_common_ptr cinfo, int pool_id) while (lhdr_ptr != NULL) { large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next; space_freed = lhdr_ptr->hdr.bytes_used + - lhdr_ptr->hdr.bytes_left + - SIZEOF(large_pool_hdr); + lhdr_ptr->hdr.bytes_left + + SIZEOF(large_pool_hdr); jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed); mem->total_space_allocated -= space_freed; lhdr_ptr = next_lhdr_ptr; @@ -984,8 +1037,8 @@ free_pool (j_common_ptr cinfo, int pool_id) while (shdr_ptr != NULL) { small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next; space_freed = shdr_ptr->hdr.bytes_used + - shdr_ptr->hdr.bytes_left + - SIZEOF(small_pool_hdr); + shdr_ptr->hdr.bytes_left + + SIZEOF(small_pool_hdr); jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed); mem->total_space_allocated -= space_freed; shdr_ptr = next_shdr_ptr; @@ -1013,9 +1066,9 @@ self_destruct (j_common_ptr cinfo) /* Release the memory manager control block too. */ jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr)); - cinfo->mem = NULL; /* ensures I will be called only once */ + cinfo->mem = NULL; /* ensures I will be called only once */ - jpeg_mem_term(cinfo); /* system-dependent cleanup */ + jpeg_mem_term(cinfo); /* system-dependent cleanup */ } @@ -1032,7 +1085,7 @@ jinit_memory_mgr (j_common_ptr cinfo) int pool; size_t test_mac; - cinfo->mem = NULL; /* for safety if init fails */ + cinfo->mem = NULL; /* for safety if init fails */ /* Check for configuration errors. * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably @@ -1059,7 +1112,7 @@ jinit_memory_mgr (j_common_ptr cinfo) mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr)); if (mem == NULL) { - jpeg_mem_term(cinfo); /* system-dependent cleanup */ + jpeg_mem_term(cinfo); /* system-dependent cleanup */ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0); } @@ -1068,6 +1121,9 @@ jinit_memory_mgr (j_common_ptr cinfo) mem->pub.alloc_large = alloc_large; mem->pub.alloc_sarray = alloc_sarray; mem->pub.alloc_barray = alloc_barray; +#ifdef NEED_DARRAY + mem->pub.alloc_darray = alloc_darray; +#endif mem->pub.request_virt_sarray = request_virt_sarray; mem->pub.request_virt_barray = request_virt_barray; mem->pub.realize_virt_arrays = realize_virt_arrays; @@ -1107,9 +1163,9 @@ jinit_memory_mgr (j_common_ptr cinfo) char ch = 'x'; if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) { - if (ch == 'm' || ch == 'M') - max_to_use *= 1000L; - mem->pub.max_memory_to_use = max_to_use * 1000L; + if (ch == 'm' || ch == 'M') + max_to_use *= 1000L; + mem->pub.max_memory_to_use = max_to_use * 1000L; } } } diff --git a/src/jpeg/libijg/jmemnobs.c b/src/jpeg/libijg/jmemnobs.c index 7e53479f..71caa671 100644 --- a/src/jpeg/libijg/jmemnobs.c +++ b/src/jpeg/libijg/jmemnobs.c @@ -34,15 +34,12 @@ extern void free JPP((void *ptr)); GLOBAL(void *) jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject) { - cinfo = 0; return (void *) malloc(sizeofobject); } GLOBAL(void) jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) { - cinfo = 0; - sizeofobject = 0; free(object); } @@ -57,15 +54,12 @@ jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject) GLOBAL(void FAR *) jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject) { - cinfo = 0; return (void FAR *) malloc(sizeofobject); } GLOBAL(void) jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject) { - cinfo = 0; - sizeofobject = 0; free(object); } @@ -79,9 +73,6 @@ GLOBAL(long) jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed, long max_bytes_needed, long already_allocated) { - cinfo = 0; - min_bytes_needed = 0; - already_allocated = 0; return max_bytes_needed; } @@ -96,8 +87,6 @@ GLOBAL(void) jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, long total_bytes_needed) { - info = 0; - total_bytes_needed = 0; ERREXIT(cinfo, JERR_NO_BACKING_STORE); } @@ -110,13 +99,11 @@ jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info, GLOBAL(long) jpeg_mem_init (j_common_ptr cinfo) { - cinfo = 0; return 0; /* just set max_memory_to_use to 0 */ } GLOBAL(void) jpeg_mem_term (j_common_ptr cinfo) { - cinfo = 0; /* no work */ } diff --git a/src/jpeg/libijg/jmemsys.h b/src/jpeg/libijg/jmemsys.h index 6c3c6d34..2e8ee7ee 100644 --- a/src/jpeg/libijg/jmemsys.h +++ b/src/jpeg/libijg/jmemsys.h @@ -22,14 +22,14 @@ /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_get_small jGetSmall -#define jpeg_free_small jFreeSmall -#define jpeg_get_large jGetLarge -#define jpeg_free_large jFreeLarge -#define jpeg_mem_available jMemAvail -#define jpeg_open_backing_store jOpenBackStore -#define jpeg_mem_init jMemInit -#define jpeg_mem_term jMemTerm +#define jpeg_get_small jGetSmall +#define jpeg_free_small jFreeSmall +#define jpeg_get_large jGetLarge +#define jpeg_free_large jFreeLarge +#define jpeg_mem_available jMemAvail +#define jpeg_open_backing_store jOpenBackStore +#define jpeg_mem_init jMemInit +#define jpeg_mem_term jMemTerm #endif /* NEED_SHORT_EXTERNAL_NAMES */ @@ -46,7 +46,7 @@ EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject)); EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, - size_t sizeofobject)); + size_t sizeofobject)); /* * These two functions are used to allocate and release large chunks of @@ -58,9 +58,9 @@ EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object, */ EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo, - size_t sizeofobject)); + size_t sizeofobject)); EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, - size_t sizeofobject)); + size_t sizeofobject)); /* * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may @@ -74,7 +74,7 @@ EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, * size_t and will be a multiple of sizeof(align_type). */ -#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ +#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */ #define MAX_ALLOC_CHUNK 1000000000L #endif @@ -101,9 +101,9 @@ EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object, */ EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, - long min_bytes_needed, - long max_bytes_needed, - long already_allocated)); + long min_bytes_needed, + long max_bytes_needed, + long already_allocated)); /* @@ -113,23 +113,23 @@ EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo, * are private to the system-dependent backing store routines. */ -#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ +#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ +#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ +typedef unsigned short XMSH; /* type of extended-memory handles */ +typedef unsigned short EMSH; /* type of expanded-memory handles */ typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ + short file_handle; /* DOS file handle if it's a temp file */ + XMSH xms_handle; /* handle if it's a chunk of XMS */ + EMSH ems_handle; /* handle if it's a chunk of EMS */ } handle_union; #endif /* USE_MSDOS_MEMMGR */ -#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ +#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ #include #endif /* USE_MAC_MEMMGR */ @@ -139,30 +139,30 @@ typedef struct backing_store_struct * backing_store_ptr; typedef struct backing_store_struct { /* Methods for reading/writing/closing this backing-store object */ JMETHOD(void, read_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); JMETHOD(void, write_backing_store, (j_common_ptr cinfo, - backing_store_ptr info, - void FAR * buffer_address, - long file_offset, long byte_count)); + backing_store_ptr info, + void FAR * buffer_address, + long file_offset, long byte_count)); JMETHOD(void, close_backing_store, (j_common_ptr cinfo, - backing_store_ptr info)); + backing_store_ptr info)); /* Private fields for system-dependent backing-store management */ #ifdef USE_MSDOS_MEMMGR /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ + handle_union handle; /* reference to backing-store storage object */ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ #else #ifdef USE_MAC_MEMMGR /* For the Mac manager (jmemmac.c), we need: */ - short temp_file; /* file reference number to temp file */ - FSSpec tempSpec; /* the FSSpec for the temp file */ + short temp_file; /* file reference number to temp file */ + FSSpec tempSpec; /* the FSSpec for the temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ #else /* For a typical implementation with temp files, we need: */ - FILE * temp_file; /* stdio reference to temp file */ + FILE * temp_file; /* stdio reference to temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ #endif #endif @@ -178,8 +178,8 @@ typedef struct backing_store_struct { */ EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo, - backing_store_ptr info, - long total_bytes_needed)); + backing_store_ptr info, + long total_bytes_needed)); /* diff --git a/src/jpeg/libijg/jmorecfg.h b/src/jpeg/libijg/jmorecfg.h index 515644dd..443c6dda 100644 --- a/src/jpeg/libijg/jmorecfg.h +++ b/src/jpeg/libijg/jmorecfg.h @@ -1,7 +1,7 @@ /* * jmorecfg.h * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -10,6 +10,7 @@ * optimizations. Most users will not need to touch this file. */ + /* * Define BITS_IN_JSAMPLE as either * 8 for 8-bit sample values (the usual setting) @@ -19,7 +20,7 @@ * We do not support run-time selection of data precision, sorry. */ -//#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */ +//#define BITS_IN_JSAMPLE 8 /* use 8 or 12 (or 16 only for lossless) */ #define BITS_IN_JSAMPLE @GDCM_BITS_IN_JSAMPLE@ /* @@ -89,6 +90,33 @@ typedef short JSAMPLE; #endif /* BITS_IN_JSAMPLE == 12 */ +#if BITS_IN_JSAMPLE == 16 +/* JSAMPLE should be the smallest type that will hold the values 0..65535. + * You can use a signed short by having GETJSAMPLE mask it with 0xFFFF. + */ + +#ifdef HAVE_UNSIGNED_SHORT + +typedef unsigned short JSAMPLE; +#define GETJSAMPLE(value) ((int) (value)) + +#else /* not HAVE_UNSIGNED_SHORT */ + +typedef short JSAMPLE; +#ifdef SHORT_IS_UNSIGNED +#define GETJSAMPLE(value) ((int) (value)) +#else +#define GETJSAMPLE(value) ((int) (value) & 0xFFFF) +#endif /* SHORT_IS_UNSIGNED */ + +#endif /* HAVE_UNSIGNED_SHORT */ + +#define MAXJSAMPLE 65535 +#define CENTERJSAMPLE 32768 + +#endif /* BITS_IN_JSAMPLE == 16 */ + + /* Representation of a DCT frequency coefficient. * This should be a signed value of at least 16 bits; "short" is usually OK. * Again, we allocate large arrays of these, but you can change to int @@ -98,6 +126,13 @@ typedef short JSAMPLE; typedef short JCOEF; +/* Representation of a spatial difference value. + * This should be a signed value of at least 16 bits; int is usually OK. + */ + +typedef int JDIFF; + + /* Compressed datastreams are represented as arrays of JOCTET. * These must be EXACTLY 8 bits wide, at least once they are written to * external storage. Note that when using the stdio data source/destination @@ -183,7 +218,6 @@ typedef unsigned int JDIMENSION; #define METHODDEF(type) static type /* a function used only in its module: */ #define LOCAL(type) static type - /* a function referenced thru EXTERNs: */ #if defined( _WIN32 ) && defined (JPEGDLL) #define GLOBAL(type) __declspec(dllexport) type @@ -285,14 +319,16 @@ typedef int boolean; #undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ #define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define C_LOSSLESS_SUPPORTED /* Lossless JPEG? */ #define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */ /* Note: if you selected 12-bit data precision, it is dangerous to turn off * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit - * precision, so jchuff.c normally uses entropy optimization to compute + * precision, so jcshuff.c normally uses entropy optimization to compute * usable tables for higher precision. If you don't want to do optimization, * you'll have to supply different default Huffman tables. - * The exact same statements apply for progressive JPEG: the default tables - * don't work for progressive mode. (This may get fixed, however.) + * The exact same statements apply for progressive and lossless JPEG: + * the default tables don't work for progressive mode or lossless mode. + * (This may get fixed, however.) */ #define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */ @@ -301,6 +337,7 @@ typedef int boolean; #undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */ #define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */ #define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/ +#define D_LOSSLESS_SUPPORTED /* Lossless JPEG? */ #define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */ #define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */ #define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */ @@ -392,4 +429,5 @@ typedef int boolean; #pragma warning ( disable : 4505 ) #endif + #endif /* JPEG_INTERNAL_OPTIONS */ diff --git a/src/jpeg/libijg/jpegint.h b/src/jpeg/libijg/jpegint.h index 95b00d40..684dada0 100644 --- a/src/jpeg/libijg/jpegint.h +++ b/src/jpeg/libijg/jpegint.h @@ -1,7 +1,7 @@ /* * jpegint.h * - * Copyright (C) 1991-1997, Thomas G. Lane. + * Copyright (C) 1991-1998, Thomas G. Lane. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -13,30 +13,30 @@ /* Declarations for both compression & decompression */ -typedef enum { /* Operating modes for buffer controllers */ - JBUF_PASS_THRU, /* Plain stripwise operation */ - /* Remaining modes require a full-image buffer to have been created */ - JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ - JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ - JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ +typedef enum { /* Operating modes for buffer controllers */ + JBUF_PASS_THRU, /* Plain stripwise operation */ + /* Remaining modes require a full-image buffer to have been created */ + JBUF_SAVE_SOURCE, /* Run source subobject only, save output */ + JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */ + JBUF_SAVE_AND_PASS /* Run both subobjects, save output */ } J_BUF_MODE; /* Values of global_state field (jdapi.c has some dependencies on ordering!) */ -#define CSTATE_START 100 /* after create_compress */ -#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ -#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ -#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ -#define DSTATE_START 200 /* after create_decompress */ -#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ -#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ -#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ -#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ -#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ -#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ -#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ -#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ -#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ -#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ +#define CSTATE_START 100 /* after create_compress */ +#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */ +#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */ +#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */ +#define DSTATE_START 200 /* after create_decompress */ +#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */ +#define DSTATE_READY 202 /* found SOS, ready for start_decompress */ +#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/ +#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */ +#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */ +#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */ +#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */ +#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */ +#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */ +#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */ /* Declarations for compression modules */ @@ -48,72 +48,58 @@ struct jpeg_comp_master { JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); /* State variables made visible to other modules */ - boolean call_pass_startup; /* True if pass_startup must be called */ - boolean is_last_pass; /* True during last pass */ + boolean call_pass_startup; /* True if pass_startup must be called */ + boolean is_last_pass; /* True during last pass */ }; /* Main buffer control (downsampled-data buffer) */ struct jpeg_c_main_controller { JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(void, process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail)); + JSAMPARRAY input_buf, JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail)); }; /* Compression preprocessing (downsampling input buffer control) */ struct jpeg_c_prep_controller { JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(void, pre_process_data, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, - JDIMENSION *in_row_ctr, - JDIMENSION in_rows_avail, - JSAMPIMAGE output_buf, - JDIMENSION *out_row_group_ctr, - JDIMENSION out_row_groups_avail)); + JSAMPARRAY input_buf, + JDIMENSION *in_row_ctr, + JDIMENSION in_rows_avail, + JSAMPIMAGE output_buf, + JDIMENSION *out_row_group_ctr, + JDIMENSION out_row_groups_avail)); }; -/* Coefficient buffer control */ -struct jpeg_c_coef_controller { +/* Compression codec (compressor proper) */ +struct jpeg_c_codec { + JMETHOD(void, entropy_start_pass, (j_compress_ptr cinfo, + boolean gather_statistics)); + JMETHOD(void, entropy_finish_pass, (j_compress_ptr cinfo)); + JMETHOD(boolean, need_optimization_pass, (j_compress_ptr cinfo)); JMETHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(boolean, compress_data, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf)); + JSAMPIMAGE input_buf)); }; /* Colorspace conversion */ struct jpeg_color_converter { JMETHOD(void, start_pass, (j_compress_ptr cinfo)); JMETHOD(void, color_convert, (j_compress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPIMAGE output_buf, - JDIMENSION output_row, int num_rows)); + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows)); }; /* Downsampling */ struct jpeg_downsampler { JMETHOD(void, start_pass, (j_compress_ptr cinfo)); JMETHOD(void, downsample, (j_compress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION in_row_index, - JSAMPIMAGE output_buf, - JDIMENSION out_row_group_index)); + JSAMPIMAGE input_buf, JDIMENSION in_row_index, + JSAMPIMAGE output_buf, + JDIMENSION out_row_group_index)); - boolean need_context_rows; /* TRUE if need rows above & below */ -}; - -/* Forward DCT (also controls coefficient quantization) */ -struct jpeg_forward_dct { - JMETHOD(void, start_pass, (j_compress_ptr cinfo)); - /* perhaps this should be an array??? */ - JMETHOD(void, forward_DCT, (j_compress_ptr cinfo, - jpeg_component_info * compptr, - JSAMPARRAY sample_data, JBLOCKROW coef_blocks, - JDIMENSION start_row, JDIMENSION start_col, - JDIMENSION num_blocks)); -}; - -/* Entropy encoding */ -struct jpeg_entropy_encoder { - JMETHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics)); - JMETHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data)); - JMETHOD(void, finish_pass, (j_compress_ptr cinfo)); + boolean need_context_rows; /* TRUE if need rows above & below */ }; /* Marker writing */ @@ -126,7 +112,7 @@ struct jpeg_marker_writer { /* These routines are exported to allow insertion of extra markers */ /* Probably only COM and APPn markers should be written this way */ JMETHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker, - unsigned int datalen)); + unsigned int datalen)); JMETHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val)); }; @@ -139,7 +125,7 @@ struct jpeg_decomp_master { JMETHOD(void, finish_output_pass, (j_decompress_ptr cinfo)); /* State variables made visible to other modules */ - boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ + boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */ }; /* Input control module */ @@ -150,39 +136,38 @@ struct jpeg_input_controller { JMETHOD(void, finish_input_pass, (j_decompress_ptr cinfo)); /* State variables made visible to other modules */ - boolean has_multiple_scans; /* True if file has multiple scans */ - boolean eoi_reached; /* True when EOI has been consumed */ + boolean has_multiple_scans; /* True if file has multiple scans */ + boolean eoi_reached; /* True when EOI has been consumed */ }; /* Main buffer control (downsampled-data buffer) */ struct jpeg_d_main_controller { JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(void, process_data, (j_decompress_ptr cinfo, - JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); + JSAMPARRAY output_buf, JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); }; -/* Coefficient buffer control */ -struct jpeg_d_coef_controller { +/* Decompression codec (decompressor proper) */ +struct jpeg_d_codec { + JMETHOD(void, calc_output_dimensions, (j_decompress_ptr cinfo)); JMETHOD(void, start_input_pass, (j_decompress_ptr cinfo)); JMETHOD(int, consume_data, (j_decompress_ptr cinfo)); JMETHOD(void, start_output_pass, (j_decompress_ptr cinfo)); JMETHOD(int, decompress_data, (j_decompress_ptr cinfo, - JSAMPIMAGE output_buf)); - /* Pointer to array of coefficient virtual arrays, or NULL if none */ - jvirt_barray_ptr *coef_arrays; + JSAMPIMAGE output_buf)); }; /* Decompression postprocessing (color quantization buffer control) */ struct jpeg_d_post_controller { JMETHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)); JMETHOD(void, post_process_data, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); }; /* Marker reading & parsing */ @@ -199,63 +184,40 @@ struct jpeg_marker_reader { /* State of marker reader --- nominally internal, but applications * supplying COM or APPn handlers might like to know the state. */ - boolean saw_SOI; /* found SOI? */ - boolean saw_SOF; /* found SOF? */ - int next_restart_num; /* next restart number expected (0-7) */ - unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ -}; - -/* Entropy decoding */ -struct jpeg_entropy_decoder { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - JMETHOD(boolean, decode_mcu, (j_decompress_ptr cinfo, - JBLOCKROW *MCU_data)); - - /* This is here to share code between baseline and progressive decoders; */ - /* other modules probably should not use it */ - boolean insufficient_data; /* set TRUE after emitting warning */ -}; - -/* Inverse DCT (also performs dequantization) */ -typedef JMETHOD(void, inverse_DCT_method_ptr, - (j_decompress_ptr cinfo, jpeg_component_info * compptr, - JCOEFPTR coef_block, - JSAMPARRAY output_buf, JDIMENSION output_col)); - -struct jpeg_inverse_dct { - JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); - /* It is useful to allow each component to have a separate IDCT method. */ - inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS]; + boolean saw_SOI; /* found SOI? */ + boolean saw_SOF; /* found SOF? */ + int next_restart_num; /* next restart number expected (0-7) */ + unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */ }; /* Upsampling (note that upsampler must also call color converter) */ struct jpeg_upsampler { JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); JMETHOD(void, upsample, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, - JDIMENSION *in_row_group_ctr, - JDIMENSION in_row_groups_avail, - JSAMPARRAY output_buf, - JDIMENSION *out_row_ctr, - JDIMENSION out_rows_avail)); - - boolean need_context_rows; /* TRUE if need rows above & below */ + JSAMPIMAGE input_buf, + JDIMENSION *in_row_group_ctr, + JDIMENSION in_row_groups_avail, + JSAMPARRAY output_buf, + JDIMENSION *out_row_ctr, + JDIMENSION out_rows_avail)); + + boolean need_context_rows; /* TRUE if need rows above & below */ }; /* Colorspace conversion */ struct jpeg_color_deconverter { JMETHOD(void, start_pass, (j_decompress_ptr cinfo)); JMETHOD(void, color_convert, (j_decompress_ptr cinfo, - JSAMPIMAGE input_buf, JDIMENSION input_row, - JSAMPARRAY output_buf, int num_rows)); + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows)); }; /* Color quantization or color precision reduction */ struct jpeg_color_quantizer { JMETHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan)); JMETHOD(void, color_quantize, (j_decompress_ptr cinfo, - JSAMPARRAY input_buf, JSAMPARRAY output_buf, - int num_rows)); + JSAMPARRAY input_buf, JSAMPARRAY output_buf, + int num_rows)); JMETHOD(void, finish_pass, (j_decompress_ptr cinfo)); JMETHOD(void, new_color_map, (j_decompress_ptr cinfo)); }; @@ -264,9 +226,9 @@ struct jpeg_color_quantizer { /* Miscellaneous useful macros */ #undef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) #undef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) /* We assume that right shift corresponds to signed division by 2 with @@ -280,85 +242,96 @@ struct jpeg_color_quantizer { */ #ifdef RIGHT_SHIFT_IS_UNSIGNED -#define SHIFT_TEMPS INT32 shift_temp; +#define SHIFT_TEMPS INT32 shift_temp; #define RIGHT_SHIFT(x,shft) \ - ((shift_temp = (x)) < 0 ? \ - (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ - (shift_temp >> (shft))) + ((shift_temp = (x)) < 0 ? \ + (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \ + (shift_temp >> (shft))) #else #define SHIFT_TEMPS -#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) +#define RIGHT_SHIFT(x,shft) ((x) >> (shft)) #endif /* Short forms of external names for systems with brain-damaged linkers. */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jinit_compress_master jICompress -#define jinit_c_master_control jICMaster -#define jinit_c_main_controller jICMainC -#define jinit_c_prep_controller jICPrepC -#define jinit_c_coef_controller jICCoefC -#define jinit_color_converter jICColor -#define jinit_downsampler jIDownsampler -#define jinit_forward_dct jIFDCT -#define jinit_huff_encoder jIHEncoder -#define jinit_phuff_encoder jIPHEncoder -#define jinit_marker_writer jIMWriter -#define jinit_master_decompress jIDMaster -#define jinit_d_main_controller jIDMainC -#define jinit_d_coef_controller jIDCoefC -#define jinit_d_post_controller jIDPostC -#define jinit_input_controller jIInCtlr -#define jinit_marker_reader jIMReader -#define jinit_huff_decoder jIHDecoder -#define jinit_phuff_decoder jIPHDecoder -#define jinit_inverse_dct jIIDCT -#define jinit_upsampler jIUpsampler -#define jinit_color_deconverter jIDColor -#define jinit_1pass_quantizer jI1Quant -#define jinit_2pass_quantizer jI2Quant -#define jinit_merged_upsampler jIMUpsampler -#define jinit_memory_mgr jIMemMgr -#define jdiv_round_up jDivRound -#define jround_up jRound -#define jcopy_sample_rows jCopySamples -#define jcopy_block_row jCopyBlocks -#define jzero_far jZeroFar -#define jpeg_zigzag_order jZIGTable -#define jpeg_natural_order jZAGTable +#define jinit_c_codec jICCodec +#define jinit_c_diff_controller jICDiffC +#define jinit_lossy_c_codec jILossyC +#define jinit_lossless_c_codec jILosslessC +#define jinit_compress_master jICompress +#define jinit_c_master_control jICMaster +#define jinit_c_main_controller jICMainC +#define jinit_c_prep_controller jICPrepC +#define jinit_c_coef_controller jICCoefC +#define jinit_color_converter jICColor +#define jinit_downsampler jIDownsampler +#define jinit_forward_dct jIFDCT +#define jinit_shuff_encoder jISHEncoder +#define jinit_phuff_encoder jIPHEncoder +#define jinit_arith_encoder jIAEncoder +#define jinit_marker_writer jIMWriter +#define jinit_d_codec jIDCodec +#define jinit_lossy_d_codec jILossyD +#define jinit_lossless_d_codec jILosslsD +#define jinit_master_decompress jIDMaster +#define jinit_d_main_controller jIDMainC +#define jinit_d_coef_controller jIDCoefC +#define jinit_d_diff_controller jIDDiffC +#define jinit_d_post_controller jIDPostC +#define jinit_input_controller jIInCtlr +#define jinit_marker_reader jIMReader +#define jinit_shuff_decoder jISHDecoder +#define jinit_phuff_decoder jIPHDecoder +#define jinit_arith_decoder jIADecoder +#define jinit_lhuff_decoder jILHDecoder +#define jinit_undifferencer jIUndiff +#define jinit_d_scaler jIDScaler +#define jinit_inverse_dct jIIDCT +#define jinit_upsampler jIUpsampler +#define jinit_color_deconverter jIDColor +#define jinit_1pass_quantizer jI1Quant +#define jinit_2pass_quantizer jI2Quant +#define jinit_merged_upsampler jIMUpsampler +#define jinit_memory_mgr jIMemMgr +#define jdiv_round_up jDivRound +#define jround_up jRound +#define jcopy_sample_rows jCopySamples +#define jcopy_block_row jCopyBlocks +#define jzero_far jZeroFar +#define jpeg_zigzag_order jZIGTable +#define jpeg_natural_order jZAGTable #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Compression module initialization routines */ +EXTERN(void) jinit_c_codec JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_c_diff_controller JPP((j_compress_ptr cinfo, boolean need_full_buffer)); EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo, - boolean transcode_only)); + boolean transcode_only)); EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); + boolean need_full_buffer)); EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo, - boolean need_full_buffer)); + boolean need_full_buffer)); +EXTERN(void) jinit_compressor JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo)); -EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo)); EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo)); +EXTERN(void) jinit_arith_encoder JPP((j_compress_ptr cinfo)); /* Decompression module initialization routines */ +EXTERN(void) jinit_d_codec JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_d_diff_controller JPP((j_decompress_ptr cinfo, boolean need_full_buffer)); EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); -EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); + boolean need_full_buffer)); +EXTERN(void) jinit_decompressor JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo, - boolean need_full_buffer)); + boolean need_full_buffer)); EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo)); -EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo)); +EXTERN(void) jinit_arith_decoder JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo)); EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo)); @@ -371,13 +344,13 @@ EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo)); EXTERN(long) jdiv_round_up JPP((long a, long b)); EXTERN(long) jround_up JPP((long a, long b)); EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols)); + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols)); EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks)); + JDIMENSION num_blocks)); EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero)); /* Constant tables in jutils.c */ -#if 0 /* This table is not actually needed in v6a */ +#if 0 /* This table is not actually needed in v6a */ extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */ #endif extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ @@ -385,7 +358,7 @@ extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */ /* Suppress undefined-structure complaints if necessary. */ #ifdef INCOMPLETE_TYPES_BROKEN -#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ +#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */ struct jvirt_sarray_control { long dummy; }; struct jvirt_barray_control { long dummy; }; #endif diff --git a/src/jpeg/libijg/jpeglib.h b/src/jpeg/libijg/jpeglib.h index d1be8dde..02c2d186 100644 --- a/src/jpeg/libijg/jpeglib.h +++ b/src/jpeg/libijg/jpeglib.h @@ -20,17 +20,17 @@ * 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 */ /* Version ID for the JPEG library. * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60". */ -#define JPEG_LIB_VERSION 62 /* Version 6b */ +#define JPEG_LIB_VERSION 62 /* Version 6b */ /* Various constants determining the sizes of things. @@ -38,23 +38,24 @@ * 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 + * the PostScript DCT filter can emit files with many more than 10 data units + * per MCU. + * If you happen to run across such a file, you can up D_MAX_DATA_UNITS_IN_MCU * to handle it. We even let you do this from the jconfig.h file. However, - * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe + * we strongly discourage changing C_MAX_DATA_UNITS_IN_MCU; just because Adobe * sometimes emits noncompliant files doesn't mean you should too. */ -#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */ -#ifndef D_MAX_BLOCKS_IN_MCU -#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */ +#define C_MAX_DATA_UNITS_IN_MCU 10 /* compressor's limit on data units/MCU */ +#ifndef D_MAX_DATA_UNITS_IN_MCU +#define D_MAX_DATA_UNITS_IN_MCU 10 /* decompressor's limit on data units/MCU */ #endif @@ -63,16 +64,20 @@ * but the pointer arrays can fit in near memory. */ -typedef JSAMPLE FAR *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 JSAMPLE FAR *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 JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ -typedef JBLOCK FAR *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 JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */ +typedef JBLOCK FAR *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 JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ +typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */ + +typedef JDIFF FAR *JDIFFROW; /* pointer to one row of difference values */ +typedef JDIFFROW *JDIFFARRAY; /* ptr to some rows (a 2-D diff array) */ +typedef JDIFFARRAY *JDIFFIMAGE; /* a 3-D diff array: top index is color */ /* Types for JPEG compression parameters and working tables. */ @@ -85,13 +90,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; @@ -99,15 +104,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; @@ -117,56 +122,58 @@ 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 + /* Component's size in data units. + * Any dummy data units added to complete an MCU are not counted; therefore * these values do not depend on whether a scan is interleaved or not. */ - JDIMENSION width_in_blocks; - JDIMENSION height_in_blocks; - /* Size of a DCT block in samples. Always DCTSIZE for compression. - * For decompression this is the size of the output from one DCT block, - * reflecting any scaling we choose to apply during the IDCT step. - * Values of 1,2,4,8 are likely to be supported. Note that different - * components may receive different IDCT scalings. + JDIMENSION width_in_data_units; + JDIMENSION height_in_data_units; + /* Size of a data unit in/output by the codec (in samples). Always + * data_unit for compression. For decompression this is the size of the + * output from one data_unit, reflecting any processing performed by the + * codec. For example, in the DCT-based codec, scaling may be applied + * during the IDCT step. Values of 1,2,4,8 are likely to be supported. + * Note that different components may have different codec_data_unit sizes. */ - int DCT_scaled_size; + int codec_data_unit; /* The downsampled dimensions are the component's actual, unpadded number * of samples at the main buffer (preprocessing/compression interface), thus * downsampled_width = ceil(image_width * Hi/Hmax) - * and similarly for height. For decompression, IDCT scaling is included, so - * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE) + * and similarly for height. For decompression, codec-based processing is + * included (ie, IDCT scaling), so + * downsampled_width = ceil(image_width * Hi/Hmax * codec_data_unit/data_unit) */ - 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_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 data units per MCU, horizontally */ + int MCU_height; /* number of data units per MCU, vertically */ + int MCU_data_units; /* MCU_width * MCU_height */ + int MCU_sample_width; /* MCU width in samples, MCU_width*codec_data_unit */ + int last_col_width; /* # of non-dummy data_units across in last MCU */ + int last_row_height; /* # of non-dummy data_units down in last MCU */ /* Saved quantization table for component; NULL if none yet saved. * See jdinput.c comments about the need for this information. @@ -182,10 +189,12 @@ 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 + lossless JPEG predictor select parm (Ss) */ + int Ah, Al; /* progressive JPEG successive approx. parms + lossless JPEG point transform parm (Al) */ } jpeg_scan_info; /* The decompressor can save APPn and COM markers in a list of these: */ @@ -193,65 +202,73 @@ typedef struct { typedef struct jpeg_marker_struct FAR * 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[] */ - JOCTET FAR * data; /* the data contained in the marker */ + 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 FAR * data; /* the data contained in the marker */ /* the marker length word is not counted in data_length or original_length */ }; +/* Known codec processes. */ + +typedef enum { + JPROC_SEQUENTIAL, /* baseline/extended sequential DCT */ + JPROC_PROGRESSIVE, /* progressive DCT */ + JPROC_LOSSLESS /* lossless (sequential) */ +} J_CODEC_PROCESS; + /* Known color spaces. */ typedef enum { - JCS_UNKNOWN, /* error/unspecified */ - JCS_GRAYSCALE, /* monochrome */ - JCS_RGB, /* 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_UNKNOWN, /* error/unspecified */ + JCS_GRAYSCALE, /* monochrome */ + JCS_RGB, /* red/green/blue */ + JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */ + JCS_CMYK, /* C/M/Y/K */ + JCS_YCCK /* Y/Cb/Cr/K */ } J_COLOR_SPACE; /* 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++.) @@ -266,7 +283,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; @@ -276,12 +293,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 @@ -291,9 +308,11 @@ struct jpeg_compress_struct { * helper routines to simplify changing parameters. */ - int data_precision; /* bits of precision in image data */ + boolean lossless; /* TRUE=lossless encoding, FALSE=lossy */ - int num_components; /* # of color components in JPEG image */ + int data_precision; /* bits of precision in image data */ + + int num_components; /* # of color components in JPEG image */ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */ jpeg_component_info * comp_info; @@ -310,19 +329,19 @@ 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 */ - int smoothing_factor; /* 1..100, or 0 for no input smoothing */ - J_DCT_METHOD dct_method; /* DCT algorithm selector */ + 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 */ + int smoothing_factor; /* 1..100, or 0 for no input smoothing */ + J_DCT_METHOD dct_method; /* DCT algorithm selector */ /* The restart interval can be specified in absolute MCUs by setting * restart_interval, or in MCU rows by setting restart_in_rows @@ -330,28 +349,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. @@ -360,14 +379,16 @@ 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 */ - - 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 + int data_unit; /* size of data unit in samples */ + J_CODEC_PROCESS process; /* encoding process of JPEG image */ + + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to codec */ + /* The codec 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 * data_unit sample rows of each component in an * "iMCU" (interleaved MCU) row. */ @@ -375,19 +396,19 @@ struct jpeg_compress_struct { * 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 */ + 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]; + int data_units_in_MCU; /* # of data units per MCU */ + int MCU_membership[C_MAX_DATA_UNITS_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/lossless JPEG parameters for scan */ /* * Links to compression subobjects (methods and private variables of modules) @@ -395,12 +416,10 @@ struct jpeg_compress_struct { struct jpeg_comp_master * master; struct jpeg_c_main_controller * main; struct jpeg_c_prep_controller * prep; - struct jpeg_c_coef_controller * coef; + struct jpeg_c_codec * codec; struct jpeg_marker_writer * marker; struct jpeg_color_converter * cconvert; struct jpeg_downsampler * downsample; - struct jpeg_forward_dct * fdct; - struct jpeg_entropy_encoder * entropy; jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */ int script_space_size; }; @@ -409,7 +428,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; @@ -417,9 +436,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 @@ -431,24 +450,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(). @@ -456,14 +475,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. @@ -475,8 +494,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. @@ -486,20 +505,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. @@ -508,7 +527,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 @@ -530,13 +549,12 @@ 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 */ - boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */ - boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */ + 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 */ @@ -547,17 +565,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 @@ -572,18 +590,21 @@ 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 min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */ - - 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 - * interleaved or not. We define an iMCU row as v_samp_factor DCT block - * rows of each component. Therefore, the IDCT output contains - * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row. + int data_unit; /* size of data unit in samples */ + J_CODEC_PROCESS process; /* decoding process of JPEG image */ + + int max_h_samp_factor; /* largest h_samp_factor */ + int max_v_samp_factor; /* largest v_samp_factor */ + + int min_codec_data_unit; /* smallest codec_data_unit of any component */ + + JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */ + /* The codec'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 interleaved + * or not. We define an iMCU row as v_samp_factor data_unit rows of each + * component. Therefore, the codec output contains + * v_samp_factor*codec_data_unit sample rows of a component per iMCU row. */ JSAMPLE * sample_range_limit; /* table for fast range-limiting */ @@ -593,19 +614,19 @@ 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 MCU_membership[D_MAX_BLOCKS_IN_MCU]; + int data_units_in_MCU; /* # of data _units per MCU */ + int MCU_membership[D_MAX_DATA_UNITS_IN_MCU]; /* MCU_membership[i] is index in cur_comp_info of component owning */ - /* i'th block in an MCU */ + /* i'th data unit in an MCU */ - int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */ + int Ss, Se, Ah, Al; /* progressive/lossless JPEG parms for scan */ /* This field is shared between entropy decoder and marker parser. * It is either zero or the code of a JPEG marker that has been @@ -618,12 +639,10 @@ struct jpeg_decompress_struct { */ struct jpeg_decomp_master * master; struct jpeg_d_main_controller * main; - struct jpeg_d_coef_controller * coef; + struct jpeg_d_codec * codec; struct jpeg_d_post_controller * post; struct jpeg_input_controller * inputctl; struct jpeg_marker_reader * marker; - struct jpeg_entropy_decoder * entropy; - struct jpeg_inverse_dct * idct; struct jpeg_upsampler * upsample; struct jpeg_color_deconverter * cconvert; struct jpeg_color_quantizer * cquantize; @@ -649,7 +668,7 @@ struct jpeg_error_mgr { JMETHOD(void, output_message, (j_common_ptr cinfo)); /* Format a message string for the most recent JPEG error or message */ JMETHOD(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 */ JMETHOD(void, reset_error_mgr, (j_common_ptr cinfo)); @@ -665,7 +684,7 @@ struct jpeg_error_mgr { /* 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 @@ -673,7 +692,7 @@ struct jpeg_error_mgr { * 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 @@ -691,8 +710,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 */ }; @@ -701,18 +720,18 @@ struct jpeg_error_mgr { struct jpeg_progress_mgr { JMETHOD(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 */ JMETHOD(void, init_destination, (j_compress_ptr cinfo)); JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo)); @@ -724,7 +743,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 */ JMETHOD(void, init_source, (j_decompress_ptr cinfo)); JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo)); @@ -745,49 +764,62 @@ 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; +#ifdef C_LOSSLESS_SUPPORTED +#define NEED_DARRAY +#else +#ifdef D_LOSSLESS_SUPPORTED +#define NEED_DARRAY +#endif +#endif + struct jpeg_memory_mgr { /* Method pointers */ JMETHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); + size_t sizeofobject)); JMETHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id, - size_t sizeofobject)); + size_t sizeofobject)); JMETHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id, - JDIMENSION samplesperrow, - JDIMENSION numrows)); + JDIMENSION samplesperrow, + JDIMENSION numrows)); JMETHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id, - JDIMENSION blocksperrow, - JDIMENSION numrows)); + JDIMENSION blocksperrow, + JDIMENSION numrows)); +#ifdef NEED_DARRAY + JMETHOD(JDIFFARRAY, alloc_darray, (j_common_ptr cinfo, int pool_id, + JDIMENSION diffsperrow, + JDIMENSION numrows)); +#endif JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION samplesperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); + int pool_id, + boolean pre_zero, + JDIMENSION samplesperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo, - int pool_id, - boolean pre_zero, - JDIMENSION blocksperrow, - JDIMENSION numrows, - JDIMENSION maxaccess)); + int pool_id, + boolean pre_zero, + JDIMENSION blocksperrow, + JDIMENSION numrows, + JDIMENSION maxaccess)); JMETHOD(void, realize_virt_arrays, (j_common_ptr cinfo)); JMETHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo, - jvirt_sarray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); + jvirt_sarray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo, - jvirt_barray_ptr ptr, - JDIMENSION start_row, - JDIMENSION num_rows, - boolean writable)); + jvirt_barray_ptr ptr, + JDIMENSION start_row, + JDIMENSION num_rows, + boolean writable)); JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id)); JMETHOD(void, self_destruct, (j_common_ptr cinfo)); @@ -815,9 +847,9 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); */ #ifdef HAVE_PROTOTYPES -#define JPP(arglist) arglist +#define JPP(arglist) arglist #else -#define JPP(arglist) () +#define JPP(arglist) () #endif @@ -829,60 +861,61 @@ typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo)); */ #ifdef NEED_SHORT_EXTERNAL_NAMES -#define jpeg_std_error jStdError -#define jpeg_CreateCompress jCreaCompress -#define jpeg_CreateDecompress jCreaDecompress -#define jpeg_destroy_compress jDestCompress -#define jpeg_destroy_decompress jDestDecompress -#define jpeg_stdio_dest jStdDest -#define jpeg_stdio_src jStdSrc -#define jpeg_set_defaults jSetDefaults -#define jpeg_set_colorspace jSetColorspace -#define jpeg_default_colorspace jDefColorspace -#define jpeg_set_quality jSetQuality -#define jpeg_set_linear_quality jSetLQuality -#define jpeg_add_quant_table jAddQuantTable -#define jpeg_quality_scaling jQualityScaling -#define jpeg_simple_progression jSimProgress -#define jpeg_suppress_tables jSuppressTables -#define jpeg_alloc_quant_table jAlcQTable -#define jpeg_alloc_huff_table jAlcHTable -#define jpeg_start_compress jStrtCompress -#define jpeg_write_scanlines jWrtScanlines -#define jpeg_finish_compress jFinCompress -#define jpeg_write_raw_data jWrtRawData -#define jpeg_write_marker jWrtMarker -#define jpeg_write_m_header jWrtMHeader -#define jpeg_write_m_byte jWrtMByte -#define jpeg_write_tables jWrtTables -#define jpeg_read_header jReadHeader -#define jpeg_start_decompress jStrtDecompress -#define jpeg_read_scanlines jReadScanlines -#define jpeg_finish_decompress jFinDecompress -#define jpeg_read_raw_data jReadRawData -#define jpeg_has_multiple_scans jHasMultScn -#define jpeg_start_output jStrtOutput -#define jpeg_finish_output jFinOutput -#define jpeg_input_complete jInComplete -#define jpeg_new_colormap jNewCMap -#define jpeg_consume_input jConsumeInput -#define jpeg_calc_output_dimensions jCalcDimensions -#define jpeg_save_markers jSaveMarkers -#define jpeg_set_marker_processor jSetMarker -#define jpeg_read_coefficients jReadCoefs -#define jpeg_write_coefficients jWrtCoefs -#define jpeg_copy_critical_parameters jCopyCrit -#define jpeg_abort_compress jAbrtCompress -#define jpeg_abort_decompress jAbrtDecompress -#define jpeg_abort jAbort -#define jpeg_destroy jDestroy -#define jpeg_resync_to_restart jResyncRestart +#define jpeg_std_error jStdError +#define jpeg_CreateCompress jCreaCompress +#define jpeg_CreateDecompress jCreaDecompress +#define jpeg_destroy_compress jDestCompress +#define jpeg_destroy_decompress jDestDecompress +#define jpeg_stdio_dest jStdDest +#define jpeg_stdio_src jStdSrc +#define jpeg_set_defaults jSetDefaults +#define jpeg_set_colorspace jSetColorspace +#define jpeg_default_colorspace jDefColorspace +#define jpeg_set_quality jSetQuality +#define jpeg_set_linear_quality jSetLQuality +#define jpeg_add_quant_table jAddQuantTable +#define jpeg_quality_scaling jQualityScaling +#define jpeg_simple_lossless jSimLossless +#define jpeg_simple_progression jSimProgress +#define jpeg_suppress_tables jSuppressTables +#define jpeg_alloc_quant_table jAlcQTable +#define jpeg_alloc_huff_table jAlcHTable +#define jpeg_start_compress jStrtCompress +#define jpeg_write_scanlines jWrtScanlines +#define jpeg_finish_compress jFinCompress +#define jpeg_write_raw_data jWrtRawData +#define jpeg_write_marker jWrtMarker +#define jpeg_write_m_header jWrtMHeader +#define jpeg_write_m_byte jWrtMByte +#define jpeg_write_tables jWrtTables +#define jpeg_read_header jReadHeader +#define jpeg_start_decompress jStrtDecompress +#define jpeg_read_scanlines jReadScanlines +#define jpeg_finish_decompress jFinDecompress +#define jpeg_read_raw_data jReadRawData +#define jpeg_has_multiple_scans jHasMultScn +#define jpeg_start_output jStrtOutput +#define jpeg_finish_output jFinOutput +#define jpeg_input_complete jInComplete +#define jpeg_new_colormap jNewCMap +#define jpeg_consume_input jConsumeInput +#define jpeg_calc_output_dimensions jCalcDimensions +#define jpeg_save_markers jSaveMarkers +#define jpeg_set_marker_processor jSetMarker +#define jpeg_read_coefficients jReadCoefs +#define jpeg_write_coefficients jWrtCoefs +#define jpeg_copy_critical_parameters jCopyCrit +#define jpeg_abort_compress jAbrtCompress +#define jpeg_abort_decompress jAbrtDecompress +#define jpeg_abort jAbort +#define jpeg_destroy jDestroy +#define jpeg_resync_to_restart jResyncRestart #endif /* NEED_SHORT_EXTERNAL_NAMES */ /* Default error-management setup */ EXTERN(struct jpeg_error_mgr *) jpeg_std_error - JPP((struct jpeg_error_mgr * err)); + JPP((struct jpeg_error_mgr * err)); /* Initialization of JPEG compression objects. * jpeg_create_compress() and jpeg_create_decompress() are the exported @@ -893,14 +926,14 @@ EXTERN(struct jpeg_error_mgr *) jpeg_std_error */ #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 JPP((j_compress_ptr cinfo, - int version, size_t structsize)); + int version, size_t structsize)); EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo, - int version, size_t structsize)); + int version, size_t structsize)); /* Destruction of JPEG compression objects */ EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); @@ -914,57 +947,59 @@ EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile)); EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo)); /* Compression parameter setup aids */ EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo, - J_COLOR_SPACE colorspace)); + J_COLOR_SPACE colorspace)); EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality, - boolean force_baseline)); + boolean force_baseline)); EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo, - int scale_factor, - boolean force_baseline)); + int scale_factor, + boolean force_baseline)); EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl, - const unsigned int *basic_table, - int scale_factor, - boolean force_baseline)); + const unsigned int *basic_table, + int scale_factor, + boolean force_baseline)); EXTERN(int) jpeg_quality_scaling JPP((int quality)); +EXTERN(void) jpeg_simple_lossless JPP((j_compress_ptr cinfo, + int predictor, int point_transform)); EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo)); EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo, - boolean suppress)); + boolean suppress)); EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo)); EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo)); /* Main entry points for compression */ EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo, - boolean write_all_tables)); + boolean write_all_tables)); EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION num_lines)); + JSAMPARRAY scanlines, + JDIMENSION num_lines)); EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo)); /* Replaces jpeg_write_scanlines when writing raw downsampled data. */ EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION num_lines)); + JSAMPIMAGE data, + JDIMENSION num_lines)); /* Write a special marker. See libjpeg.doc concerning safe usage. */ EXTERN(void) jpeg_write_marker - JPP((j_compress_ptr cinfo, int marker, - const JOCTET * dataptr, unsigned int datalen)); + JPP((j_compress_ptr cinfo, int marker, + const JOCTET * dataptr, unsigned int datalen)); /* Same, but piecemeal. */ EXTERN(void) jpeg_write_m_header - JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); + JPP((j_compress_ptr cinfo, int marker, unsigned int datalen)); EXTERN(void) jpeg_write_m_byte - JPP((j_compress_ptr cinfo, int val)); + JPP((j_compress_ptr cinfo, int val)); /* Alternate compression function: just write an abbreviated table file */ EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo)); /* Decompression startup: read start of JPEG datastream to see what's there */ EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, - boolean require_image)); + 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 @@ -974,49 +1009,49 @@ EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo, /* Main entry points for decompression */ EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo)); EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo, - JSAMPARRAY scanlines, - JDIMENSION max_lines)); + JSAMPARRAY scanlines, + JDIMENSION max_lines)); EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo)); /* Replaces jpeg_read_scanlines when reading raw downsampled data. */ EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo, - JSAMPIMAGE data, - JDIMENSION max_lines)); + JSAMPIMAGE data, + JDIMENSION max_lines)); /* Additional entry points for buffered-image mode. */ EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo, - int scan_number)); + int scan_number)); EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo)); EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo)); EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo)); EXTERN(int) jpeg_consume_input JPP((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. */ EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo)); /* Control saving of COM and APPn markers into marker_list. */ EXTERN(void) jpeg_save_markers - JPP((j_decompress_ptr cinfo, int marker_code, - unsigned int length_limit)); + JPP((j_decompress_ptr cinfo, int marker_code, + unsigned int length_limit)); /* Install a special processing method for COM or APPn markers. */ EXTERN(void) jpeg_set_marker_processor - JPP((j_decompress_ptr cinfo, int marker_code, - jpeg_marker_parser_method routine)); + JPP((j_decompress_ptr cinfo, int marker_code, + jpeg_marker_parser_method routine)); /* Read or write raw DCT coefficients --- useful for lossless transcoding. */ EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo)); EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo, - jvirt_barray_ptr * coef_arrays)); + jvirt_barray_ptr * coef_arrays)); EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo, - j_compress_ptr dstinfo)); + j_compress_ptr dstinfo)); /* If you choose to abort compression or decompression before completing * jpeg_finish_(de)compress, then you need to clean up to release memory, @@ -1035,17 +1070,17 @@ EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo)); /* Default restart-marker-resync procedure for use by data source modules */ EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, - int desired)); + int desired)); /* These marker codes are exported since applications and data source modules * 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) @@ -1054,7 +1089,7 @@ EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo, */ #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; }; @@ -1089,8 +1124,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 #endif /* JPEGLIB_H */ diff --git a/src/jpeg/libijg/jquant1.c b/src/jpeg/libijg/jquant1.c index 2ec9a41e..9a0e2844 100644 --- a/src/jpeg/libijg/jquant1.c +++ b/src/jpeg/libijg/jquant1.c @@ -246,8 +246,6 @@ output_value (j_decompress_ptr cinfo, int ci, int j, int maxj) /* Return j'th output value, where j will range from 0 to maxj */ /* The output values must fall in 0..MAXJSAMPLE in increasing order */ { - cinfo = 0; - ci = 0; /* We always provide values 0 and MAXJSAMPLE for each component; * any additional values are equally spaced between these limits. * (Forcing the upper and lower values to the limits ensures that @@ -262,8 +260,6 @@ largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj) /* Return largest input value that should map to j'th output value */ /* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */ { - cinfo = 0; - ci = 0; /* Breakpoints are halfway between values returned by output_value */ return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj)); } @@ -748,7 +744,6 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) size_t arraysize; int i; - is_pre_scan = 0; /* Install my colormap. */ cinfo->colormap = cquantize->sv_colormap; cinfo->actual_number_of_colors = cquantize->sv_actual; @@ -802,7 +797,6 @@ start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan) METHODDEF(void) finish_pass_1_quant (j_decompress_ptr cinfo) { - cinfo = 0; /* no work in 1-pass case */ } diff --git a/src/jpeg/libijg/jquant2.c b/src/jpeg/libijg/jquant2.c index 9355f011..c145f766 100644 --- a/src/jpeg/libijg/jquant2.c +++ b/src/jpeg/libijg/jquant2.c @@ -232,7 +232,6 @@ prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf, JDIMENSION col; JDIMENSION width = cinfo->output_width; - output_buf = 0; for (row = 0; row < num_rows; row++) { ptr = input_buf[row]; for (col = width; col > 0; col--) { @@ -1156,7 +1155,6 @@ finish_pass1 (j_decompress_ptr cinfo) METHODDEF(void) finish_pass2 (j_decompress_ptr cinfo) { - cinfo = 0; /* no work */ } diff --git a/src/jpeg/libijg/jutils.c b/src/jpeg/libijg/jutils.c index d18a9555..23abeb88 100644 --- a/src/jpeg/libijg/jutils.c +++ b/src/jpeg/libijg/jutils.c @@ -21,7 +21,7 @@ * of a DCT block read in natural order (left to right, top to bottom). */ -#if 0 /* This table is not actually needed in v6a */ +#if 0 /* This table is not actually needed in v6a */ const int jpeg_zigzag_order[DCTSIZE2] = { 0, 1, 5, 6, 14, 15, 27, 28, @@ -96,21 +96,21 @@ jround_up (long a, long b) * is not all that great, because these routines aren't very heavily used.) */ -#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ -#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) -#define FMEMZERO(target,size) MEMZERO(target,size) -#else /* 80x86 case, define if we can */ +#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */ +#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size) +#define FMEMZERO(target,size) MEMZERO(target,size) +#else /* 80x86 case, define if we can */ #ifdef USE_FMEM -#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) -#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) +#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size)) +#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size)) #endif #endif GLOBAL(void) jcopy_sample_rows (JSAMPARRAY input_array, int source_row, - JSAMPARRAY output_array, int dest_row, - int num_rows, JDIMENSION num_cols) + JSAMPARRAY output_array, int dest_row, + int num_rows, JDIMENSION num_cols) /* Copy some rows of samples from one place to another. * num_rows rows are copied from input_array[source_row++] * to output_array[dest_row++]; these areas may overlap for duplication. @@ -135,7 +135,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row, FMEMCOPY(outptr, inptr, count); #else for (count = num_cols; count > 0; count--) - *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ + *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */ #endif } } @@ -143,7 +143,7 @@ jcopy_sample_rows (JSAMPARRAY input_array, int source_row, GLOBAL(void) jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row, - JDIMENSION num_blocks) + JDIMENSION num_blocks) /* Copy a row of coefficient blocks from one place to another. */ { #ifdef FMEMCOPY diff --git a/src/jpeg/libijg/jversion.h b/src/jpeg/libijg/jversion.h index 6472c58d..95d81303 100644 --- a/src/jpeg/libijg/jversion.h +++ b/src/jpeg/libijg/jversion.h @@ -9,6 +9,6 @@ */ -#define JVERSION "6b 27-Mar-1998" +#define JVERSION "6b 27-Mar-1998" -#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" +#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane" diff --git a/src/jpeg/libijg/libjpeg.doc b/src/jpeg/libijg/libjpeg.doc index 689b206c..20ce7b48 100644 --- a/src/jpeg/libijg/libjpeg.doc +++ b/src/jpeg/libijg/libjpeg.doc @@ -92,7 +92,6 @@ the ISO JPEG standard; most baseline, extended-sequential, and progressive JPEG processes are supported. (Our subset includes all features now in common use.) Unsupported ISO options include: * Hierarchical storage - * Lossless JPEG * Arithmetic entropy coding (unsupported for legal reasons) * DNL marker * Nonintegral subsampling ratios @@ -870,6 +869,12 @@ jpeg_simple_progression (j_compress_ptr cinfo) unless you want to make a custom scan sequence. You must ensure that the JPEG color space is set correctly before calling this routine. +jpeg_simple_lossless (j_compress_ptr cinfo, int predictor, int point_transform) + Generates a default scan script for writing a lossless-JPEG file. + This is the recommended method of creating a lossless file, + unless you want to make a custom scan sequence. You must ensure that + the JPEG color space is set correctly before calling this routine. + Compression parameters (cinfo fields) include: diff --git a/src/jpeg/libijg/structure.doc b/src/jpeg/libijg/structure.doc index 51c9def7..3d62accf 100644 --- a/src/jpeg/libijg/structure.doc +++ b/src/jpeg/libijg/structure.doc @@ -21,8 +21,10 @@ In this document, JPEG-specific terminology follows the JPEG standard: A "sample" is a single component value (i.e., one number in the image data). A "coefficient" is a frequency coefficient (a DCT transform output number). A "block" is an 8x8 group of samples or coefficients. - An "MCU" (minimum coded unit) is an interleaved set of blocks of size - determined by the sampling factors, or a single block in a + A "data unit" is an abstract data type which is either a block for lossy + (DCT-based) codecs or a sample for lossless (predictive) codecs. + An "MCU" (minimum coded unit) is an interleaved set of data units of size + determined by the sampling factors, or a single data unit in a noninterleaved scan. We do not use the terms "pixel" and "sample" interchangeably. When we say pixel, we mean an element of the full-size image, while a sample is an element @@ -43,13 +45,8 @@ command-line user interface and I/O routines for several uncompressed image formats. This document concentrates on the library itself. We desire the library to be capable of supporting all JPEG baseline, extended -sequential, and progressive DCT processes. Hierarchical processes are not -supported. - -The library does not support the lossless (spatial) JPEG process. Lossless -JPEG shares little or no code with lossy JPEG, and would normally be used -without the extensive pre- and post-processing provided by this library. -We feel that lossless JPEG is better handled by a separate library. +sequential, and progressive DCT processes, as well as the lossless (spatial) +process. Hierarchical processes are not supported. Within these limits, any set of compression parameters allowed by the JPEG spec should be readable for decompression. (We can be more restrictive about @@ -134,9 +131,13 @@ elements: * Color space conversion (e.g., RGB to YCbCr). * Edge expansion and downsampling. Optionally, this step can do simple smoothing --- this is often helpful for low-quality source data. - JPEG proper: + Lossy JPEG proper: * MCU assembly, DCT, quantization. * Entropy coding (sequential or progressive, Huffman or arithmetic). + Lossless JPEG proper: + * Point transform. + * Prediction, differencing. + * Entropy coding (Huffman or arithmetic) In addition to these modules we need overall control, marker generation, and support code (memory management & error handling). There is also a @@ -146,9 +147,13 @@ do something else with the data. The decompressor library contains the following main elements: - JPEG proper: + Lossy JPEG proper: * Entropy decoding (sequential or progressive, Huffman or arithmetic). * Dequantization, inverse DCT, MCU disassembly. + Lossless JPEG proper: + * Entropy decoding (Huffman or arithmetic). + * Prediction, undifferencing. + * Point transform, sample size scaling. Postprocessing: * Upsampling. Optionally, this step may be able to do more general rescaling of the image. @@ -312,6 +317,21 @@ overall system structuring principle, not as a complete description of the task performed by any one controller. +*** Codec object structure *** + +As noted above, this library supports both the lossy (DCT-based) and lossless +JPEG processes. Because these processes have little in common with one another +(and their implementations share very little code), we need to provide a way to +isloate the underlying JPEG process from the rest of the library. This is +accomplished by introducing an abstract "codec object" which acts a generic +interface to the JPEG (de)compressor proper. + +Using the power of the object-oriented scheme described above, we build the +lossy and lossless modules as two separate implementations of the codec object. +Switching between lossy and lossless processes then becomes as trivial as +assigning the appropriate method pointers during initialization of the library. + + *** Compression object structure *** Here is a sketch of the logical structure of the JPEG compression library: @@ -319,10 +339,30 @@ Here is a sketch of the logical structure of the JPEG compression library: |-- Colorspace conversion |-- Preprocessing controller --| | |-- Downsampling + | Main controller --| - | |-- Forward DCT, quantize - |-- Coefficient controller --| - |-- Entropy encoding + | /--> Lossy codec + | / + |-- Compression codec < *OR* + \ + \--> Lossless codec + + +where the lossy codec looks like: + + |-- Forward DCT, quantize +<-- Coefficient controller --| + |-- Entropy encoding + + +and the lossless codec looks like: + + |-- Point transformation + | +<-- Difference controller --|-- Prediction, differencing + | + |-- Lossless entropy encoding + This sketch also describes the flow of control (subroutine calls) during typical image data processing. Each of the components shown in the diagram is @@ -377,6 +417,23 @@ The objects shown above are: during each pass, and the coder must emit the appropriate subset of coefficients. +* Difference controller: buffer controller for the spatial difference data. + When emitting a multiscan JPEG file, this controller is responsible for + buffering the full image. The equivalent of one fully interleaved MCU row + of subsampled data is processed per call, even when the JPEG file is + noninterleaved. + +* Point transformation: Scale the data down by the point transformation + parameter. + +* Prediction and differencing: Calculate the predictor and subtract it + from the input. Works on one scanline per call. The difference + controller supplies the prior scanline which is used for prediction. + +* Lossless entropy encoding: Perform Huffman or arithmetic entropy coding and + emit the coded data to the data destination module. This module handles MCU + assembly. Works on one MCU-row per call. + In addition to the above objects, the compression library includes these objects: @@ -418,15 +475,35 @@ decompression; the progress monitor, if used, may be shared as well. Here is a sketch of the logical structure of the JPEG decompression library: - |-- Entropy decoding - |-- Coefficient controller --| - | |-- Dequantize, Inverse DCT + /--> Lossy codec + / + |-- Decompression codec < *OR* + | \ + | \--> Lossless codec Main controller --| + | | |-- Upsampling |-- Postprocessing controller --| |-- Colorspace conversion |-- Color quantization |-- Color precision reduction + +where the lossy codec looks like: + + |-- Entropy decoding +<-- Coefficient controller --| + |-- Dequantize, Inverse DCT + + +and the lossless codec looks like: + + |-- Lossless entropy decoding + | +<-- Difference controller --|-- Prediction, undifferencing + | + |-- Point transformation, sample size scaling + + As before, this diagram also represents typical control flow. The objects shown are: @@ -460,6 +537,23 @@ shown are: that emit only 1x1, 2x2, or 4x4 samples per DCT block, not the full 8x8. Works on one DCT block at a time. +* Difference controller: buffer controller for the spatial difference data. + When reading a multiscan JPEG file, this controller is responsible for + buffering the full image. The equivalent of one fully interleaved MCU row + is processed per call, even when the source JPEG file is noninterleaved. + +* Lossless entropy decoding: Read coded data from the data source module and + perform Huffman or arithmetic entropy decoding. Works on one MCU-row per + call. + +* Prediction and undifferencing: Calculate the predictor and add it to the + decoded difference. Works on one scanline per call. The difference + controller supplies the prior scanline which is used for prediction. + +* Point transform and sample size scaling: Scale the data up by the point + transformation parameter and scale it down to fit into the compiled-in + sample size. + * Postprocessing controller: buffer controller for the color quantization input buffer, when quantization is in use. (Without quantization, this controller just calls the upsampler.) For two-pass quantization, this