16-bit lossless JPEG support

This commit is contained in:
DRC 2022-12-15 12:20:50 -06:00
parent ad4e2ad86f
commit 2241434eb9
46 changed files with 906 additions and 148 deletions

View File

@ -556,7 +556,7 @@ if(WITH_ARITH_DEC)
set(JPEG_SOURCES ${JPEG_SOURCES} jdarith.c)
endif()
# Compile a separate version of these source files with 12-bit data
# Compile a separate version of these source files with 12-bit and 16-bit data
# precision.
add_library(jpeg12 OBJECT jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jcdiffct.c
jclossls.c jcmainct.c jcprepct.c jcsample.c jdapistd.c jdcoefct.c jdcolor.c
@ -564,6 +564,10 @@ add_library(jpeg12 OBJECT jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jcdiffct.c
jfdctfst.c jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c
jquant2.c jutils.c)
set_property(TARGET jpeg12 PROPERTY COMPILE_FLAGS "-DBITS_IN_JSAMPLE=12")
add_library(jpeg16 OBJECT jcapistd.c jccolor.c jcdiffct.c jclossls.c jcmainct.c
jcprepct.c jcsample.c jdapistd.c jdcolor.c jddiffct.c jdlossls.c jdmainct.c
jdpostct.c jdsample.c jquant1.c jquant2.c jutils.c)
set_property(TARGET jpeg16 PROPERTY COMPILE_FLAGS "-DBITS_IN_JSAMPLE=16")
if(WITH_SIMD)
add_subdirectory(simd)
@ -597,7 +601,7 @@ endif()
if(ENABLE_STATIC)
add_library(jpeg-static STATIC ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS}
${SIMD_OBJS} $<TARGET_OBJECTS:jpeg12>)
${SIMD_OBJS} $<TARGET_OBJECTS:jpeg12> $<TARGET_OBJECTS:jpeg16>)
if(NOT MSVC)
set_target_properties(jpeg-static PROPERTIES OUTPUT_NAME jpeg)
endif()
@ -607,7 +611,7 @@ if(WITH_TURBOJPEG)
if(ENABLE_SHARED)
set(TURBOJPEG_SOURCES ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS} ${SIMD_OBJS}
turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c rdbmp.c rdppm.c
wrbmp.c wrppm.c $<TARGET_OBJECTS:jpeg12>)
wrbmp.c wrppm.c $<TARGET_OBJECTS:jpeg12> $<TARGET_OBJECTS:jpeg16>)
set(TJMAPFILE ${CMAKE_CURRENT_SOURCE_DIR}/turbojpeg-mapfile)
if(WITH_JAVA)
set(TURBOJPEG_SOURCES ${TURBOJPEG_SOURCES} turbojpeg-jni.c)
@ -659,7 +663,8 @@ if(WITH_TURBOJPEG)
if(ENABLE_STATIC)
add_library(turbojpeg-static STATIC ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS}
${SIMD_OBJS} turbojpeg.c transupp.c jdatadst-tj.c jdatasrc-tj.c rdbmp.c
rdppm.c wrbmp.c wrppm.c $<TARGET_OBJECTS:jpeg12>)
rdppm.c wrbmp.c wrppm.c $<TARGET_OBJECTS:jpeg12>
$<TARGET_OBJECTS:jpeg16>)
set_property(TARGET turbojpeg-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
if(NOT MSVC)
@ -685,24 +690,32 @@ set(CDJPEG_COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
if(ENABLE_STATIC)
# Compile a separate version of these source files with 12-bit data
# precision.
# Compile a separate version of these source files with 12-bit and 16-bit
# data precision.
add_library(cjpeg12-static OBJECT rdgif.c rdppm.c)
set_property(TARGET cjpeg12-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=12 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_library(cjpeg16-static OBJECT rdgif.c rdppm.c)
set_property(TARGET cjpeg16-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=16 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_executable(cjpeg-static cjpeg.c cdjpeg.c rdbmp.c rdgif.c rdppm.c
rdswitch.c rdtarga.c $<TARGET_OBJECTS:cjpeg12-static>)
rdswitch.c rdtarga.c $<TARGET_OBJECTS:cjpeg12-static>
$<TARGET_OBJECTS:cjpeg16-static>)
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS
${CDJPEG_COMPILE_FLAGS})
target_link_libraries(cjpeg-static jpeg-static)
# Compile a separate version of these source files with 12-bit data
# precision.
# Compile a separate version of these source files with 12-bit and 16-bit
# data precision.
add_library(djpeg12-static OBJECT rdcolmap.c wrgif.c wrppm.c)
set_property(TARGET djpeg12-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=12 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_library(djpeg16-static OBJECT rdcolmap.c wrgif.c wrppm.c)
set_property(TARGET djpeg16-static PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=16 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_executable(djpeg-static djpeg.c cdjpeg.c rdcolmap.c rdswitch.c wrbmp.c
wrgif.c wrppm.c wrtarga.c $<TARGET_OBJECTS:djpeg12-static>)
wrgif.c wrppm.c wrtarga.c $<TARGET_OBJECTS:djpeg12-static>
$<TARGET_OBJECTS:djpeg16-static>)
set_property(TARGET djpeg-static PROPERTY COMPILE_FLAGS
${CDJPEG_COMPILE_FLAGS})
target_link_libraries(djpeg-static jpeg-static)
@ -988,12 +1001,15 @@ foreach(libtype ${TEST_LIBTYPES})
# SIMD-accelerated ones.)
macro(add_bittest PROG NAME ARGS OUTFILE INFILE MD5SUM)
if(${PROG} STREQUAL "cjpeg12")
if(${PROG} STREQUAL "cjpeg16")
set(ACTUAL_ARGS "${ARGS};-precision;16")
elseif(${PROG} STREQUAL "cjpeg12")
set(ACTUAL_ARGS "${ARGS};-precision;12")
else()
set(ACTUAL_ARGS ${ARGS})
endif()
string(REGEX REPLACE "12" "" ACTUAL_PROG ${PROG})
string(REGEX REPLACE "16" "" ACTUAL_PROG ${PROG})
string(REGEX REPLACE "12" "" ACTUAL_PROG ${ACTUAL_PROG})
add_test(${PROG}-${libtype}-${NAME}
${CMAKE_CROSSCOMPILING_EMULATOR} ${ACTUAL_PROG}${suffix} ${ACTUAL_ARGS}
-outfile ${OUTFILE} ${INFILE})
@ -1008,6 +1024,20 @@ foreach(libtype ${TEST_LIBTYPES})
endif()
endmacro()
set(MD5_JPEG_LOSSLESS fe99437df4e9976fe5e841969242b208)
set(MD5_PPM_LOSSLESS 01d9642a2b8723fefebbe9cb074ccd02)
# Lossless (all arguments other than -lossless and -restart should have no
# effect)
add_bittest(cjpeg16 lossless
"-lossless;4;-restart;1;-quality;1;-grayscale;-optimize;-dct;float;-smooth;100;-baseline;-qslots;1,0,0;-sample;1x2,3x4,2x1"
testout16_lossless.jpg ${TESTIMAGES}/testorig.ppm
${MD5_JPEG_LOSSLESS})
add_bittest(djpeg16 lossless
"-fast;-scale;1/8;-dct;float;-dither;none;-nosmooth;-onepass"
testout16_lossless.ppm testout16_lossless.jpg
${MD5_PPM_LOSSLESS} cjpeg16-${libtype}-lossless)
foreach(sample_bits 8 12)
if(sample_bits EQUAL 12)

View File

@ -3,41 +3,46 @@
### Significant changes relative to 2.1.4:
1. 12-bit-per-component JPEG support is now included in the libjpeg API
library, cjpeg, djpeg, and jpegtran:
- The existing `data_precision` field in `jpeg_compress_struct` and
`jpeg_decompress_struct` has been repurposed to enable the creation of
12-bit-per-component JPEG images or to detect whether a 12-bit-per-component
JPEG image is being decompressed.
- New 12-bit-per-component versions of `jpeg_write_scanlines()`,
`jpeg_write_raw_data()`, `jpeg_read_scanlines()`, `jpeg_skip_scanlines()`,
`jpeg_crop_scanline()`, and `jpeg_read_raw_data()` provide interfaces for
compressing from/decompressing to 12-bit-per-component uncompressed image
buffers.
- A new cjpeg command-line argument (`-precision`) can be used to create
a 12-bit-per-component JPEG image. (djpeg and jpegtran handle
12-bit-per-component JPEG images automatically.)
Refer to [libjpeg.txt](libjpeg.txt) and [usage.txt](usage.txt) for more
details.
2. Significantly sped up the computation of optimal Huffman tables. This
1. Significantly sped up the computation of optimal Huffman tables. This
speeds up the compression of tiny images by as much as 2x and provides a
noticeable speedup for images as large as 256x256 when using optimal Huffman
tables.
3. All deprecated fields, constructors, and methods in the TurboJPEG Java API
2. All deprecated fields, constructors, and methods in the TurboJPEG Java API
have been removed.
4. Added support for 8-bit and 12-bit lossless JPEG images. A new libjpeg API
function (`jpeg_enable_lossless()`), TurboJPEG API flag (`TJFLAG_LOSSLESS` in
the C API and `TJ.FLAG_LOSSLESS` in the Java API), and cjpeg/TJBench
command-line argument (`-lossless`) can be used to create a lossless JPEG
image. (Decompression of lossless JPEG images is handled automatically.) Note
that the TurboJPEG API and TJBench can currently only be used to create and
decompress 8-bit lossless JPEG images. Refer to [libjpeg.txt](libjpeg.txt),
[usage.txt](usage.txt), and the TurboJPEG API documentation for more details.
3. Added support for 8-bit, 12-bit, and 16-bit lossless JPEG images. A new
libjpeg API function (`jpeg_enable_lossless()`), TurboJPEG API flag
(`TJFLAG_LOSSLESS` in the C API and `TJ.FLAG_LOSSLESS` in the Java API), and
cjpeg/TJBench command-line argument (`-lossless`) can be used to create a
lossless JPEG image. (Decompression of lossless JPEG images is handled
automatically.) Note that the TurboJPEG API and TJBench can currently only be
used to create and decompress 8-bit lossless JPEG images. Refer to
[libjpeg.txt](libjpeg.txt), [usage.txt](usage.txt), and the TurboJPEG API
documentation for more details.
4. 12-bit-per-component (lossy and lossless) and 16-bit-per-component
(lossless) JPEG support is now included in the libjpeg API library, cjpeg,
djpeg, and jpegtran:
- The existing `data_precision` field in `jpeg_compress_struct` and
`jpeg_decompress_struct` has been repurposed to enable the creation of
12-bit-per-component and 16-bit-per-component JPEG images or to detect whether
a 12-bit-per-component or 16-bit-per-component JPEG image is being
decompressed.
- New 12-bit-per-component and 16-bit-per-component versions of
`jpeg_write_scanlines()` and `jpeg_read_scanlines()`, as well as new
12-bit-per-component versions of `jpeg_write_raw_data()`,
`jpeg_skip_scanlines()`, `jpeg_crop_scanline()`, and `jpeg_read_raw_data()`,
provide interfaces for compressing from/decompressing to 12-bit-per-component
and 16-bit-per-component uncompressed image buffers.
- A new cjpeg command-line argument (`-precision`) can be used to create
a 12-bit-per-component or 16-bit-per-component JPEG image. (djpeg and jpegtran
handle 12-bit-per-component and 16-bit-per-component JPEG images
automatically.)
Refer to [libjpeg.txt](libjpeg.txt) and [usage.txt](usage.txt) for more
details.
5. Introduced a new flag in the TurboJPEG C and Java APIs (`TJFLAG_ARITHMETIC`
and `TJ.FLAG_ARITHMETIC`, respectively) that causes the library to use

View File

@ -36,6 +36,9 @@ struct cjpeg_source_struct {
JSAMPARRAY buffer;
J12SAMPARRAY buffer12;
#ifdef C_LOSSLESS_SUPPORTED
J16SAMPARRAY buffer16;
#endif
JDIMENSION buffer_height;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
JDIMENSION max_pixels;
@ -77,6 +80,9 @@ struct djpeg_dest_struct {
*/
JSAMPARRAY buffer;
J12SAMPARRAY buffer12;
#ifdef D_LOSSLESS_SUPPORTED
J16SAMPARRAY buffer16;
#endif
JDIMENSION buffer_height;
};
@ -111,13 +117,26 @@ EXTERN(djpeg_dest_ptr) jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
boolean use_inversion_array);
EXTERN(cjpeg_source_ptr) jinit_read_gif(j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) j12init_read_gif(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(cjpeg_source_ptr) j16init_read_gif(j_compress_ptr cinfo);
#endif
EXTERN(djpeg_dest_ptr) jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw);
EXTERN(djpeg_dest_ptr) j12init_write_gif(j_decompress_ptr cinfo,
boolean is_lzw);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(djpeg_dest_ptr) j16init_write_gif(j_decompress_ptr cinfo,
boolean is_lzw);
#endif
EXTERN(cjpeg_source_ptr) jinit_read_ppm(j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) j12init_read_ppm(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(cjpeg_source_ptr) j16init_read_ppm(j_compress_ptr cinfo);
#endif
EXTERN(djpeg_dest_ptr) jinit_write_ppm(j_decompress_ptr cinfo);
EXTERN(djpeg_dest_ptr) j12init_write_ppm(j_decompress_ptr cinfo);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(djpeg_dest_ptr) j16init_write_ppm(j_decompress_ptr cinfo);
#endif
EXTERN(cjpeg_source_ptr) jinit_read_targa(j_compress_ptr cinfo);
EXTERN(djpeg_dest_ptr) jinit_write_targa(j_decompress_ptr cinfo);
@ -135,6 +154,9 @@ EXTERN(boolean) set_sample_factors(j_compress_ptr cinfo, char *arg);
EXTERN(void) read_color_map(j_decompress_ptr cinfo, FILE *infile);
EXTERN(void) read_color_map_12(j_decompress_ptr cinfo, FILE *infile);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(void) read_color_map_16(j_decompress_ptr cinfo, FILE *infile);
#endif
/* common support routines (in cdjpeg.c) */

11
cjpeg.1
View File

@ -1,4 +1,4 @@
.TH CJPEG 1 "16 November 2022"
.TH CJPEG 1 "30 November 2022"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@ -150,10 +150,13 @@ about the same --- often a little smaller.
Switches for advanced users:
.TP
.BI \-precision " N"
Create JPEG file with N-bit data precision. N is 8 or 12; default is 8.
Create JPEG file with N-bit data precision. N is 8, 12, or 16; default is 8.
If N is 16, then
.B -lossless
must also be specified.
.B Caution:
12-bit JPEG is not yet widely implemented, so many decoders will be unable to
view a 12-bit JPEG file at all.
12-bit and 16-bit JPEG is not yet widely implemented, so many decoders will be
unable to view a 12-bit or 16-bit JPEG file at all.
.TP
.BI \-lossless " psv[,Pt]"
Create a lossless JPEG file using the specified predictor selection value

38
cjpeg.c
View File

@ -105,14 +105,28 @@ select_file_type(j_compress_ptr cinfo, FILE *infile)
#endif
#ifdef GIF_SUPPORTED
case 'G':
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_gif(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_gif(cinfo);
else
return jinit_read_gif(cinfo);
#endif
#ifdef PPM_SUPPORTED
case 'P':
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_ppm(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
} else if (cinfo->data_precision == 12)
return j12init_read_ppm(cinfo);
else
return jinit_read_ppm(cinfo);
@ -213,7 +227,12 @@ usage(void)
#endif
fprintf(stderr, "Switches for advanced users:\n");
fprintf(stderr, " -precision N Create JPEG file with N-bit data precision\n");
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " (N is 8, 12, or 16; default is 8; if N is 16, then -lossless\n");
fprintf(stderr, " must also be specified)\n");
#else
fprintf(stderr, " (N is 8 or 12; default is 8)\n");
#endif
#ifdef C_LOSSLESS_SUPPORTED
fprintf(stderr, " -lossless psv[,Pt] Create lossless JPEG file\n");
#endif
@ -427,7 +446,11 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
usage();
if (sscanf(argv[argn], "%d", &val) != 1)
usage();
#ifdef C_LOSSLESS_SUPPORTED
if (val != 8 && val != 12 && val != 16)
#else
if (val != 8 && val != 12)
#endif
usage();
cinfo->data_precision = val;
@ -768,7 +791,16 @@ main(int argc, char **argv)
jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);
/* Process data */
if (cinfo.data_precision == 12) {
if (cinfo.data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg16_write_scanlines(&cinfo, src_mgr->buffer16, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
while (cinfo.next_scanline < cinfo.image_height) {
num_scanlines = (*src_mgr->get_pixel_rows) (&cinfo, src_mgr);
(void)jpeg12_write_scanlines(&cinfo, src_mgr->buffer12, num_scanlines);

43
djpeg.c
View File

@ -662,7 +662,14 @@ main(int argc, char **argv)
#endif
#ifdef GIF_SUPPORTED
case FMT_GIF:
if (cinfo.data_precision == 12)
if (cinfo.data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
dest_mgr = j16init_write_gif(&cinfo, TRUE);
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
break;
#endif
} else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_gif(&cinfo, TRUE);
else
dest_mgr = jinit_write_gif(&cinfo, TRUE);
@ -673,7 +680,14 @@ main(int argc, char **argv)
#endif
#ifdef PPM_SUPPORTED
case FMT_PPM:
if (cinfo.data_precision == 12)
if (cinfo.data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
dest_mgr = j16init_write_ppm(&cinfo);
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
break;
#endif
} else if (cinfo.data_precision == 12)
dest_mgr = j12init_write_ppm(&cinfo);
else
dest_mgr = jinit_write_ppm(&cinfo);
@ -715,7 +729,9 @@ main(int argc, char **argv)
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
if (cinfo.data_precision == 12) {
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < skip_start) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,
@ -767,7 +783,9 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
if (cinfo.data_precision == 12)
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12)
jpeg12_crop_scanline(&cinfo, &crop_x, &crop_width);
else
jpeg_crop_scanline(&cinfo, &crop_x, &crop_width);
@ -784,7 +802,9 @@ main(int argc, char **argv)
(*dest_mgr->start_output) (&cinfo, dest_mgr);
cinfo.output_height = tmp;
if (cinfo.data_precision == 12) {
if (cinfo.data_precision == 16)
ERREXIT(&cinfo, JERR_NOTIMPL);
else if (cinfo.data_precision == 12) {
/* Process data */
if ((tmp = jpeg12_skip_scanlines(&cinfo, crop_y)) != crop_y) {
fprintf(stderr, "%s: jpeg12_skip_scanlines() returned %u rather than %u\n",
@ -831,7 +851,18 @@ main(int argc, char **argv)
/* Write output file header */
(*dest_mgr->start_output) (&cinfo, dest_mgr);
if (cinfo.data_precision == 12) {
if (cinfo.data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg16_read_scanlines(&cinfo, dest_mgr->buffer16,
dest_mgr->buffer_height);
(*dest_mgr->put_pixel_rows) (&cinfo, dest_mgr, num_scanlines);
}
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
} else if (cinfo.data_precision == 12) {
/* Process data */
while (cinfo.output_scanline < cinfo.output_height) {
num_scanlines = jpeg12_read_scanlines(&cinfo, dest_mgr->buffer12,

View File

@ -42,6 +42,15 @@ target_link_libraries(cjpeg12_fuzzer${FUZZER_SUFFIX} ${FUZZ_LIBRARY}
install(TARGETS cjpeg12_fuzzer${FUZZER_SUFFIX} RUNTIME DESTINATION
${FUZZ_BINDIR})
add_executable(cjpeg16_fuzzer${FUZZER_SUFFIX} cjpeg16.cc ../cdjpeg.c ../rdbmp.c
../rdgif.c ../rdppm.c ../rdswitch.c ../rdtarga.c)
set_property(TARGET cjpeg16_fuzzer${FUZZER_SUFFIX} PROPERTY COMPILE_FLAGS
${COMPILE_FLAGS})
target_link_libraries(cjpeg16_fuzzer${FUZZER_SUFFIX} ${FUZZ_LIBRARY}
jpeg-static)
install(TARGETS cjpeg16_fuzzer${FUZZER_SUFFIX} RUNTIME DESTINATION
${FUZZ_BINDIR})
macro(add_fuzz_target target source_file)
add_executable(${target}_fuzzer${FUZZER_SUFFIX} ${source_file})
target_link_libraries(${target}_fuzzer${FUZZER_SUFFIX} ${FUZZ_LIBRARY}

View File

@ -19,6 +19,7 @@ make install
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/cjpeg_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/cjpeg12_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/cjpeg16_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_yuv_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip
cp $SRC/compress_fuzzer_seed_corpus.zip $OUT/compress_lossless_fuzzer${FUZZER_SUFFIX}_seed_corpus.zip

79
fuzz/cjpeg16.cc Normal file
View File

@ -0,0 +1,79 @@
/*
* Copyright (C)2021-2022 D. R. Commander. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the libjpeg-turbo Project nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS",
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/* This fuzz target wraps cjpeg in order to test esoteric compression options
as well as the GIF and Targa readers. */
#define main cjpeg_main
#define CJPEG_FUZZER
extern "C" {
#include "../cjpeg.c"
}
#undef main
#undef CJPEG_FUZZER
#include <stdint.h>
#include <unistd.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
char filename[FILENAME_MAX] = { 0 };
char *argv1[] = {
(char *)"cjpeg", (char *)"-precision", (char *)"16",
(char *)"-lossless", (char *)"1,4", NULL
};
char *argv2[] = {
(char *)"cjpeg", (char *)"-precision", (char *)"16",
(char *)"-lossless", (char *)"4,0", NULL
};
int fd = -1;
#if defined(__has_feature) && __has_feature(memory_sanitizer)
char env[18] = "JSIMD_FORCENONE=1";
/* The libjpeg-turbo SIMD extensions produce false positives with
MemorySanitizer. */
putenv(env);
#endif
snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_cjpeg16_fuzz.XXXXXX");
if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0)
goto bailout;
argv1[5] = argv2[5] = filename;
cjpeg_main(6, argv1);
cjpeg_main(6, argv2);
bailout:
if (fd >= 0) {
close(fd);
if (strlen(filename) > 0) unlink(filename);
}
return 0;
}

View File

@ -194,7 +194,14 @@ jpeg_finish_compress(j_compress_ptr cinfo)
/* We bypass the main controller and invoke coef controller directly;
* all work is being done from the coefficient buffer.
*/
if (cinfo->data_precision == 12) {
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
if (!(*cinfo->coef->compress_data_16) (cinfo, (J16SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
if (!(*cinfo->coef->compress_data_12) (cinfo, (J12SAMPIMAGE)NULL))
ERREXIT(cinfo, JERR_CANT_SUSPEND);
} else {

View File

@ -85,6 +85,7 @@ GLOBAL(JDIMENSION)
_jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
JDIMENSION num_lines)
{
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
JDIMENSION row_ctr, rows_left;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
@ -119,9 +120,15 @@ _jpeg_write_scanlines(j_compress_ptr cinfo, _JSAMPARRAY scanlines,
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, num_lines);
cinfo->next_scanline += row_ctr;
return row_ctr;
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
return 0;
#endif
}
#if BITS_IN_JSAMPLE != 16
/*
* Alternate entry point to write raw data.
* Processes exactly one iMCU row per call, unless suspended.
@ -176,3 +183,5 @@ _jpeg_write_raw_data(j_compress_ptr cinfo, _JSAMPIMAGE data,
cinfo->next_scanline += lines_per_iMCU_row;
return lines_per_iMCU_row;
}
#endif /* BITS_IN_JSAMPLE != 16 */

View File

@ -33,6 +33,7 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
@ -68,6 +69,9 @@ rgb_ycc_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
ctab[b + B_CR_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -87,6 +91,7 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
@ -109,6 +114,9 @@ rgb_gray_convert_internal(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
ctab[b + B_Y_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}

View File

@ -20,13 +20,17 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* Private subobject */
typedef struct {
struct jpeg_color_converter pub; /* public fields */
#if BITS_IN_JSAMPLE != 16
/* Private state for RGB->YCC conversion */
JLONG *rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
#endif
} my_color_converter;
typedef my_color_converter *my_cconvert_ptr;
@ -209,6 +213,7 @@ typedef my_color_converter *my_cconvert_ptr;
METHODDEF(void)
rgb_ycc_start(j_compress_ptr cinfo)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
JLONG *rgb_ycc_tab;
JLONG i;
@ -235,6 +240,9 @@ rgb_ycc_start(j_compress_ptr cinfo)
rgb_ycc_tab[i + G_CR_OFF] = (-FIX(0.41869)) * i;
rgb_ycc_tab[i + B_CR_OFF] = (-FIX(0.08131)) * i;
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -388,6 +396,7 @@ METHODDEF(void)
cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
_JSAMPIMAGE output_buf, JDIMENSION output_row, int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_ycc_tab;
@ -426,6 +435,9 @@ cmyk_ycck_convert(j_compress_ptr cinfo, _JSAMPARRAY input_buf,
ctab[b + B_CR_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -716,3 +728,5 @@ _jinit_color_converter(j_compress_ptr cinfo)
break;
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */

View File

@ -40,7 +40,16 @@ jinit_compress_master(j_compress_ptr cinfo)
/* Preprocessing */
if (!cinfo->raw_data_in) {
if (cinfo->data_precision == 12) {
if (cinfo->data_precision == 16) {
#ifdef C_LOSSLESS_SUPPORTED
j16init_color_converter(cinfo);
j16init_downsampler(cinfo);
j16init_c_prep_controller(cinfo,
FALSE /* never need full buffer here */);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
j12init_color_converter(cinfo);
j12init_downsampler(cinfo);
j12init_c_prep_controller(cinfo,
@ -55,7 +64,9 @@ jinit_compress_master(j_compress_ptr cinfo)
if (cinfo->master->lossless) {
#ifdef C_LOSSLESS_SUPPORTED
/* Prediction, sample differencing, and point transform */
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
j16init_lossless_compressor(cinfo);
else if (cinfo->data_precision == 12)
j12init_lossless_compressor(cinfo);
else
jinit_lossless_compressor(cinfo);
@ -67,7 +78,10 @@ jinit_compress_master(j_compress_ptr cinfo)
}
/* Need a full-image difference buffer in any multi-pass mode. */
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
j16init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
else if (cinfo->data_precision == 12)
j12init_c_diff_controller(cinfo, (boolean)(cinfo->num_scans > 1 ||
cinfo->optimize_coding));
else
@ -77,6 +91,8 @@ jinit_compress_master(j_compress_ptr cinfo)
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
if (cinfo->data_precision == 16)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Forward DCT */
if (cinfo->data_precision == 12)
j12init_forward_dct(cinfo);
@ -109,7 +125,13 @@ jinit_compress_master(j_compress_ptr cinfo)
cinfo->optimize_coding));
}
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
#ifdef C_LOSSLESS_SUPPORTED
j16init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_c_main_controller(cinfo, FALSE /* never need full buffer here */);
else
jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);

View File

@ -21,6 +21,8 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* Private buffer controller object */
typedef struct {
@ -167,3 +169,5 @@ _jinit_c_main_controller(j_compress_ptr cinfo, boolean need_full_buffer)
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */

View File

@ -83,7 +83,12 @@ initial_setup(j_compress_ptr cinfo, boolean transcode_only)
if ((long)jd_samplesperrow != samplesperrow)
ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
#ifdef C_LOSSLESS_SUPPORTED
if (cinfo->data_precision != 8 && cinfo->data_precision != 12 &&
cinfo->data_precision != 16)
#else
if (cinfo->data_precision != 8 && cinfo->data_precision != 12)
#endif
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Check that number of components won't exceed internal array sizes */

View File

@ -25,6 +25,8 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* At present, jcsample.c can request context rows only for smoothing.
* In the future, we might also need context rows for CCIR601 sampling
* or other more-complex downsampling procedures. The code to support
@ -359,3 +361,5 @@ _jinit_c_prep_controller(j_compress_ptr cinfo, boolean need_full_buffer)
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */

View File

@ -59,6 +59,8 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)
/* Pointer to routine to downsample a single component */
typedef void (*downsample1_ptr) (j_compress_ptr cinfo,
jpeg_component_info *compptr,
@ -537,3 +539,5 @@ _jinit_downsampler(j_compress_ptr cinfo)
TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
#endif
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED) */

View File

@ -19,8 +19,13 @@
*/
#include "jinclude.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
#include "jdmainct.h"
#include "jdcoefct.h"
#else
#define JPEG_INTERNALS
#include "jpeglib.h"
#endif
#include "jdmaster.h"
#include "jdmerge.h"
#include "jdsample.h"
@ -151,6 +156,8 @@ output_pass_setup(j_decompress_ptr cinfo)
#endif /* BITS_IN_JSAMPLE == 8 */
#if BITS_IN_JSAMPLE != 16
/*
* Enable partial scanline decompression
*
@ -274,6 +281,8 @@ _jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset,
}
}
#endif /* BITS_IN_JSAMPLE != 16 */
/*
* Read some scanlines of data from the JPEG decompressor.
@ -292,6 +301,7 @@ GLOBAL(JDIMENSION)
_jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines,
JDIMENSION max_lines)
{
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
JDIMENSION row_ctr;
if (cinfo->data_precision != BITS_IN_JSAMPLE)
@ -316,9 +326,15 @@ _jpeg_read_scanlines(j_decompress_ptr cinfo, _JSAMPARRAY scanlines,
(*cinfo->main->_process_data) (cinfo, scanlines, &row_ctr, max_lines);
cinfo->output_scanline += row_ctr;
return row_ctr;
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
return 0;
#endif
}
#if BITS_IN_JSAMPLE != 16
/* Dummy color convert function used by _jpeg_skip_scanlines() */
LOCAL(void)
noop_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
@ -660,6 +676,8 @@ _jpeg_read_raw_data(j_decompress_ptr cinfo, _JSAMPIMAGE data,
return lines_per_iMCU_row;
}
#endif /* BITS_IN_JSAMPLE != 16 */
#if BITS_IN_JSAMPLE == 8

View File

@ -6,6 +6,7 @@
* libjpeg-turbo Modifications:
* Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
* Copyright (C) 2020, Google, Inc.
* Copyright (C) 2022, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
@ -14,6 +15,8 @@
#include "jpeglib.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/* Block smoothing is only applicable for progressive JPEG, so: */
#ifndef D_PROGRESSIVE_SUPPORTED
#undef BLOCK_SMOOTHING_SUPPORTED
@ -81,3 +84,5 @@ start_iMCU_row(j_decompress_ptr cinfo)
coef->MCU_ctr = 0;
coef->MCU_vert_offset = 0;
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -21,6 +21,7 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION input_row, _JSAMPARRAY output_buf,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int y, cb, cr;
register _JSAMPROW outptr;
@ -91,6 +92,9 @@ ycc_rgb565_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
*(INT16 *)outptr = (INT16)rgb;
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -100,6 +104,7 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION input_row, _JSAMPARRAY output_buf,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int y, cb, cr;
register _JSAMPROW outptr;
@ -177,6 +182,9 @@ ycc_rgb565D_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
*(INT16 *)outptr = (INT16)rgb;
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}

View File

@ -32,6 +32,7 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION input_row, _JSAMPARRAY output_buf,
int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int y, cb, cr;
register _JSAMPROW outptr;
@ -70,6 +71,9 @@ ycc_rgb_convert_internal(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
outptr += RGB_PIXELSIZE;
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}

View File

@ -21,11 +21,14 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/* Private subobject */
typedef struct {
struct jpeg_color_deconverter pub; /* public fields */
#if BITS_IN_JSAMPLE != 16
/* Private state for YCC->RGB conversion */
int *Cr_r_tab; /* => table for Cr to R conversion */
int *Cb_b_tab; /* => table for Cb to B conversion */
@ -34,6 +37,7 @@ typedef struct {
/* Private state for RGB->Y conversion */
JLONG *rgb_y_tab; /* => table for RGB to Y conversion */
#endif
} my_color_deconverter;
typedef my_color_deconverter *my_cconvert_ptr;
@ -210,6 +214,7 @@ typedef my_color_deconverter *my_cconvert_ptr;
LOCAL(void)
build_ycc_rgb_table(j_decompress_ptr cinfo)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
int i;
JLONG x;
@ -243,6 +248,9 @@ build_ycc_rgb_table(j_decompress_ptr cinfo)
/* We also add in ONE_HALF so that need not do it in inner loop */
cconvert->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -301,6 +309,7 @@ ycc_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
LOCAL(void)
build_rgb_y_table(j_decompress_ptr cinfo)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
JLONG *rgb_y_tab;
JLONG i;
@ -315,6 +324,9 @@ build_rgb_y_table(j_decompress_ptr cinfo)
rgb_y_tab[i + G_Y_OFF] = FIX(0.58700) * i;
rgb_y_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -326,6 +338,7 @@ METHODDEF(void)
rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int r, g, b;
register JLONG *ctab = cconvert->rgb_y_tab;
@ -349,6 +362,9 @@ rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
ctab[b + B_Y_OFF]) >> SCALEBITS);
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -528,6 +544,7 @@ METHODDEF(void)
ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)
{
#if BITS_IN_JSAMPLE != 16
my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;
register int y, cb, cr;
register _JSAMPROW outptr;
@ -564,6 +581,9 @@ ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,
outptr += 4;
}
}
#else
ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
#endif
}
@ -901,3 +921,5 @@ _jinit_color_deconverter(j_decompress_ptr cinfo)
else
cinfo->output_components = cinfo->out_color_components;
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -57,7 +57,12 @@ initial_setup(j_decompress_ptr cinfo)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int)JPEG_MAX_DIMENSION);
/* For now, precision must match compiled-in value... */
#ifdef D_LOSSLESS_SUPPORTED
if (cinfo->data_precision != 8 && cinfo->data_precision != 12 &&
cinfo->data_precision != 16)
#else
if (cinfo->data_precision != 8 && cinfo->data_precision != 12)
#endif
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Check that number of components won't exceed internal array sizes */

View File

@ -20,6 +20,8 @@
#include "jdmainct.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/*
* In the current system design, the main buffer need never be a full-image
* buffer; any full-height buffers will be found inside the coefficient,
@ -463,3 +465,5 @@ _jinit_d_main_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
(JDIMENSION)(rgroup * ngroups));
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -15,6 +15,8 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/* Private buffer controller object */
typedef struct {
@ -72,3 +74,5 @@ set_wraparound_pointers(j_decompress_ptr cinfo)
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -414,9 +414,39 @@ prepare_range_limit_table(j_decompress_ptr cinfo)
{
JSAMPLE *table;
J12SAMPLE *table12;
#ifdef D_LOSSLESS_SUPPORTED
J16SAMPLE *table16;
#endif
int i;
if (cinfo->data_precision == 12) {
if (cinfo->data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
table16 = (J16SAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(5 * (MAXJ16SAMPLE + 1) + CENTERJ16SAMPLE) *
sizeof(J16SAMPLE));
table16 += (MAXJ16SAMPLE + 1); /* allow negative subscripts of simple
table */
cinfo->sample_range_limit = (JSAMPLE *)table16;
/* First segment of "simple" table: limit[x] = 0 for x < 0 */
memset(table16 - (MAXJ16SAMPLE + 1), 0,
(MAXJ16SAMPLE + 1) * sizeof(J16SAMPLE));
/* Main part of "simple" table: limit[x] = x */
for (i = 0; i <= MAXJ16SAMPLE; i++)
table16[i] = (J16SAMPLE)i;
table16 += CENTERJ16SAMPLE; /* Point to where post-IDCT table starts */
/* End of simple table, rest of first half of post-IDCT table */
for (i = CENTERJ16SAMPLE; i < 2 * (MAXJ16SAMPLE + 1); i++)
table16[i] = MAXJ16SAMPLE;
/* Second half of post-IDCT table */
memset(table16 + (2 * (MAXJ16SAMPLE + 1)), 0,
(2 * (MAXJ16SAMPLE + 1) - CENTERJ16SAMPLE) * sizeof(J16SAMPLE));
memcpy(table16 + (4 * (MAXJ16SAMPLE + 1) - CENTERJ16SAMPLE),
cinfo->sample_range_limit, CENTERJ16SAMPLE * sizeof(J16SAMPLE));
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
table12 = (J12SAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(5 * (MAXJ12SAMPLE + 1) + CENTERJ12SAMPLE) *
@ -536,7 +566,13 @@ master_selection(j_decompress_ptr cinfo)
if (cinfo->enable_1pass_quant) {
#ifdef QUANT_1PASS_SUPPORTED
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
j16init_1pass_quantizer(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_1pass_quantizer(cinfo);
else
jinit_1pass_quantizer(cinfo);
@ -549,7 +585,13 @@ master_selection(j_decompress_ptr cinfo)
/* We use the 2-pass code to map to external colormaps. */
if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
#ifdef QUANT_2PASS_SUPPORTED
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
j16init_2pass_quantizer(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_2pass_quantizer(cinfo);
else
jinit_2pass_quantizer(cinfo);
@ -567,7 +609,9 @@ master_selection(j_decompress_ptr cinfo)
if (!cinfo->raw_data_out) {
if (master->using_merged_upsample) {
#ifdef UPSAMPLE_MERGING_SUPPORTED
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
else if (cinfo->data_precision == 12)
j12init_merged_upsampler(cinfo); /* does color conversion too */
else
jinit_merged_upsampler(cinfo); /* does color conversion too */
@ -575,7 +619,14 @@ master_selection(j_decompress_ptr cinfo)
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
if (cinfo->data_precision == 12) {
if (cinfo->data_precision == 16) {
#ifdef D_LOSSLESS_SUPPORTED
j16init_color_deconverter(cinfo);
j16init_upsampler(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
} else if (cinfo->data_precision == 12) {
j12init_color_deconverter(cinfo);
j12init_upsampler(cinfo);
} else {
@ -583,7 +634,13 @@ master_selection(j_decompress_ptr cinfo)
jinit_upsampler(cinfo);
}
}
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
j16init_d_post_controller(cinfo, cinfo->enable_2pass_quant);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_d_post_controller(cinfo, cinfo->enable_2pass_quant);
else
jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
@ -594,7 +651,9 @@ master_selection(j_decompress_ptr cinfo)
/* Prediction, sample undifferencing, point transform, and sample size
* scaling
*/
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
j16init_lossless_decompressor(cinfo);
else if (cinfo->data_precision == 12)
j12init_lossless_decompressor(cinfo);
else
jinit_lossless_decompressor(cinfo);
@ -608,7 +667,9 @@ master_selection(j_decompress_ptr cinfo)
/* Initialize principal buffer controllers. */
use_c_buffer = cinfo->inputctl->has_multiple_scans ||
cinfo->buffered_image;
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
j16init_d_diff_controller(cinfo, use_c_buffer);
else if (cinfo->data_precision == 12)
j12init_d_diff_controller(cinfo, use_c_buffer);
else
jinit_d_diff_controller(cinfo, use_c_buffer);
@ -616,6 +677,8 @@ master_selection(j_decompress_ptr cinfo)
ERREXIT(cinfo, JERR_NOT_COMPILED);
#endif
} else {
if (cinfo->data_precision == 16)
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Inverse DCT */
if (cinfo->data_precision == 12)
j12init_inverse_dct(cinfo);
@ -649,7 +712,14 @@ master_selection(j_decompress_ptr cinfo)
}
if (!cinfo->raw_data_out) {
if (cinfo->data_precision == 12)
if (cinfo->data_precision == 16)
#ifdef D_LOSSLESS_SUPPORTED
j16init_d_main_controller(cinfo,
FALSE /* never need full buffer here */);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
#endif
else if (cinfo->data_precision == 12)
j12init_d_main_controller(cinfo,
FALSE /* never need full buffer here */);
else

View File

@ -25,6 +25,8 @@
#include "jsamplecomp.h"
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/* Private buffer controller object */
typedef struct {
@ -296,3 +298,5 @@ _jinit_d_post_controller(j_decompress_ptr cinfo, boolean need_full_buffer)
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -32,6 +32,8 @@
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/*
* Initialize for an upsampling pass.
*/
@ -534,3 +536,5 @@ _jinit_upsampler(j_decompress_ptr cinfo)
}
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */

View File

@ -353,9 +353,10 @@ alloc_small(j_common_ptr cinfo, int pool_id, size_t sizeofobject)
* request is large enough that it may as well be passed directly to
* jpeg_get_large; the pool management just links everything together
* so that we can free it all on demand.
* Note: the major use of "large" objects is in JSAMPARRAY/J12SAMPARRAY and
* JBLOCKARRAY structures. The routines that create these structures (see
* below) deliberately bunch rows together to ensure a large request size.
* Note: the major use of "large" objects is in
* JSAMPARRAY/J12SAMPARRAY/J16SAMPARRAY and JBLOCKARRAY structures. The
* routines that create these structures (see below) deliberately bunch rows
* together to ensure a large request size.
*/
METHODDEF(void *)
@ -441,11 +442,17 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
long ltemp;
J12SAMPARRAY result12;
J12SAMPROW workspace12;
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
J16SAMPARRAY result16;
J16SAMPROW workspace16;
#endif
int data_precision = cinfo->is_decompressor ?
((j_decompress_ptr)cinfo)->data_precision :
((j_compress_ptr)cinfo)->data_precision;
size_t sample_size = data_precision == 12 ?
sizeof(J12SAMPLE) : sizeof(JSAMPLE);
size_t sample_size = data_precision == 16 ?
sizeof(J16SAMPLE) : (data_precision == 12 ?
sizeof(J12SAMPLE) :
sizeof(JSAMPLE));
/* Make sure each row is properly aligned */
if ((ALIGN_SIZE % sample_size) != 0)
@ -470,7 +477,31 @@ alloc_sarray(j_common_ptr cinfo, int pool_id, JDIMENSION samplesperrow,
rowsperchunk = numrows;
mem->last_rowsperchunk = rowsperchunk;
if (data_precision == 12) {
if (data_precision == 16) {
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
/* Get space for row pointers (small object) */
result16 = (J16SAMPARRAY)alloc_small(cinfo, pool_id,
(size_t)(numrows *
sizeof(J16SAMPROW)));
/* Get the rows themselves (large objects) */
currow = 0;
while (currow < numrows) {
rowsperchunk = MIN(rowsperchunk, numrows - currow);
workspace16 = (J16SAMPROW)alloc_large(cinfo, pool_id,
(size_t)((size_t)rowsperchunk * (size_t)samplesperrow * sample_size));
for (i = rowsperchunk; i > 0; i--) {
result16[currow++] = workspace16;
workspace16 += samplesperrow;
}
}
return (JSAMPARRAY)result16;
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
return NULL;
#endif
} else if (data_precision == 12) {
/* Get space for row pointers (small object) */
result12 = (J12SAMPARRAY)alloc_small(cinfo, pool_id,
(size_t)(numrows *
@ -672,8 +703,10 @@ realize_virt_arrays(j_common_ptr cinfo)
int data_precision = cinfo->is_decompressor ?
((j_decompress_ptr)cinfo)->data_precision :
((j_compress_ptr)cinfo)->data_precision;
size_t sample_size = data_precision == 12 ?
sizeof(J12SAMPLE) : sizeof(JSAMPLE);
size_t sample_size = data_precision == 16 ?
sizeof(J16SAMPLE) : (data_precision == 12 ?
sizeof(J12SAMPLE) :
sizeof(JSAMPLE));
/* Compute the minimum space needed (maxaccess rows in each buffer)
* and the maximum space needed (full image height in each buffer).
@ -788,8 +821,10 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
int data_precision = cinfo->is_decompressor ?
((j_decompress_ptr)cinfo)->data_precision :
((j_compress_ptr)cinfo)->data_precision;
size_t sample_size = data_precision == 12 ?
sizeof(J12SAMPLE) : sizeof(JSAMPLE);
size_t sample_size = data_precision == 16 ?
sizeof(J16SAMPLE) : (data_precision == 12 ?
sizeof(J12SAMPLE) :
sizeof(JSAMPLE));
bytesperrow = (long)ptr->samplesperrow * (long)sample_size;
file_offset = ptr->cur_start_row * bytesperrow;
@ -805,7 +840,22 @@ do_sarray_io(j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
if (rows <= 0) /* this chunk might be past end of file! */
break;
byte_count = rows * bytesperrow;
if (data_precision == 12) {
if (data_precision == 16) {
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
J16SAMPARRAY mem_buffer16 = (J16SAMPARRAY)ptr->mem_buffer;
if (writing)
(*ptr->b_s_info.write_backing_store) (cinfo, &ptr->b_s_info,
(void *)mem_buffer16[i],
file_offset, byte_count);
else
(*ptr->b_s_info.read_backing_store) (cinfo, &ptr->b_s_info,
(void *)mem_buffer16[i],
file_offset, byte_count);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, data_precision);
#endif
} else if (data_precision == 12) {
J12SAMPARRAY mem_buffer12 = (J12SAMPARRAY)ptr->mem_buffer;
if (writing)
@ -876,8 +926,10 @@ access_virt_sarray(j_common_ptr cinfo, jvirt_sarray_ptr ptr,
int data_precision = cinfo->is_decompressor ?
((j_decompress_ptr)cinfo)->data_precision :
((j_compress_ptr)cinfo)->data_precision;
size_t sample_size = data_precision == 12 ?
sizeof(J12SAMPLE) : sizeof(JSAMPLE);
size_t sample_size = data_precision == 16 ?
sizeof(J16SAMPLE) : (data_precision == 12 ?
sizeof(J12SAMPLE) :
sizeof(JSAMPLE));
/* debugging check */
if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||

View File

@ -60,6 +60,14 @@ typedef short J12SAMPLE;
#define CENTERJ12SAMPLE 2048
/* J16SAMPLE should be the smallest type that will hold the values 0..65535. */
typedef unsigned short J16SAMPLE;
#define MAXJ16SAMPLE 65535
#define CENTERJ16SAMPLE 32768
/* 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

View File

@ -106,6 +106,10 @@ struct jpeg_c_main_controller {
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
void (*process_data_12) (j_compress_ptr cinfo, J12SAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
#ifdef C_LOSSLESS_SUPPORTED
void (*process_data_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail);
#endif
};
/* Compression preprocessing (downsampling input buffer control) */
@ -122,6 +126,14 @@ struct jpeg_c_prep_controller {
J12SAMPIMAGE output_buf,
JDIMENSION *out_row_group_ctr,
JDIMENSION out_row_groups_avail);
#ifdef C_LOSSLESS_SUPPORTED
void (*pre_process_data_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
JDIMENSION *in_row_ctr,
JDIMENSION in_rows_avail,
J16SAMPIMAGE output_buf,
JDIMENSION *out_row_group_ctr,
JDIMENSION out_row_groups_avail);
#endif
};
/* Lossy mode: Coefficient buffer control
@ -131,6 +143,9 @@ struct jpeg_c_coef_controller {
void (*start_pass) (j_compress_ptr cinfo, J_BUF_MODE pass_mode);
boolean (*compress_data) (j_compress_ptr cinfo, JSAMPIMAGE input_buf);
boolean (*compress_data_12) (j_compress_ptr cinfo, J12SAMPIMAGE input_buf);
#ifdef C_LOSSLESS_SUPPORTED
boolean (*compress_data_16) (j_compress_ptr cinfo, J16SAMPIMAGE input_buf);
#endif
};
/* Colorspace conversion */
@ -142,6 +157,11 @@ struct jpeg_color_converter {
void (*color_convert_12) (j_compress_ptr cinfo, J12SAMPARRAY input_buf,
J12SAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows);
#ifdef C_LOSSLESS_SUPPORTED
void (*color_convert_16) (j_compress_ptr cinfo, J16SAMPARRAY input_buf,
J16SAMPIMAGE output_buf, JDIMENSION output_row,
int num_rows);
#endif
};
/* Downsampling */
@ -153,6 +173,11 @@ struct jpeg_downsampler {
void (*downsample_12) (j_compress_ptr cinfo, J12SAMPIMAGE input_buf,
JDIMENSION in_row_index, J12SAMPIMAGE output_buf,
JDIMENSION out_row_group_index);
#ifdef C_LOSSLESS_SUPPORTED
void (*downsample_16) (j_compress_ptr cinfo, J16SAMPIMAGE input_buf,
JDIMENSION in_row_index, J16SAMPIMAGE output_buf,
JDIMENSION out_row_group_index);
#endif
boolean need_context_rows; /* TRUE if need rows above & below */
};
@ -245,6 +270,10 @@ struct jpeg_d_main_controller {
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
void (*process_data_12) (j_decompress_ptr cinfo, J12SAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
#ifdef D_LOSSLESS_SUPPORTED
void (*process_data_16) (j_decompress_ptr cinfo, J16SAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
#endif
};
/* Lossy mode: Coefficient buffer control
@ -256,6 +285,9 @@ struct jpeg_d_coef_controller {
void (*start_output_pass) (j_decompress_ptr cinfo);
int (*decompress_data) (j_decompress_ptr cinfo, JSAMPIMAGE output_buf);
int (*decompress_data_12) (j_decompress_ptr cinfo, J12SAMPIMAGE output_buf);
#ifdef D_LOSSLESS_SUPPORTED
int (*decompress_data_16) (j_decompress_ptr cinfo, J16SAMPIMAGE output_buf);
#endif
/* These variables keep track of the current location of the input side. */
/* cinfo->input_iMCU_row is also used for this. */
@ -284,6 +316,14 @@ struct jpeg_d_post_controller {
J12SAMPARRAY output_buf,
JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail);
#ifdef D_LOSSLESS_SUPPORTED
void (*post_process_data_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail,
J16SAMPARRAY output_buf,
JDIMENSION *out_row_ctr,
JDIMENSION out_rows_avail);
#endif
};
/* Marker reading & parsing */
@ -358,6 +398,12 @@ struct jpeg_upsampler {
JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, J12SAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
#ifdef D_LOSSLESS_SUPPORTED
void (*upsample_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
JDIMENSION *in_row_group_ctr,
JDIMENSION in_row_groups_avail, J16SAMPARRAY output_buf,
JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail);
#endif
boolean need_context_rows; /* TRUE if need rows above & below */
};
@ -371,6 +417,11 @@ struct jpeg_color_deconverter {
void (*color_convert_12) (j_decompress_ptr cinfo, J12SAMPIMAGE input_buf,
JDIMENSION input_row, J12SAMPARRAY output_buf,
int num_rows);
#ifdef D_LOSSLESS_SUPPORTED
void (*color_convert_16) (j_decompress_ptr cinfo, J16SAMPIMAGE input_buf,
JDIMENSION input_row, J16SAMPARRAY output_buf,
int num_rows);
#endif
};
/* Color quantization or color precision reduction */
@ -380,6 +431,10 @@ struct jpeg_color_quantizer {
JSAMPARRAY output_buf, int num_rows);
void (*color_quantize_12) (j_decompress_ptr cinfo, J12SAMPARRAY input_buf,
J12SAMPARRAY output_buf, int num_rows);
#ifdef D_LOSSLESS_SUPPORTED
void (*color_quantize_16) (j_decompress_ptr cinfo, J16SAMPARRAY input_buf,
J16SAMPARRAY output_buf, int num_rows);
#endif
void (*finish_pass) (j_decompress_ptr cinfo);
void (*new_color_map) (j_decompress_ptr cinfo);
};
@ -442,13 +497,22 @@ EXTERN(void) jinit_phuff_encoder(j_compress_ptr cinfo);
EXTERN(void) jinit_arith_encoder(j_compress_ptr cinfo);
EXTERN(void) jinit_marker_writer(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(void) j16init_c_main_controller(j_compress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_c_prep_controller(j_compress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_color_converter(j_compress_ptr cinfo);
EXTERN(void) j16init_downsampler(j_compress_ptr cinfo);
EXTERN(void) jinit_c_diff_controller(j_compress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j12init_c_diff_controller(j_compress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_c_diff_controller(j_compress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) jinit_lhuff_encoder(j_compress_ptr cinfo);
EXTERN(void) jinit_lossless_compressor(j_compress_ptr cinfo);
EXTERN(void) j12init_lossless_compressor(j_compress_ptr cinfo);
EXTERN(void) j16init_lossless_compressor(j_compress_ptr cinfo);
#endif
/* Decompression module initialization routines */
@ -483,13 +547,24 @@ EXTERN(void) j12init_2pass_quantizer(j_decompress_ptr cinfo);
EXTERN(void) jinit_merged_upsampler(j_decompress_ptr cinfo);
EXTERN(void) j12init_merged_upsampler(j_decompress_ptr cinfo);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(void) j16init_d_main_controller(j_decompress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_d_post_controller(j_decompress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_upsampler(j_decompress_ptr cinfo);
EXTERN(void) j16init_color_deconverter(j_decompress_ptr cinfo);
EXTERN(void) j16init_1pass_quantizer(j_decompress_ptr cinfo);
EXTERN(void) j16init_2pass_quantizer(j_decompress_ptr cinfo);
EXTERN(void) jinit_d_diff_controller(j_decompress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j12init_d_diff_controller(j_decompress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) j16init_d_diff_controller(j_decompress_ptr cinfo,
boolean need_full_buffer);
EXTERN(void) jinit_lhuff_decoder(j_decompress_ptr cinfo);
EXTERN(void) jinit_lossless_decompressor(j_decompress_ptr cinfo);
EXTERN(void) j12init_lossless_decompressor(j_decompress_ptr cinfo);
EXTERN(void) j16init_lossless_decompressor(j_decompress_ptr cinfo);
#endif
/* Memory manager initialization */
@ -504,6 +579,11 @@ EXTERN(void) jcopy_sample_rows(JSAMPARRAY input_array, int source_row,
EXTERN(void) j12copy_sample_rows(J12SAMPARRAY input_array, int source_row,
J12SAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols);
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
EXTERN(void) j16copy_sample_rows(J16SAMPARRAY input_array, int source_row,
J16SAMPARRAY output_array, int dest_row,
int num_rows, JDIMENSION num_cols);
#endif
EXTERN(void) jcopy_block_row(JBLOCKROW input_row, JBLOCKROW output_row,
JDIMENSION num_blocks);
EXTERN(void) jzero_far(void *target, size_t bytestozero);

View File

@ -86,6 +86,13 @@ typedef J12SAMPROW *J12SAMPARRAY; /* ptr to some 12-bit sample rows (a 2-D
typedef J12SAMPARRAY *J12SAMPIMAGE; /* a 3-D 12-bit sample array: top index is
color */
typedef J16SAMPLE *J16SAMPROW; /* ptr to one image row of 16-bit pixel
samples. */
typedef J16SAMPROW *J16SAMPARRAY; /* ptr to some 16-bit sample rows (a 2-D
16-bit sample array) */
typedef J16SAMPARRAY *J16SAMPIMAGE; /* a 3-D 16-bit sample array: top index is
color */
typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
typedef JBLOCK *JBLOCKROW; /* pointer to one row of coefficient blocks */
typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
@ -566,10 +573,11 @@ struct jpeg_decompress_struct {
*/
int actual_number_of_colors; /* number of entries in use */
JSAMPARRAY colormap; /* The color map as a 2-D pixel array
If data_precision is 12, then this is
actually a J12SAMPARRAY, so callers must
type-cast it in order to read/write 12-bit
samples from/to the array. */
If data_precision is 12 or 16, then this is
actually a J12SAMPARRAY or a J16SAMPARRAY,
so callers must type-cast it in order to
read/write 12-bit or 16-bit samples from/to
the array. */
/* State variables: these variables indicate the progress of decompression.
* The application may examine these but must not modify them.
@ -689,10 +697,11 @@ struct jpeg_decompress_struct {
*/
JSAMPLE *sample_range_limit; /* table for fast range-limiting
If data_precision is 12, then this is
actually a J12SAMPLE pointer, so callers
must type-cast it in order to read 12-bit
samples from the array. */
If data_precision is 12 or 16, then this is
actually a J12SAMPLE pointer or a J16SAMPLE
pointer, so callers must type-cast it in
order to read 12-bit or 16-bit samples from
the array. */
/*
* These fields are valid during any one scan.
@ -873,10 +882,10 @@ struct jpeg_memory_mgr {
void *(*alloc_small) (j_common_ptr cinfo, int pool_id, size_t sizeofobject);
void *(*alloc_large) (j_common_ptr cinfo, int pool_id,
size_t sizeofobject);
/* If cinfo->data_precision is 12, then this method and the
* access_virt_sarray method actually return a J12SAMPARRAY, so callers must
* type-cast the return value in order to read/write 12-bit samples from/to
* the array.
/* If cinfo->data_precision is 12 or 16, then this method and the
* access_virt_sarray method actually return a J12SAMPARRAY or a
* J16SAMPARRAY, so callers must type-cast the return value in order to
* read/write 12-bit or 16-bit samples from/to the array.
*/
JSAMPARRAY (*alloc_sarray) (j_common_ptr cinfo, int pool_id,
JDIMENSION samplesperrow, JDIMENSION numrows);
@ -1000,6 +1009,9 @@ EXTERN(JDIMENSION) jpeg_write_scanlines(j_compress_ptr cinfo,
EXTERN(JDIMENSION) jpeg12_write_scanlines(j_compress_ptr cinfo,
J12SAMPARRAY scanlines,
JDIMENSION num_lines);
EXTERN(JDIMENSION) jpeg16_write_scanlines(j_compress_ptr cinfo,
J16SAMPARRAY scanlines,
JDIMENSION num_lines);
EXTERN(void) jpeg_finish_compress(j_compress_ptr cinfo);
#if JPEG_LIB_VERSION >= 70
@ -1051,6 +1063,9 @@ EXTERN(JDIMENSION) jpeg_read_scanlines(j_decompress_ptr cinfo,
EXTERN(JDIMENSION) jpeg12_read_scanlines(j_decompress_ptr cinfo,
J12SAMPARRAY scanlines,
JDIMENSION max_lines);
EXTERN(JDIMENSION) jpeg16_read_scanlines(j_decompress_ptr cinfo,
J16SAMPARRAY scanlines,
JDIMENSION max_lines);
EXTERN(JDIMENSION) jpeg_skip_scanlines(j_decompress_ptr cinfo,
JDIMENSION num_lines);
EXTERN(JDIMENSION) jpeg12_skip_scanlines(j_decompress_ptr cinfo,

View File

@ -18,7 +18,8 @@
#include "jpeglib.h"
#include "jsamplecomp.h"
#ifdef QUANT_1PASS_SUPPORTED
#if defined(QUANT_1PASS_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED))
/*
@ -857,4 +858,5 @@ _jinit_1pass_quantizer(j_decompress_ptr cinfo)
alloc_fs_workspace(cinfo);
}
#endif /* QUANT_1PASS_SUPPORTED */
#endif /* defined(QUANT_1PASS_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)) */

View File

@ -25,7 +25,8 @@
#include "jpeglib.h"
#include "jsamplecomp.h"
#ifdef QUANT_2PASS_SUPPORTED
#if defined(QUANT_2PASS_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED))
/*
@ -1289,4 +1290,5 @@ _jinit_2pass_quantizer(j_decompress_ptr cinfo)
}
}
#endif /* QUANT_2PASS_SUPPORTED */
#endif /* defined(QUANT_2PASS_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)) */

View File

@ -16,7 +16,99 @@
#ifndef JSAMPLECOMP_H
#define JSAMPLECOMP_H
#if BITS_IN_JSAMPLE == 12
#if BITS_IN_JSAMPLE == 16
/* Sample data types and macros (jmorecfg.h) */
#define _JSAMPLE J16SAMPLE
#define _MAXJSAMPLE MAXJ16SAMPLE
#define _CENTERJSAMPLE CENTERJ16SAMPLE
#define _JSAMPROW J16SAMPROW
#define _JSAMPARRAY J16SAMPARRAY
#define _JSAMPIMAGE J16SAMPIMAGE
/* External functions (jpeglib.h) */
#define _jpeg_write_scanlines jpeg16_write_scanlines
#define _jpeg_read_scanlines jpeg16_read_scanlines
/* Internal methods (jpegint.h) */
#ifdef C_LOSSLESS_SUPPORTED
/* Use the 16-bit method in the jpeg_c_main_controller structure. */
#define _process_data process_data_16
/* Use the 16-bit method in the jpeg_c_prep_controller structure. */
#define _pre_process_data pre_process_data_16
/* Use the 16-bit method in the jpeg_c_coef_controller structure. */
#define _compress_data compress_data_16
/* Use the 16-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert_16
/* Use the 16-bit method in the jpeg_downsampler structure. */
#define _downsample downsample_16
#endif
#ifdef D_LOSSLESS_SUPPORTED
/* Use the 16-bit method in the jpeg_d_main_controller structure. */
#define _process_data process_data_16
/* Use the 16-bit method in the jpeg_d_coef_controller structure. */
#define _decompress_data decompress_data_16
/* Use the 16-bit method in the jpeg_d_post_controller structure. */
#define _post_process_data post_process_data_16
/* Use the 16-bit method in the jpeg_upsampler structure. */
#define _upsample upsample_16
/* Use the 16-bit method in the jpeg_color_converter structure. */
#define _color_convert color_convert_16
/* Use the 16-bit method in the jpeg_color_quantizer structure. */
#define _color_quantize color_quantize_16
#endif
/* Global internal functions (jpegint.h) */
#ifdef C_LOSSLESS_SUPPORTED
#define _jinit_c_main_controller j16init_c_main_controller
#define _jinit_c_prep_controller j16init_c_prep_controller
#define _jinit_color_converter j16init_color_converter
#define _jinit_downsampler j16init_downsampler
#define _jinit_c_diff_controller j16init_c_diff_controller
#define _jinit_lossless_compressor j16init_lossless_compressor
#endif
#ifdef D_LOSSLESS_SUPPORTED
#define _jinit_d_main_controller j16init_d_main_controller
#define _jinit_d_post_controller j16init_d_post_controller
#define _jinit_upsampler j16init_upsampler
#define _jinit_color_deconverter j16init_color_deconverter
#define _jinit_1pass_quantizer j16init_1pass_quantizer
#define _jinit_2pass_quantizer j16init_2pass_quantizer
#define _jinit_merged_upsampler j16init_merged_upsampler
#define _jinit_d_diff_controller j16init_d_diff_controller
#define _jinit_lossless_decompressor j16init_lossless_decompressor
#endif
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
#define _jcopy_sample_rows j16copy_sample_rows
#endif
/* Internal fields (cdjpeg.h) */
#if defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
/* Use the 16-bit buffer in the cjpeg_source_struct and djpeg_dest_struct
structures. */
#define _buffer buffer16
#endif
/* Image I/O functions (cdjpeg.h) */
#ifdef C_LOSSLESS_SUPPORTED
#define _jinit_read_gif j16init_read_gif
#define _jinit_read_ppm j16init_read_ppm
#endif
#ifdef D_LOSSLESS_SUPPORTED
#define _jinit_write_gif j16init_write_gif
#define _jinit_write_ppm j16init_write_ppm
#define _read_color_map read_color_map_16
#endif
#elif BITS_IN_JSAMPLE == 12
/* Sample data types and macros (jmorecfg.h) */
#define _JSAMPLE J12SAMPLE

View File

@ -95,6 +95,9 @@ jround_up(long a, long b)
#endif /* BITS_IN_JSAMPLE == 8 */
#if BITS_IN_JSAMPLE != 16 || \
defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED)
GLOBAL(void)
_jcopy_sample_rows(_JSAMPARRAY input_array, int source_row,
_JSAMPARRAY output_array, int dest_row, int num_rows,
@ -119,6 +122,9 @@ _jcopy_sample_rows(_JSAMPARRAY input_array, int source_row,
}
}
#endif /* BITS_IN_JSAMPLE != 16 ||
defined(C_LOSSLESS_SUPPORTED) || defined(D_LOSSLESS_SUPPORTED) */
#if BITS_IN_JSAMPLE == 8

View File

@ -31,7 +31,7 @@ TABLE OF CONTENTS
Overview:
Functions provided by the library
12-bit Data Precision
12-bit and 16-bit Data Precision
Outline of typical usage
Basic library usage:
Data formats
@ -101,7 +101,8 @@ use.) Unsupported ISO options include:
* Hierarchical storage
* DNL marker
* Nonintegral subsampling ratios
We support both 8- and 12-bit data precision.
We support 8-bit (lossy and lossless), 12-bit (lossy and lossless), and 16-bit
(lossless) data precision.
By itself, the library handles only interchange JPEG datastreams --- in
particular the widely used JFIF file format. The library can be used by
@ -110,15 +111,17 @@ are embedded in more complex file formats. (For example, this library is
used by the free LIBTIFF library to support JPEG compression in TIFF.)
12-bit Data Precision
---------------------
12-bit and 16-bit Data Precision
--------------------------------
The JPEG standard provides for both the baseline 8-bit DCT process and a 12-bit
DCT process. The IJG code supports 12-bit-per-component lossy JPEG if you set
cinfo->data_precision to 12. Note that this causes the sample size to be
The JPEG standard provides for baseline 8-bit and 12-bit DCT processes as well
as 8-bit, 12-bit, and 16-bit lossless (predictive) processes. This code
supports 12-bit-per-component lossy or lossless JPEG if you set
cinfo->data_precision to 12 and 16-bit-per-component lossless JPEG if you set
cinfo->data_precision to 16. Note that this causes the sample size to be
larger than a char, so it affects the surrounding application's image data.
The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
and GIF file formats.
The sample applications cjpeg and djpeg can support 12-bit and 16-bit mode only
for PPM and GIF file formats.
Note that, when 12-bit data precision is enabled, the library always compresses
in Huffman optimization mode, in order to generate valid Huffman tables. This
@ -138,15 +141,26 @@ instead of "jpeg_" and use the following data types and macros:
* MAXJ12SAMPLE instead of MAXJSAMPLE
* CENTERJ12SAMPLE instead of CENTERJSAMPLE
This allows both 8-bit and 12-bit data precision to be used in a single
Functions that are specific to 16-bit data precision have a prefix of "jpeg16_"
instead of "jpeg_" and use the following data types and macros:
* J16SAMPLE instead of JSAMPLE
* J16SAMPROW instead of JSAMPROW
* J16SAMPARRAY instead of JSAMPARRAY
* J16SAMPIMAGE instead of JSAMPIMAGE
* MAXJ16SAMPLE instead of MAXJSAMPLE
* CENTERJ16SAMPLE instead of CENTERJSAMPLE
This allows 8-bit, 12-bit, and 16-bit data precision to be used in a single
application. (Refer to example.c). Arithmetic coding and SIMD acceleration
are not currently implemented for 12-bit data precision.
are not currently implemented for 12-bit data precision, nor are they
implemented for lossless mode with any data precision.
Refer to the descriptions of the data_precision compression and decompression
parameters below for further information.
This documentation uses "J*SAMPLE", "J*SAMPROW", "J*SAMPARRAY", and
"J*SAMPIMAGE" to generically refer to either the 8-bit or 12-bit data types.
"J*SAMPIMAGE" to generically refer to the 8-bit, 12-bit, or 16-bit data types.
Outline of typical usage
@ -160,7 +174,9 @@ The rough outline of a JPEG compression operation is:
jpeg_start_compress(...);
while (scan lines remain to be written)
jpeg_write_scanlines(...); /* Use jpeg12_write_scanlines() for
12-bit data precision. */
12-bit data precision and
jpeg16_write_scanlines() for
16-bit data precision. */
jpeg_finish_compress(...);
Release the JPEG compression object
@ -188,7 +204,9 @@ Similarly, the rough outline of a JPEG decompression operation is:
jpeg_start_decompress(...);
while (scan lines remain to be read)
jpeg_read_scanlines(...); /* Use jpeg12_read_scanlines() for
12-bit data precision. */
12-bit data precision and
jpeg16_read_scanlines() for
16-bit data precision. */
jpeg_finish_decompress(...);
Release the JPEG decompression object
@ -270,7 +288,7 @@ For best results, source data values should have the precision specified by
cinfo->data_precision (normally 8 bits). For instance, if you choose to
compress data that's only 6 bits/channel, you should left-justify each value in
a byte before passing it to the compressor. If you need to compress data
that has more than 8 bits/channel, set cinfo->data_precision = 12.
that has more than 8 bits/channel, set cinfo->data_precision = 12 or 16.
The data format returned by the decompressor is the same in all details,
@ -283,8 +301,8 @@ a 2-D J*SAMPARRAY in which each row holds the values of one color component,
that is, colormap[i][j] is the value of the i'th color component for pixel
value (map index) j. Note that since the colormap indexes are stored in
J*SAMPLEs, the maximum number of colors is limited by the size of J*SAMPLE
(ie, at most 256 colors for 8-bit data precision and 4096 colors for 12-bit
data precision).
(ie, at most 256 colors for 8-bit data precision, 4096 colors for 12-bit data
precision, and 65536 colors for 16-bit data precision).
Compression details
@ -422,7 +440,9 @@ the compression cycle.
5. while (scan lines remain to be written)
jpeg_write_scanlines(...); /* Use jpeg12_write_scanlines() for 12-bit
data precision. */
data precision and
jpeg16_write_scanlines() for 16-bit data
precision. */
Now write all the required image data by calling jpeg*_write_scanlines()
one or more times. You can pass one or more scanlines in each call, up
@ -449,13 +469,16 @@ array containing 3-byte RGB pixels:
JSAMPROW row_pointer[1]; /* pointer to a single row
Use J12SAMPROW for 12-bit data
precision. */
precision and J16SAMPROW for 16-bit
data precision. */
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer[0] = image_buffer[cinfo.next_scanline];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
/* Use jpeg12_write_scanlines() for
12-bit data precision. */
12-bit data precision and
jpeg16_write_scanlines() for 16-bit
data precision. */
}
jpeg*_write_scanlines() returns the number of scanlines actually written.
@ -700,7 +723,9 @@ relevant parameters (scaling, output color space, and quantization flag).
6. while (scan lines remain to be read)
jpeg_read_scanlines(...); /* Use jpeg12_read_scanlines() for 12-bit
data precision. */
data precision and
jpeg16_read_scanlines() for 16-bit data
precision. */
Now you can read the decompressed image data by calling jpeg*_read_scanlines()
one or more times. At each call, you pass in the maximum number of scanlines
@ -1029,7 +1054,10 @@ int data_precision
To create a 12-bit-per-component JPEG file, set data_precision to 12
prior to calling jpeg_start_compress() or using the memory manager,
then use jpeg12_write_scanlines() or jpeg12_write_raw_data() instead of
jpeg_write_scanlines() or jpeg_write_raw_data().
jpeg_write_scanlines() or jpeg_write_raw_data(). To create a
16-bit-per-component lossless JPEG file, set data_precision to 16 prior
to calling jpeg_start_compress() or using the memory manager, then use
jpeg16_write_scanlines() instead of jpeg_write_scanlines().
J_DCT_METHOD dct_method
Selects the algorithm used for the DCT step. Choices are:
@ -1256,7 +1284,8 @@ int data_precision Data precision (bits per component)
jpeg12_skip_scanlines(), jpeg12_crop_scanline(), and/or
jpeg12_read_raw_data() instead of jpeg_read_scanlines(),
jpeg_skip_scanlines(), jpeg_crop_scanline(), and/or
jpeg_read_raw_data().
jpeg_read_raw_data(). If data_precision is 16, then use
jpeg16_read_scanlines() instead of jpeg_read_scanlines().
JDIMENSION image_width Width and height of image
JDIMENSION image_height
@ -1341,9 +1370,9 @@ JSAMPARRAY colormap
CAUTION: if the JPEG library creates its own colormap, the storage
pointed to by this field is released by jpeg_finish_decompress().
Copy the colormap somewhere else first, if you want to save it.
CAUTION: if data_precision is 12, then this is actually a J12SAMPARRAY,
so it must be type-cast in order to read 12-bit samples from or write
12-bit samples to the array.
CAUTION: if data_precision is 12 or 16, then this is actually a
J12SAMPARRAY or a J16SAMPARRAY, so it must be type-cast in order to
read/write 12-bit or 16-bit samples from/to the array.
int actual_number_of_colors
The number of colors in the color map.
@ -2053,7 +2082,9 @@ The basic control flow for buffered-image decoding is
jpeg_start_output() /* start a new output pass */
for (all scanlines in image) {
jpeg_read_scanlines() /* Use jpeg12_read_scanlines() for
12-bit data precision. */
12-bit data precision and
jpeg16_read_scanlines() for 16-bit
data precision. */
display scanlines
}
jpeg_finish_output() /* terminate output pass */
@ -3121,9 +3152,9 @@ This does not count any memory allocated by the application, such as a
buffer to hold the final output image.
The above figures are valid for 8-bit JPEG data precision and a machine with
32-bit ints. For 12-bit JPEG data, double the size of the strip buffers and
quantization pixel buffer. The "fixed-size" data will be somewhat smaller
with 16-bit ints, larger with 64-bit ints. Also, CMYK or other unusual
32-bit ints. For 12-bit and 16-bit JPEG data, double the size of the strip
buffers and quantization pixel buffer. The "fixed-size" data will be somewhat
smaller with 16-bit ints, larger with 64-bit ints. Also, CMYK or other unusual
color spaces will require different amounts of space.
The full-image coefficient and pixel buffers, if needed at all, do not

View File

@ -28,6 +28,7 @@
#include "jsamplecomp.h"
#ifdef QUANT_2PASS_SUPPORTED /* otherwise can't quantize to supplied map */
#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)
/* Portions of this code are based on the PBMPLUS library, which is:
**
@ -256,4 +257,5 @@ _read_color_map(j_decompress_ptr cinfo, FILE *infile)
}
}
#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */
#endif /* QUANT_2PASS_SUPPORTED */

View File

@ -36,7 +36,8 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jsamplecomp.h"
#ifdef GIF_SUPPORTED
#if defined(GIF_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED))
/* Macros to deal with unsigned chars as efficiently as compiler allows */
@ -721,4 +722,5 @@ _jinit_read_gif(j_compress_ptr cinfo)
return (cjpeg_source_ptr)source;
}
#endif /* GIF_SUPPORTED */
#endif /* defined(GIF_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)) */

View File

@ -25,7 +25,8 @@
#include "cmyk.h"
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef PPM_SUPPORTED
#if defined(PPM_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED))
/* Portions of this code are based on the PBMPLUS library, which is:
@ -781,4 +782,5 @@ _jinit_read_ppm(j_compress_ptr cinfo)
return (cjpeg_source_ptr)source;
}
#endif /* PPM_SUPPORTED */
#endif /* defined(PPM_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)) */

View File

@ -37,7 +37,7 @@ if(MSVC)
set(JPEG_SRCS ${JPEG_SRCS} ${CMAKE_BINARY_DIR}/win/jpeg.rc)
endif()
add_library(jpeg SHARED ${JPEG_SRCS} ${DEFFILE} ${SIMD_TARGET_OBJECTS}
${SIMD_OBJS} $<TARGET_OBJECTS:jpeg12>)
${SIMD_OBJS} $<TARGET_OBJECTS:jpeg12> $<TARGET_OBJECTS:jpeg16>)
set_target_properties(jpeg PROPERTIES SOVERSION ${SO_MAJOR_VERSION}
VERSION ${SO_MAJOR_VERSION}.${SO_AGE}.${SO_MINOR_VERSION})
@ -68,21 +68,31 @@ endif()
set(CDJPEG_COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
# Compile a separate version of these source files with 12-bit data precision.
# Compile a separate version of these source files with 12-bit and 16-bit data
# precision.
add_library(cjpeg12 OBJECT ../rdgif.c ../rdppm.c)
set_property(TARGET cjpeg12 PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=12 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_library(cjpeg16 OBJECT ../rdgif.c ../rdppm.c)
set_property(TARGET cjpeg16 PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=16 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_executable(cjpeg ../cjpeg.c ../cdjpeg.c ../rdbmp.c ../rdgif.c ../rdppm.c
../rdswitch.c ../rdtarga.c $<TARGET_OBJECTS:cjpeg12>)
../rdswitch.c ../rdtarga.c $<TARGET_OBJECTS:cjpeg12>
$<TARGET_OBJECTS:cjpeg16>)
set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS ${CDJPEG_COMPILE_FLAGS})
target_link_libraries(cjpeg jpeg)
# Compile a separate version of these source files with 12-bit data precision.
# Compile a separate version of these source files with 12-bit and 16-bit data
# precision.
add_library(djpeg12 OBJECT ../rdcolmap.c ../wrgif.c ../wrppm.c)
set_property(TARGET djpeg12 PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=12 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_library(djpeg16 OBJECT ../rdcolmap.c ../wrgif.c ../wrppm.c)
set_property(TARGET djpeg16 PROPERTY COMPILE_FLAGS
"-DBITS_IN_JSAMPLE=16 -DGIF_SUPPORTED -DPPM_SUPPORTED")
add_executable(djpeg ../djpeg.c ../cdjpeg.c ../rdcolmap.c ../rdswitch.c
../wrbmp.c ../wrgif.c ../wrppm.c ../wrtarga.c $<TARGET_OBJECTS:djpeg12>)
../wrbmp.c ../wrgif.c ../wrppm.c ../wrtarga.c $<TARGET_OBJECTS:djpeg12>
$<TARGET_OBJECTS:djpeg16>)
set_property(TARGET djpeg PROPERTY COMPILE_FLAGS ${CDJPEG_COMPILE_FLAGS})
target_link_libraries(djpeg jpeg)

View File

@ -519,9 +519,9 @@ shown are:
is not used for full-color output. Works on one pixel row at a time; may
require two passes to generate a color map. Note that the output will
always be a single component representing colormap indexes. In the current
design, the output values are JSAMPLEs or J12SAMPLEs, so the library cannot
quantize to more than 256 colors when using 8-bit data precision. This is
unlikely to be a problem in practice.
design, the output values are JSAMPLEs, J12SAMPLEs, or J16SAMPLEs, so the
library cannot quantize to more than 256 colors when using 8-bit data
precision. This is unlikely to be a problem in practice.
* Color reduction: this module handles color precision reduction, e.g.,
generating 15-bit color (5 bits/primary) from JPEG's 24-bit output.
@ -621,8 +621,16 @@ Arrays of 12-bit pixel sample values use the following data structure:
typedef J12SAMPROW *J12SAMPARRAY; ptr to a list of rows
typedef J12SAMPARRAY *J12SAMPIMAGE; ptr to a list of color-component arrays
The basic element type JSAMPLE (8-bit sample) will be unsigned char, and the
basic element type J12SAMPLE (12-bit sample) with be short.
Arrays of 16-bit pixel sample values use the following data structure:
typedef something J16SAMPLE; a pixel component value, 0..MAXJ16SAMPLE
typedef J16SAMPLE *J16SAMPROW; ptr to a row of samples
typedef J16SAMPROW *J16SAMPARRAY; ptr to a list of rows
typedef J16SAMPARRAY *J16SAMPIMAGE; ptr to a list of color-component arrays
The basic element type JSAMPLE (8-bit sample) will be unsigned char, the basic
element type J12SAMPLE (12-bit sample) will be short, and the basic element
type J16SAMPLE (16-bit sample) will be unsigned short.
With these conventions, J*SAMPLE values can be assumed to be >= 0. This helps
simplify correct rounding during downsampling, etc. The JPEG standard's
@ -633,7 +641,8 @@ decompression the output of the IDCT step will be immediately shifted back to
When 8-bit samples are in use, the code uses MAXJSAMPLE and CENTERJSAMPLE,
which are defined as 255 and 128 respectively. When 12-bit samples are in use,
the code uses MAXJ12SAMPLE and CENTERJ12SAMPLE, which are defined as 4095 and
2048 respectively.)
2048 respectively. When 16-bit samples are in use, the code uses MAXJ16SAMPLE
and CENTERJ16SAMPLE, which are defined as 65535 and 32768 respectively.)
We use a pointer per row, rather than a two-dimensional J*SAMPLE array. This
choice costs only a small amount of memory and has several benefits:

View File

@ -161,7 +161,11 @@ file size is about the same --- often a little smaller.
Switches for advanced users:
-precision N Create JPEG file with N-bit data precision.
N is 8 or 12; default is 8.
N is 8, 12, or 16; default is 8. If N is 16, then
-lossless must also be specified. CAUTION: 12-bit and
16-bit JPEG is not yet widely implemented, so many
decoders will be unable to view a 12-bit or 16-bit JPEG
file at all.
-lossless psv[,Pt] Create a lossless JPEG file using the specified
predictor selection value (1 - 7) and optional point

View File

@ -33,7 +33,8 @@
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "jsamplecomp.h"
#ifdef GIF_SUPPORTED
#if defined(GIF_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED))
#define MAX_LZW_BITS 12 /* maximum LZW code size (4096 symbols) */
@ -582,4 +583,5 @@ _jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw)
return (djpeg_dest_ptr)dest;
}
#endif /* GIF_SUPPORTED */
#endif /* defined(GIF_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)) */

View File

@ -22,7 +22,8 @@
#include "cmyk.h"
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#ifdef PPM_SUPPORTED
#if defined(PPM_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED))
/*
@ -366,4 +367,5 @@ _jinit_write_ppm(j_decompress_ptr cinfo)
return (djpeg_dest_ptr)dest;
}
#endif /* PPM_SUPPORTED */
#endif /* defined(PPM_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)) */