Files
mozjpeg/jsamplecomp.h
DRC e8b40f3c2b Vastly improve 12-bit JPEG integration
The Gordian knot that 7fec5074f9 attempted
to unravel was caused by the fact that there are several
data-precision-dependent (JSAMPLE-dependent) fields and methods in the
exposed libjpeg API structures, and if you change the exposed libjpeg
API structures, then you have to change the whole API.  If you change
the whole API, then you have to provide a whole new library to support
the new API, and that makes it difficult to support multiple data
precisions in the same application.  (It is not impossible, as example.c
demonstrated, but using data-precision-dependent libjpeg API structures
would have made the cjpeg, djpeg, and jpegtran source code hard to read,
so it made more sense to build, install, and package 12-bit-specific
versions of those applications.)

Unfortunately, the result of that initial integration effort was an
unreadable and unmaintainable mess, which is a problem for a library
that is an ISO/ITU-T reference implementation.  Also, as I dug into the
problem of lossless JPEG support, I realized that 16-bit lossless JPEG
images are a thing, and supporting yet another version of the libjpeg
API just for those images is untenable.

In fact, however, the touch points for JSAMPLE in the exposed libjpeg
API structures are minimal:

  - The colormap and sample_range_limit fields in jpeg_decompress_struct
  - The alloc_sarray() and access_virt_sarray() methods in
    jpeg_memory_mgr
  - jpeg_write_scanlines() and jpeg_write_raw_data()
  - jpeg_read_scanlines() and jpeg_read_raw_data()
  - jpeg_skip_scanlines() and jpeg_crop_scanline()
    (This is subtle, but both of those functions use JSAMPLE-dependent
    opaque structures behind the scenes.)

It is much more readable and maintainable to provide 12-bit-specific
versions of those six top-level API functions and to document that the
aforementioned methods and fields must be type-cast when using 12-bit
samples.  Since that eliminates the need to provide a 12-bit-specific
version of the exposed libjpeg API structures, we can:

  - Compile only the precision-dependent libjpeg modules (the
    coefficient buffer controllers, the colorspace converters, the
    DCT/IDCT managers, the main buffer controllers, the preprocessing
    and postprocessing controller, the downsampler and upsamplers, the
    quantizers, the integer DCT methods, and the IDCT methods) for
    multiple data precisions.
  - Introduce 12-bit-specific methods into the various internal
    structures defined in jpegint.h.
  - Create precision-independent data type, macro, method, field, and
    function names that are prefixed by an underscore, and use an
    internal header to convert those into precision-dependent data
    type, macro, method, field, and function names, based on the value
    of BITS_IN_JSAMPLE, when compiling the precision-dependent libjpeg
    modules.
  - Expose precision-dependent jinit*() functions for each of the
    precision-dependent libjpeg modules.
  - Abstract the precision-dependent libjpeg modules by calling the
    appropriate precision-dependent jinit*() function, based on the
    value of cinfo->data_precision, from top-level libjpeg API
    functions.
2022-11-04 12:30:33 -05:00

236 lines
8.9 KiB
C

