Back-port code from jpeg-8 that removes unpopulated (and unneeded) tables for AC and DC coefficients when generating progressive JPEG files with arithmetic coding. This should make such files bitwise compatible with jpeg-8, barring any other mathematical differences listed in README-turbo.txt. Add regression tests for progressive+arithmetic JPEG files.

git-svn-id: svn+ssh://svn.code.sf.net/p/libjpeg-turbo/code/trunk@1079 632fc199-4ca6-4c93-a231-07263d6284db
This commit is contained in:
DRC
2013-11-06 06:50:38 +00:00
3 changed files with 43 additions and 42 deletions

View File

@@ -309,6 +309,7 @@ set(MD5_BMP_256 4980185e3776e89bd931736e1cddeee6)
set(MD5_JPEG_ARI e986fb0a637a8d833d96e8a6d6d84ea1)
set(MD5_PPM_ARI 72b59a99bcf1de24c5b27d151bde2437)
set(MD5_JPEG_PROG 1c4afddc05c0a43489ee54438a482d92)
set(MD5_JPEG_PROG_ARI 0a8f1c8f66e113c3cf635df0a475a617)
set(MD5_JPEG_CROP b4197f377e621c4e9b1d20471432610d)
if(WITH_JAVA)
@@ -366,6 +367,8 @@ add_test(cjpeg-ari sharedlib/cjpeg -dct int -arithmetic -outfile testoutari.jpg
add_test(cjpeg-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(jpegtran-toari sharedlib/jpegtran -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg)
add_test(jpegtran-toari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-prog-ari sharedlib/cjpeg -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-prog-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-ari sharedlib/djpeg -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)
@@ -423,6 +426,8 @@ add_test(cjpeg-static-ari cjpeg-static -dct int -arithmetic -outfile testoutari.
add_test(cjpeg-static-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testoutari.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
add_test(jpegtran-static-toari jpegtran-static -arithmetic -outfile testouta.jpg ${CMAKE_SOURCE_DIR}/testimages/testimgint.jpg)
add_test(jpegtran-static-toari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_ARI} -DFILE=testouta.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake)
add_test(cjpeg-static-prog-ari cjpeg-static -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg ${CMAKE_SOURCE_DIR}/testimages/testorig.ppm)
add_test(cjpeg-static-prog-ari-cmp ${CMAKE_COMMAND} -DMD5=${MD5_JPEG_PROG_ARI} -DFILE=testoutpa.jpg -P ${CMAKE_SOURCE_DIR}/cmakescripts/md5cmp.cmake )
endif()
if(WITH_ARITH_DEC)
add_test(djpeg-static-ari djpeg-static -dct int -fast -ppm -outfile testoutari.ppm ${CMAKE_SOURCE_DIR}/testimages/testimgari.jpg)

View File

@@ -192,6 +192,7 @@ MD5_BMP_256 = 4980185e3776e89bd931736e1cddeee6
MD5_JPEG_ARI = e986fb0a637a8d833d96e8a6d6d84ea1
MD5_PPM_ARI = 72b59a99bcf1de24c5b27d151bde2437
MD5_JPEG_PROG = 1c4afddc05c0a43489ee54438a482d92
MD5_JPEG_PROG_ARI = 0a8f1c8f66e113c3cf635df0a475a617
MD5_JPEG_CROP = b4197f377e621c4e9b1d20471432610d
test: testclean all
@@ -273,6 +274,8 @@ if WITH_ARITH_ENC
md5/md5cmp $(MD5_JPEG_ARI) testoutari.jpg
./jpegtran -arithmetic -outfile testouta.jpg $(srcdir)/testimages/testimgint.jpg
md5/md5cmp $(MD5_JPEG_ARI) testouta.jpg
./cjpeg -dct int -progressive -arithmetic -sample 1x1 -outfile testoutpa.jpg $(srcdir)/testimages/testorig.ppm
md5/md5cmp $(MD5_JPEG_PROG_ARI) testoutpa.jpg
endif
if WITH_ARITH_DEC
./djpeg -dct int -fast -ppm -outfile testoutari.ppm $(srcdir)/testimages/testimgari.jpg

View File

@@ -239,26 +239,32 @@ emit_dac (j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
dc_in_use[compptr->dc_tbl_no] = 1;
ac_in_use[compptr->ac_tbl_no] = 1;
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0)
dc_in_use[compptr->dc_tbl_no] = 1;
/* AC needs no table when not present */
if (cinfo->Se)
ac_in_use[compptr->ac_tbl_no] = 1;
}
length = 0;
for (i = 0; i < NUM_ARITH_TBLS; i++)
length += dc_in_use[i] + ac_in_use[i];
emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2);
for (i = 0; i < NUM_ARITH_TBLS; i++) {
if (dc_in_use[i]) {
emit_byte(cinfo, i);
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
}
if (ac_in_use[i]) {
emit_byte(cinfo, i + 0x10);
emit_byte(cinfo, cinfo->arith_ac_K[i]);
if (length) {
emit_marker(cinfo, M_DAC);
emit_2bytes(cinfo, length*2 + 2);
for (i = 0; i < NUM_ARITH_TBLS; i++) {
if (dc_in_use[i]) {
emit_byte(cinfo, i);
emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
}
if (ac_in_use[i]) {
emit_byte(cinfo, i + 0x10);
emit_byte(cinfo, cinfo->arith_ac_K[i]);
}
}
}
#endif /* C_ARITH_CODING_SUPPORTED */
@@ -324,22 +330,16 @@ emit_sos (j_compress_ptr cinfo)
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
emit_byte(cinfo, compptr->component_id);
td = compptr->dc_tbl_no;
ta = compptr->ac_tbl_no;
if (cinfo->progressive_mode) {
/* Progressive mode: only DC or only AC tables are used in one scan;
* furthermore, Huffman coding of DC refinement uses no table at all.
* We emit 0 for unused field(s); this is recommended by the P&M text
* but does not seem to be specified in the standard.
*/
if (cinfo->Ss == 0) {
ta = 0; /* DC scan */
if (cinfo->Ah != 0 && !cinfo->arith_code)
td = 0; /* no DC table either */
} else {
td = 0; /* AC scan */
}
}
/* We emit 0 for unused field(s); this is recommended by the P&M text
* but does not seem to be specified in the standard.
*/
/* DC needs no table for refinement scan */
td = cinfo->Ss == 0 && cinfo->Ah == 0 ? compptr->dc_tbl_no : 0;
/* AC needs no table when not present */
ta = cinfo->Se ? compptr->ac_tbl_no : 0;
emit_byte(cinfo, (td << 4) + ta);
}
@@ -573,19 +573,12 @@ write_scan_header (j_compress_ptr cinfo)
*/
for (i = 0; i < cinfo->comps_in_scan; i++) {
compptr = cinfo->cur_comp_info[i];
if (cinfo->progressive_mode) {
/* Progressive mode: only DC or only AC tables are used in one scan */
if (cinfo->Ss == 0) {
if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
} else {
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
} else {
/* Sequential mode: need both DC and AC tables */
/* DC needs no table for refinement scan */
if (cinfo->Ss == 0 && cinfo->Ah == 0)
emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
/* AC needs no table when not present */
if (cinfo->Se)
emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
}
}
}