/*
* jsamplecomp.h
*
* Copyright (C) 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
/* In source files that must be compiled for multiple data precisions, we
* prefix all precision-dependent data types, macros, methods, fields, and
* function names with an underscore. Including this file replaces those
* precision-independent tokens with their precision-dependent equivalents,
* based on the value of BITS_IN_JSAMPLE.
*/
#ifndef JSAMPLECOMP_H
#define JSAMPLECOMP_H
#if BITS_IN_JSAMPLE == 12
/* Sample data types and macros (jmorecfg.h) */
#define _JSAMPLE J12SAMPLE
#define _MAXJSAMPLE MAXJ12SAMPLE
#define _CENTERJSAMPLE CENTERJ12SAMPLE
#define _JSAMPROW J12SAMPROW
#define _JSAMPARRAY J12SAMPARRAY
#define _JSAMPIMAGE J12SAMPIMAGE
/* External functions (jpeglib.h) */
#define _jpeg_write_scanlines jpeg12_write_scanlines
#define _jpeg_write_raw_data jpeg12_write_raw_data
#define _jpeg_read_scanlines jpeg12_read_scanlines
#define _jpeg_skip_scanlines jpeg12_skip_scanlines
#define _jpeg_crop_scanline jpeg12_crop_scanline
#define _jpeg_read_raw_data jpeg12_read_raw_data
/* Internal methods (jpegint.h) */
/* Use the 12-bit method in the jpeg_c_main_controller structure. */
#define _process_data process_data_12
/* Use the 12-bit method in the jpeg_c_prep_controller structure. */
#define _pre_process_data pre_process_data_12
/* Use the 12-bit method in the jpeg_c_coef_controller structure. */
#define _compress_data compress_data_12
/* Use the 12-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert_12
/* Use the 12-bit method in the jpeg_downsampler structure. */
#define _downsample downsample_12
/* Use the 12-bit method in the jpeg_forward_dct structure. */
#define _forward_DCT forward_DCT_12
/* Use the 12-bit method in the jpeg_d_main_controller structure. */
#define _process_data process_data_12
/* Use the 12-bit method in the jpeg_d_coef_controller structure. */
#define _decompress_data decompress_data_12
/* Use the 12-bit method in the jpeg_d_post_controller structure. */
#define _post_process_data post_process_data_12
/* Use the 12-bit method in the jpeg_inverse_dct structure. */
#define _inverse_DCT_method_ptr inverse_DCT_12_method_ptr
#define _inverse_DCT inverse_DCT_12
/* Use the 12-bit method in the jpeg_upsampler structure. */
#define _upsample upsample_12
/* Use the 12-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert_12
/* Use the 12-bit method in the jpeg_color_quantizer structure. */
#define _color_quantize color_quantize_12
/* Global internal functions (jpegint.h) */
#define _jinit_c_main_controller j12init_c_main_controller
#define _jinit_c_prep_controller j12init_c_prep_controller
#define _jinit_c_coef_controller j12init_c_coef_controller
#define _jinit_color_converter j12init_color_converter
#define _jinit_downsampler j12init_downsampler
#define _jinit_forward_dct j12init_forward_dct
#define _jinit_d_main_controller j12init_d_main_controller
#define _jinit_d_coef_controller j12init_d_coef_controller
#define _jinit_d_post_controller j12init_d_post_controller
#define _jinit_inverse_dct j12init_inverse_dct
#define _jinit_upsampler j12init_upsampler
#define _jinit_color_deconverter j12init_color_deconverter
#define _jinit_1pass_quantizer j12init_1pass_quantizer
#define _jinit_2pass_quantizer j12init_2pass_quantizer
#define _jinit_merged_upsampler j12init_merged_upsampler
#define _jcopy_sample_rows j12copy_sample_rows
/* Global internal functions (jdct.h) */
#define _jpeg_fdct_islow jpeg12_fdct_islow
#define _jpeg_fdct_ifast jpeg12_fdct_ifast
#define _jpeg_idct_islow jpeg12_idct_islow
#define _jpeg_idct_ifast jpeg12_idct_ifast
#define _jpeg_idct_float jpeg12_idct_float
#define _jpeg_idct_7x7 jpeg12_idct_7x7
#define _jpeg_idct_6x6 jpeg12_idct_6x6
#define _jpeg_idct_5x5 jpeg12_idct_5x5
#define _jpeg_idct_4x4 jpeg12_idct_4x4
#define _jpeg_idct_3x3 jpeg12_idct_3x3
#define _jpeg_idct_2x2 jpeg12_idct_2x2
#define _jpeg_idct_1x1 jpeg12_idct_1x1
#define _jpeg_idct_9x9 jpeg12_idct_9x9
#define _jpeg_idct_10x10 jpeg12_idct_10x10
#define _jpeg_idct_11x11 jpeg12_idct_11x11
#define _jpeg_idct_12x12 jpeg12_idct_12x12
#define _jpeg_idct_13x13 jpeg12_idct_13x13
#define _jpeg_idct_14x14 jpeg12_idct_14x14
#define _jpeg_idct_15x15 jpeg12_idct_15x15
#define _jpeg_idct_16x16 jpeg12_idct_16x16
/* Internal fields (cdjpeg.h) */
/* Use the 12-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
structures. */
#define _buffer buffer12
/* Image I/O functions (cdjpeg.h) */
#define _jinit_read_gif j12init_read_gif
#define _jinit_write_gif j12init_write_gif
#define _jinit_read_ppm j12init_read_ppm
#define _jinit_write_ppm j12init_write_ppm
#define _read_color_map read_color_map_12
#else /* BITS_IN_JSAMPLE */
/* Sample data types and macros (jmorecfg.h) */
#define _JSAMPLE JSAMPLE
#define _MAXJSAMPLE MAXJSAMPLE
#define _CENTERJSAMPLE CENTERJSAMPLE
#define _JSAMPROW JSAMPROW
#define _JSAMPARRAY JSAMPARRAY
#define _JSAMPIMAGE JSAMPIMAGE
/* External functions (jpeglib.h) */
#define _jpeg_write_scanlines jpeg_write_scanlines
#define _jpeg_write_raw_data jpeg_write_raw_data
#define _jpeg_read_scanlines jpeg_read_scanlines
#define _jpeg_skip_scanlines jpeg_skip_scanlines
#define _jpeg_crop_scanline jpeg_crop_scanline
#define _jpeg_read_raw_data jpeg_read_raw_data
/* Internal methods (jpegint.h) */
/* Use the 8-bit method in the jpeg_c_main_controller structure. */
#define _process_data process_data
/* Use the 8-bit method in the jpeg_c_prep_controller structure. */
#define _pre_process_data pre_process_data
/* Use the 8-bit method in the jpeg_c_coef_controller structure. */
#define _compress_data compress_data
/* Use the 8-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert
/* Use the 8-bit method in the jpeg_downsampler structure. */
#define _downsample downsample
/* Use the 8-bit method in the jpeg_forward_dct structure. */
#define _forward_DCT forward_DCT
/* Use the 8-bit method in the jpeg_d_main_controller structure. */
#define _process_data process_data
/* Use the 8-bit method in the jpeg_d_coef_controller structure. */
#define _decompress_data decompress_data
/* Use the 8-bit method in the jpeg_d_post_controller structure. */
#define _post_process_data post_process_data
/* Use the 8-bit method in the jpeg_inverse_dct structure. */
#define _inverse_DCT_method_ptr inverse_DCT_method_ptr
#define _inverse_DCT inverse_DCT
/* Use the 8-bit method in the jpeg_upsampler structure. */
#define _upsample upsample
/* Use the 8-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert
/* Use the 8-bit method in the jpeg_color_quantizer structure. */
#define _color_quantize color_quantize
/* Global internal functions (jpegint.h) */
#define _jinit_c_main_controller jinit_c_main_controller
#define _jinit_c_prep_controller jinit_c_prep_controller
#define _jinit_c_coef_controller jinit_c_coef_controller
#define _jinit_color_converter jinit_color_converter
#define _jinit_downsampler jinit_downsampler
#define _jinit_forward_dct jinit_forward_dct
#define _jinit_d_main_controller jinit_d_main_controller
#define _jinit_d_coef_controller jinit_d_coef_controller
#define _jinit_d_post_controller jinit_d_post_controller
#define _jinit_inverse_dct jinit_inverse_dct
#define _jinit_upsampler jinit_upsampler
#define _jinit_color_deconverter jinit_color_deconverter
#define _jinit_1pass_quantizer jinit_1pass_quantizer
#define _jinit_2pass_quantizer jinit_2pass_quantizer
#define _jinit_merged_upsampler jinit_merged_upsampler
#define _jcopy_sample_rows jcopy_sample_rows
/* Global internal functions (jdct.h) */
#define _jpeg_fdct_islow jpeg_fdct_islow
#define _jpeg_fdct_ifast jpeg_fdct_ifast
#define _jpeg_idct_islow jpeg_idct_islow
#define _jpeg_idct_ifast jpeg_idct_ifast
#define _jpeg_idct_float jpeg_idct_float
#define _jpeg_idct_7x7 jpeg_idct_7x7
#define _jpeg_idct_6x6 jpeg_idct_6x6
#define _jpeg_idct_5x5 jpeg_idct_5x5
#define _jpeg_idct_4x4 jpeg_idct_4x4
#define _jpeg_idct_3x3 jpeg_idct_3x3
#define _jpeg_idct_2x2 jpeg_idct_2x2
#define _jpeg_idct_1x1 jpeg_idct_1x1
#define _jpeg_idct_9x9 jpeg_idct_9x9
#define _jpeg_idct_10x10 jpeg_idct_10x10
#define _jpeg_idct_11x11 jpeg_idct_11x11
#define _jpeg_idct_12x12 jpeg_idct_12x12
#define _jpeg_idct_13x13 jpeg_idct_13x13
#define _jpeg_idct_14x14 jpeg_idct_14x14
#define _jpeg_idct_15x15 jpeg_idct_15x15
#define _jpeg_idct_16x16 jpeg_idct_16x16
/* Internal fields (cdjpeg.h) */
/* Use the 8-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
structures. */
#define _buffer buffer
/* Image I/O functions (cdjpeg.h) */
#define _jinit_read_gif jinit_read_gif
#define _jinit_write_gif jinit_write_gif
#define _jinit_read_ppm jinit_read_ppm
#define _jinit_write_ppm jinit_write_ppm
#define _read_color_map read_color_map
#endif /* BITS_IN_JSAMPLE */
#endif /* JSAMPLECOMP_H */