1
0
mirror of https://github.com/libjpeg-turbo/libjpeg-turbo.git synced 2026-10-23 11:48:53 +03:00

PNG image I/O support

Note that this changes the behavior of tj3GetICCProfile() in the
following ways:

- It can now be called with a compression instance, thus allowing the
  caller to retrieve an ICC profile (or the size thereof) extracted from
  a PNG image by tj3LoadImage*().
- The ICC profile extracted from a JPEG image can now be retrieved
  multiple times.  If I recall, I didn't allow this in TurboJPEG 3.1
  because there were already two buffer copies, one in
  jpeg_read_icc_profile() and another in the JNI wrapper.  That is no
  longer relevant, since the TurboJPEG Java API is now a separate
  project.

These changes should be backward-compatible.  Applications that treat
tj3GetICCProfile() as a mailbox rather than a newsstand will still work.
The changes were necessary in order to:

- allow decompression programs to both extract the ICC profile from a
  JPEG image and embed it into a PNG output image, and
- allow compression programs to retrieve the ICC profile size from a PNG
  input image (which is important when computing the worst-case JPEG
  destination buffer size.)

Closes #645
This commit is contained in:
DRC
2026-03-06 15:03:34 -05:00
parent 31dff48862
commit 54bd58cc30
76 changed files with 19446 additions and 627 deletions

View File

@@ -725,6 +725,10 @@ if(ENABLE_SHARED)
add_subdirectory(sharedlib)
endif()
if(WITH_TURBOJPEG OR WITH_TOOLS)
add_subdirectory(src/spng)
endif()
if(ENABLE_STATIC)
add_library(jpeg-static STATIC ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS}
${SIMD_OBJS})
@@ -737,8 +741,11 @@ if(WITH_TURBOJPEG)
set(TURBOJPEG_SOURCES ${JPEG_SOURCES} ${SIMD_TARGET_OBJECTS} ${SIMD_OBJS}
src/turbojpeg.c src/transupp.c src/jdatadst-tj.c src/jdatasrc-tj.c
src/rdbmp.c
src/wrapper/rdpng-8.c src/wrapper/rdpng-12.c src/wrapper/rdpng-16.c
$<TARGET_OBJECTS:spng-static>
src/wrapper/rdppm-8.c src/wrapper/rdppm-12.c src/wrapper/rdppm-16.c
src/wrbmp.c
src/wrapper/wrpng-8.c src/wrapper/wrpng-12.c src/wrapper/wrpng-16.c
src/wrapper/wrppm-8.c src/wrapper/wrppm-12.c src/wrapper/wrppm-16.c)
if(ENABLE_SHARED)
set(TJMAPFILE ${CMAKE_CURRENT_SOURCE_DIR}/src/turbojpeg-mapfile)
@@ -749,8 +756,11 @@ if(WITH_TURBOJPEG)
${CMAKE_BINARY_DIR}/win/turbojpeg.rc)
endif()
add_library(turbojpeg SHARED ${TURBOJPEG_SOURCES})
if(UNIX)
target_link_libraries(turbojpeg m)
endif()
set_property(TARGET turbojpeg PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
"-DBMP_SUPPORTED -DPNG_SUPPORTED -DSPNG_STATIC -DPPM_SUPPORTED")
if(WIN32)
set_target_properties(turbojpeg PROPERTIES DEFINE_SYMBOL DLLDEFINE)
endif()
@@ -800,8 +810,11 @@ if(WITH_TURBOJPEG)
if(ENABLE_STATIC)
add_library(turbojpeg-static STATIC ${TURBOJPEG_SOURCES})
if(UNIX)
target_link_libraries(turbojpeg-static m)
endif()
set_property(TARGET turbojpeg-static PROPERTY COMPILE_FLAGS
"-DBMP_SUPPORTED -DPPM_SUPPORTED")
"-DBMP_SUPPORTED -DPNG_SUPPORTED -DSPNG_STATIC -DPPM_SUPPORTED")
if(NOT MSVC_LIKE)
set_target_properties(turbojpeg-static PROPERTIES OUTPUT_NAME turbojpeg)
endif()
@@ -827,28 +840,38 @@ if(WITH_TOOLS)
set(USE_SETMODE "-DUSE_SETMODE")
endif()
set(CDJPEG_COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPNG_SUPPORTED -DSPNG_STATIC -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
endif()
if(ENABLE_STATIC)
if(WITH_TOOLS)
add_executable(cjpeg-static src/cjpeg.c src/cdjpeg.c src/rdbmp.c
src/rdgif.c
src/wrapper/rdpng-8.c src/wrapper/rdpng-12.c src/wrapper/rdpng-16.c
$<TARGET_OBJECTS:spng-static>
src/wrapper/rdppm-8.c src/wrapper/rdppm-12.c src/wrapper/rdppm-16.c
src/rdswitch.c src/rdtarga.c)
set_property(TARGET cjpeg-static PROPERTY COMPILE_FLAGS
${CDJPEG_COMPILE_FLAGS})
target_link_libraries(cjpeg-static jpeg-static)
if(UNIX)
target_link_libraries(cjpeg-static m)
endif()
add_executable(djpeg-static src/djpeg.c src/cdjpeg.c
src/wrapper/rdcolmap-8.c src/wrapper/rdcolmap-12.c
src/rdswitch.c src/wrbmp.c
src/wrapper/wrgif-8.c src/wrapper/wrgif-12.c
src/wrapper/wrpng-8.c src/wrapper/wrpng-12.c src/wrapper/wrpng-16.c
$<TARGET_OBJECTS:spng-static>
src/wrapper/wrppm-8.c src/wrapper/wrppm-12.c src/wrapper/wrppm-16.c
src/wrtarga.c)
set_property(TARGET djpeg-static PROPERTY COMPILE_FLAGS
${CDJPEG_COMPILE_FLAGS})
target_link_libraries(djpeg-static jpeg-static)
if(UNIX)
target_link_libraries(djpeg-static m)
endif()
add_executable(jpegtran-static src/jpegtran.c src/cdjpeg.c src/rdswitch.c
src/transupp.c)
@@ -1128,26 +1151,32 @@ foreach(libtype ${TEST_LIBTYPES})
if(sample_bits EQUAL 12)
set(tjbench tjbench12)
set(testout testout12${suffix})
set(SRCIMG ${TESTIMAGES}/monkey16.png)
set(ext png)
set(EXT PNG)
set(MD5_PPM_GRAY_TILE 2f799249148b1a9d0e61fa4408f6c397)
set(MD5_PPM_420_8x8_TILE b25684e1af37be504ee3fd137757353f)
set(MD5_PPM_420_16x16_TILE 2c1af444a63d19167eb3f4c1fa7f1b67)
set(MD5_PPM_420_32x32_TILE cce091fe18688f39bc0b5ba29238e1e2)
set(MD5_PPM_420_64x64_TILE f770ec8f710a014606dee662bc88606d)
set(MD5_PPM_420_128x128_TILE a841bc82e9eda34cbdefe53f808b339c)
set(MD5_PPM_420M_8x8_TILE 9de845a8d805affb9ae3a7b2712eaa46)
set(MD5_PPM_420M_TILE 455d273be0e229b9c8aabb16481bce5b)
set(MD5_PPM_422_8x8_TILE 5e9f784a98a7eae2789ea1458ed43748)
set(MD5_PPM_422_16x16_TILE c8df65a792d371a30c8fb7352f320314)
set(MD5_PPM_422_32x32_TILE b523b630237e3305a5c4d353ff4ee19b)
set(MD5_PPM_422_64x64_TILE eb30bdd20337079745b039e24e613bfd)
set(MD5_PPM_422_128x128_TILE 7997458635973b004da46863e2da55ea)
set(MD5_PPM_422M_8x8_TILE f8443fffd32cce7681dd36010ce43c07)
set(MD5_PPM_422M_TILE a0d45368343a63ca2c8ee87cc4ef9ded)
set(MD5_PPM_444_TILE 2f571a032e4dbc8ef40f75219d336b0b)
set(MD5_PNG_GRAY_TILE bcaa76c54892f5e44c0f6112db6a0a35)
set(MD5_PNG_420_8x8_TILE 23d18a28cdb99ebd6482ec439a325145)
set(MD5_PNG_420_16x16_TILE 8ac83919cd9bc66747b1bc41ab86dc65)
set(MD5_PNG_420_32x32_TILE 312365e8a26db21c020f34db06f1f6a5)
set(MD5_PNG_420_64x64_TILE 7b9cc3b86accadb2016d8bdfaace5deb)
set(MD5_PNG_420_128x128_TILE 168aea5291e0f3fa6d7f8cb790df5275)
set(MD5_PNG_420M_8x8_TILE 453dea7a488f97a5119c4379502a6f73)
set(MD5_PNG_420M_TILE 1fe9aaf032d0829f803fbd783018c691)
set(MD5_PNG_422_8x8_TILE 4b432543b64aae148fd1584fea4b398c)
set(MD5_PNG_422_16x16_TILE b05b6e084b70d19576fb078e65d3615d)
set(MD5_PNG_422_32x32_TILE b57cb2c7c3420cd81d64f6458bb73597)
set(MD5_PNG_422_64x64_TILE 767e833babb90da4eddab195a3ca4cd6)
set(MD5_PNG_422_128x128_TILE b0fd65ffe4fb7db8c59e66b10c42ee59)
set(MD5_PNG_422M_8x8_TILE 53ac3022fa03281fe8957a8bc04f1bf7)
set(MD5_PNG_422M_TILE 4f5a2c19a64cf01fadff9feae2715905)
set(MD5_PNG_444_TILE 6fd835c21df272c8739d81b9d294cf0b)
else()
set(tjbench tjbench)
set(testout testout${suffix})
set(SRCIMG ${TESTIMAGES}/testorig.ppm)
set(ext ppm)
set(EXT PPM)
set(MD5_PPM_GRAY_TILE 2c3b567086e6ca0c5e6d34ad8d6f6fe8)
set(MD5_PPM_420_8x8_TILE efca1bdf0226df01777137778cf986ec)
@@ -1171,9 +1200,9 @@ foreach(libtype ${TEST_LIBTYPES})
# larger image buffer
add_test(NAME ${tjbench}-${libtype}-tile-cp
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${TESTIMAGES}/testorig.ppm ${testout}_tile.ppm)
${SRCIMG} ${testout}_tile.${ext})
add_test(NAME ${tjbench}-${libtype}-tile
COMMAND tjbench${suffix} ${testout}_tile.ppm 95
COMMAND tjbench${suffix} ${testout}_tile.${ext} 95
-precision ${sample_bits} -rgb -quiet -tile -benchtime 0.01
-warmup 0)
set_tests_properties(${tjbench}-${libtype}-tile
@@ -1181,16 +1210,16 @@ foreach(libtype ${TEST_LIBTYPES})
foreach(tile 8 16 32 64 128)
add_test(NAME ${tjbench}-${libtype}-tile-gray-${tile}x${tile}-cmp
COMMAND md5cmp ${MD5_PPM_GRAY_TILE}
${testout}_tile_GRAY_Q95_${tile}x${tile}.ppm)
COMMAND md5cmp ${MD5_${EXT}_GRAY_TILE}
${testout}_tile_GRAY_Q95_${tile}x${tile}.${ext})
foreach(subsamp 420 422)
add_test(NAME ${tjbench}-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
COMMAND md5cmp ${MD5_PPM_${subsamp}_${tile}x${tile}_TILE}
${testout}_tile_${subsamp}_Q95_${tile}x${tile}.ppm)
COMMAND md5cmp ${MD5_${EXT}_${subsamp}_${tile}x${tile}_TILE}
${testout}_tile_${subsamp}_Q95_${tile}x${tile}.${ext})
endforeach()
add_test(NAME ${tjbench}-${libtype}-tile-444-${tile}x${tile}-cmp
COMMAND md5cmp ${MD5_PPM_444_TILE}
${testout}_tile_444_Q95_${tile}x${tile}.ppm)
COMMAND md5cmp ${MD5_${EXT}_444_TILE}
${testout}_tile_444_Q95_${tile}x${tile}.${ext})
foreach(subsamp gray 420 422 444)
set_tests_properties(
${tjbench}-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp
@@ -1200,25 +1229,25 @@ foreach(libtype ${TEST_LIBTYPES})
add_test(NAME ${tjbench}-${libtype}-tilem-cp
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${TESTIMAGES}/testorig.ppm ${testout}_tilem.ppm)
${SRCIMG} ${testout}_tilem.${ext})
add_test(NAME ${tjbench}-${libtype}-tilem
COMMAND tjbench${suffix} ${testout}_tilem.ppm 95
COMMAND tjbench${suffix} ${testout}_tilem.${ext} 95
-precision ${sample_bits} -rgb -fastupsample -quiet -tile
-benchtime 0.01 -warmup 0)
set_tests_properties(${tjbench}-${libtype}-tilem
PROPERTIES DEPENDS ${tjbench}-${libtype}-tilem-cp)
add_test(NAME ${tjbench}-${libtype}-tile-420m-8x8-cmp
COMMAND md5cmp ${MD5_PPM_420M_8x8_TILE}
${testout}_tilem_420_Q95_8x8.ppm)
COMMAND md5cmp ${MD5_${EXT}_420M_8x8_TILE}
${testout}_tilem_420_Q95_8x8.${ext})
add_test(NAME ${tjbench}-${libtype}-tile-422m-8x8-cmp
COMMAND md5cmp ${MD5_PPM_422M_8x8_TILE}
${testout}_tilem_422_Q95_8x8.ppm)
COMMAND md5cmp ${MD5_${EXT}_422M_8x8_TILE}
${testout}_tilem_422_Q95_8x8.${ext})
foreach(tile 16 32 64 128)
foreach(subsamp 420 422)
add_test(NAME ${tjbench}-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp
COMMAND md5cmp ${MD5_PPM_${subsamp}M_TILE}
${testout}_tilem_${subsamp}_Q95_${tile}x${tile}.ppm)
COMMAND md5cmp ${MD5_${EXT}_${subsamp}M_TILE}
${testout}_tilem_${subsamp}_Q95_${tile}x${tile}.${ext})
endforeach()
endforeach()
foreach(tile 8 16 32 64 128)
@@ -1261,19 +1290,18 @@ foreach(libtype ${TEST_LIBTYPES})
endif()
endmacro()
set(MD5_JPEG_LOSSLESS fe99437df4e9976fe5e841969242b208)
set(MD5_PPM_LOSSLESS 01d9642a2b8723fefebbe9cb074ccd02)
set(MD5_JPEG_LOSSLESS fdf975c44ddcbc86f144eb58f2417c97)
set(MD5_PNG_LOSSLESS 97c2093c9398224108056c1d16170f56)
# 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})
testout16_lossless.jpg ${TESTIMAGES}/monkey16.png ${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)
"-fast;-scale;1/8;-dct;float;-dither;none;-nosmooth;-onepass;-png"
testout16_lossless.png testout16_lossless.jpg
${MD5_PNG_LOSSLESS} cjpeg16-${libtype}-lossless)
foreach(sample_bits 8 12)
@@ -1282,73 +1310,79 @@ foreach(libtype ${TEST_LIBTYPES})
set(djpeg djpeg12)
set(jpegtran jpegtran12)
set(testout testout12${suffix})
set(SRCIMG ${TESTIMAGES}/monkey16.png)
set(ext png)
set(EXT PNG)
set(JPEGIMG ${TESTIMAGES}/monkey12.jpg)
set(TESTORIG testorig12.jpg)
set(MD5_JPEG_RGB_ISLOW 9d7369207c520d37f2c1cbfcb82b2964)
set(MD5_JPEG_RGB_ISLOW2 e619791332a99813bdca9f56fd60f9f9)
set(MD5_PPM_RGB_ISLOW f3301d2219783b8b3d942b7239fa50c0)
set(MD5_JPEG_422_IFAST_OPT 7322e3bd2f127f7de4b40d4480ce60e4)
set(MD5_PPM_422_IFAST 79807fa552899e66a04708f533e16950)
set(MD5_JPEG_440_ISLOW e25c1912e38367be505a89c410c1c2d2)
set(MD5_PPM_440_ISLOW e7d2e26288870cfcb30f3114ad01e380)
set(MD5_PPM_422M_IFAST 07737bfe8a7c1c87aaa393a0098d16b0)
set(MD5_JPEG_420_IFAST_Q100_PROG 9447cef4803d9b0f74bcf333cc710a29)
set(MD5_PPM_420_Q100_IFAST 1b3730122709f53d007255e8dfd3305e)
set(MD5_PPM_420M_Q100_IFAST 980a1a3c5bf9510022869d30b7d26566)
set(MD5_JPEG_GRAY_ISLOW 235c90707b16e2e069f37c888b2636d9)
set(MD5_PPM_GRAY_ISLOW 7213c10af507ad467da5578ca5ee1fca)
set(MD5_PPM_GRAY_ISLOW_RGB e96ee81c30a6ed422d466338bd3de65d)
set(MD5_JPEG_420S_IFAST_OPT 7af8e60be4d9c227ec63ac9b6630855e)
set(MD5_JPEG_RGB_ISLOW 412da084cd06bece1822dc7b92f01e1a)
set(MD5_JPEG_RGB_ISLOW2 47d05e783674661f1c2c749e230d98b7)
set(MD5_PNG_RGB_ISLOW 21954dadfb85fcafe684f022f0f04cbe)
set(MD5_JPEG_422_IFAST_OPT fd9d6d81531e33661de10495a0069001)
set(MD5_PNG_422_IFAST 2e7e0bc9454bc4d3e4034b1d4708737f)
set(MD5_JPEG_440_ISLOW 3f8c31d8fef17c4ad92e5603116211c9)
set(MD5_PNG_440_ISLOW 5772777a70f83276b237fd15f062da93)
set(MD5_PNG_422M_IFAST 5b08090a77d6b6c5f27d8d6488b41c90)
set(MD5_JPEG_420_IFAST_Q100_PROG dafebba3616229772fcb157cc90efbc1)
set(MD5_PNG_420_Q100_IFAST 0f87bac3bd89f5cbb8d39153969e0863)
set(MD5_PNG_420M_Q100_IFAST d7fad5dd405ab7af58950a63de37eb90)
set(MD5_JPEG_GRAY_ISLOW 4bd46c0943f1ba911437700b0a98bd56)
set(MD5_PNG_GRAY_ISLOW 2d9179b5e54cd50f32b7bce4d1ab8f21)
set(MD5_PNG_GRAY_ISLOW_RGB aea0063a3991b3148b1e339ef42dcfdc)
set(MD5_JPEG_420S_IFAST_OPT 2b7de3331421c2e41cf6cd9b5ddcf8e0)
set(MD5_JPEG_3x2_FLOAT_PROG_SSE a8c17daf77b457725ec929e215b603f8)
set(MD5_PPM_3x2_FLOAT_SSE 42876ab9e5c2f76a87d08db5fbd57956)
set(MD5_JPEG_3x2_FLOAT_PROG_SSE 2fe2ef00578fd4d5f7c105e37090780c)
set(MD5_PNG_3x2_FLOAT_SSE d6ed57702c4178e14a70d04fdcaee813)
set(MD5_JPEG_3x2_FLOAT_PROG_NO_FP_CONTRACT
${MD5_JPEG_3x2_FLOAT_PROG_SSE})
set(MD5_PPM_3x2_FLOAT_NO_FP_CONTRACT ${MD5_PPM_3x2_FLOAT_SSE})
set(MD5_PNG_3x2_FLOAT_NO_FP_CONTRACT ${MD5_PNG_3x2_FLOAT_SSE})
set(MD5_JPEG_3x2_FLOAT_PROG_FP_CONTRACT ${MD5_JPEG_3x2_FLOAT_PROG_SSE})
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
set(MD5_PPM_3x2_FLOAT_FP_CONTRACT 2da9de6ae869e88b8372de815d366b03)
set(MD5_PNG_3x2_FLOAT_FP_CONTRACT ${MD5_PNG_3x2_FLOAT_SSE})
else()
set(MD5_PPM_3x2_FLOAT_FP_CONTRACT ${MD5_PPM_3x2_FLOAT_SSE})
set(MD5_PNG_3x2_FLOAT_FP_CONTRACT f7910f3bc725a8ed072a74368a87350a)
endif()
set(MD5_JPEG_3x2_FLOAT_PROG_387 bc6dbbefac2872f6b9d6c4a0ae60c3c0)
set(MD5_PPM_3x2_FLOAT_387 bcc5723c61560463ac60f772e742d092)
set(MD5_JPEG_3x2_FLOAT_PROG_MSVC e27840755870fa849872e58aa0cd1400)
set(MD5_PPM_3x2_FLOAT_MSVC 6c2880b83bb1aa41dfe330e7a9768690)
set(MD5_JPEG_3x2_FLOAT_PROG_387 5d203a595f448cf19ce86c9bb2c52dfe)
set(MD5_PNG_3x2_FLOAT_387 c7c7ed9912f3138db1c6df74b09045f3)
set(MD5_JPEG_3x2_FLOAT_PROG_MSVC af7f873ea14136271cc21ddbc4bee46c)
set(MD5_PNG_3x2_FLOAT_MSVC fb14952c43ff3131c2049bb9324f0958)
set(MD5_JPEG_3x2_IFAST_PROG 1396cc2b7185cfe943d408c9d305339e)
set(MD5_PPM_3x2_IFAST 3975985ef6eeb0a2cdc58daa651ccc00)
set(MD5_PPM_420M_ISLOW_2_1 4ca6be2a6f326ff9eaab63e70a8259c0)
set(MD5_PPM_420M_ISLOW_15_8 12aa9f9534c1b3d7ba047322226365eb)
set(MD5_PPM_420M_ISLOW_13_8 f7e22817c7b25e1393e4ec101e9d4e96)
set(MD5_PPM_420M_ISLOW_11_8 800a16f9f4dc9b293197bfe11be10a82)
set(MD5_PPM_420M_ISLOW_9_8 06b7a92a9bc69f4dc36ec40f1937d55c)
set(MD5_PPM_420M_ISLOW_7_8 3ec444a14a4ab4eab88ffc49c48eca43)
set(MD5_PPM_420M_ISLOW_3_4 3e726b7ea872445b19437d1c1d4f0d93)
set(MD5_PPM_420M_ISLOW_5_8 a8a771abdc94301d20ffac119b2caccd)
set(MD5_PPM_420M_ISLOW_1_2 b419124dd5568b085787234866102866)
set(MD5_PPM_420M_ISLOW_3_8 343d19015531b7bbe746124127244fa8)
set(MD5_PPM_420M_ISLOW_1_4 35fd59d866e44659edfa3c18db2a3edb)
set(MD5_PPM_420M_ISLOW_1_8 ccaed48ac0aedefda5d4abe4013f4ad7)
set(MD5_JPEG_LOSSLESS 8473501f5bb7c826524472c858bf4fcd)
set(MD5_PPM_LOSSLESS 1da3fb2620e5a4e258e0fcb891bc67e8)
set(MD5_PPM_420_ISLOW_SKIP15_31 86664cd9dc956536409e44e244d20a97)
set(MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71
452a21656115a163029cfba5c04fa76a)
set(MD5_PPM_444_ISLOW_SKIP1_6 ef63901f71ef7a75cd78253fc0914f84)
set(MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13
15b173fb5872d9575572fbcc1b05956f)
set(MD5_JPEG_CROP cdb35ff4b4519392690ea040c56ea99c)
set(MD5_JPEG_3x2_IFAST_PROG eb1ba1cb5656025dc2ba13d81bcd5a2d)
set(MD5_PNG_3x2_IFAST 53d4b5128bcf1f6d2ee68d468a7c0ffe)
set(MD5_PNG_420M_ISLOW_2_1 bddff0d7f1d52af8fc3cea32697bade8)
set(MD5_PNG_420M_ISLOW_15_8 24bfcb8a44a98a11ed6d106871fe9b54)
set(MD5_PNG_420M_ISLOW_13_8 c1a7a3fe779eead62a282a313bd004c0)
set(MD5_PNG_420M_ISLOW_11_8 47c66c258b3e491267356f620d03ccf1)
set(MD5_PNG_420M_ISLOW_9_8 8b0ba0208093344b0bbd7aaaedad0eec)
set(MD5_PNG_420M_ISLOW_7_8 09549d957b05cf38d81ec3789d49579b)
set(MD5_PNG_420M_ISLOW_3_4 d5a6771349297d45066da112fc037f66)
set(MD5_PNG_420M_ISLOW_5_8 8346e9737cee0293bbfcf4c6adc24517)
set(MD5_PNG_420M_ISLOW_1_2 84fa0e1b325bff68cb750d9e527b8af0)
set(MD5_PNG_420M_ISLOW_3_8 55e8d9dba2f72994988b460226b14941)
set(MD5_PNG_420M_ISLOW_1_4 b426dc84306466a9d4dc5126c627dd22)
set(MD5_PNG_420M_ISLOW_1_8 53c1b7097ec94a3084396b977a46e1cf)
set(MD5_JPEG_LOSSLESS dacb841a16cc2e1140042d989bf6457e)
set(MD5_PNG_LOSSLESS 55e3dea5fe4d501a21f85c1ce76d732b)
set(MD5_PNG_420_ISLOW_SKIP15_31 65f4a5856b846af1b028590e329ab8e5)
set(MD5_PNG_420_ISLOW_PROG_CROP62x62_71_71
7c5214f1f3e02e294405dcfe174e9f7d)
set(MD5_PNG_444_ISLOW_SKIP1_6 c54ec6e326a294d1dfb74f1b2e4f506a)
set(MD5_PNG_444_ISLOW_PROG_CROP98x98_13_13
c5253e945abceee9de077c4d726c1b99)
set(MD5_JPEG_CROP b816363e572435067ec23bfa390761b4)
set(MD5_JPEG_EXAMPLE_COMPRESS 5e502da0c3c0f957a58c536f31e973dc)
set(MD5_PPM_EXAMPLE_DECOMPRESS 70194fdcb73370ee7ba0db868d0c6fc8)
set(MD5_PPM_EXAMPLE_DECOMPRESS 49aac0119b87c4deb70e9a7daf151253)
else()
set(cjpeg cjpeg)
set(djpeg djpeg)
set(jpegtran jpegtran)
set(testout testout${suffix})
set(SRCIMG ${TESTIMAGES}/testorig.ppm)
set(ext ppm)
set(EXT PPM)
set(JPEGIMG ${TESTIMAGES}/testorig.jpg)
set(TESTORIG testorig.jpg)
set(MD5_JPEG_RGB_ISLOW 1d44a406f61da743b5fd31c0a9abdca3)
set(MD5_JPEG_RGB_ISLOW2 b811e5ad807beb9384e51ef6a47f715d)
set(MD5_PPM_RGB_ISLOW 00a257f5393fef8821f2b88ac7421291)
@@ -1430,14 +1464,14 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: null SAMP: fullsize FDCT: islow ENT: huff
add_bittest(${cjpeg} rgb-islow "-rgb;-dct;int;-icc;${TESTIMAGES}/test1.icc"
${testout}_rgb_islow.jpg ${TESTIMAGES}/testorig.ppm
${testout}_rgb_islow.jpg ${SRCIMG}
${MD5_JPEG_RGB_ISLOW})
# CC: null SAMP: fullsize IDCT: islow ENT: huff
add_bittest(${djpeg} rgb-islow
"-dct;int;-ppm;-icc;${testout}_rgb_islow.icc"
${testout}_rgb_islow.ppm ${testout}_rgb_islow.jpg
${MD5_PPM_RGB_ISLOW} ${cjpeg}-${libtype}-rgb-islow)
"-dct;int;-${ext};-icc;${testout}_rgb_islow.icc"
${testout}_rgb_islow.${ext} ${testout}_rgb_islow.jpg
${MD5_${EXT}_RGB_ISLOW} ${cjpeg}-${libtype}-rgb-islow)
add_test(NAME ${djpeg}-${libtype}-rgb-islow-icc-cmp
COMMAND md5cmp b06a39d730129122e85c1363ed1bbc9e ${testout}_rgb_islow.icc)
@@ -1462,28 +1496,28 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize/h2v1 FDCT: ifast ENT: 2-pass huff
add_bittest(${cjpeg} 422-ifast-opt "-sample;2x1;-dct;fast;-opt"
${testout}_422_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm
${testout}_422_ifast_opt.jpg ${SRCIMG}
${MD5_JPEG_422_IFAST_OPT})
# CC: YCC->RGB SAMP: fullsize/h2v1 fancy IDCT: ifast ENT: huff
add_bittest(${djpeg} 422-ifast "-dct;fast"
${testout}_422_ifast.ppm ${testout}_422_ifast_opt.jpg
${MD5_PPM_422_IFAST} ${cjpeg}-${libtype}-422-ifast-opt)
add_bittest(${djpeg} 422-ifast "-dct;fast;-${ext}"
${testout}_422_ifast.${ext} ${testout}_422_ifast_opt.jpg
${MD5_${EXT}_422_IFAST} ${cjpeg}-${libtype}-422-ifast-opt)
# CC: RGB->YCC SAMP: fullsize/h1v2 FDCT: islow ENT: huff
add_bittest(${cjpeg} 440-islow "-sample;1x2;-dct;int"
${testout}_440_islow.jpg ${TESTIMAGES}/testorig.ppm
${testout}_440_islow.jpg ${SRCIMG}
${MD5_JPEG_440_ISLOW})
# CC: YCC->RGB SAMP: fullsize/h1v2 fancy IDCT: islow ENT: huff
add_bittest(${djpeg} 440-islow "-dct;int"
${testout}_440_islow.ppm ${testout}_440_islow.jpg
${MD5_PPM_440_ISLOW} ${cjpeg}-${libtype}-440-islow)
add_bittest(${djpeg} 440-islow "-dct;int;-${ext}"
${testout}_440_islow.${ext} ${testout}_440_islow.jpg
${MD5_${EXT}_440_ISLOW} ${cjpeg}-${libtype}-440-islow)
# CC: YCC->RGB SAMP: h2v1 merged IDCT: ifast ENT: huff
add_bittest(${djpeg} 422m-ifast "-dct;fast;-nosmooth"
${testout}_422m_ifast.ppm ${testout}_422_ifast_opt.jpg
${MD5_PPM_422M_IFAST} ${cjpeg}-${libtype}-422-ifast-opt)
add_bittest(${djpeg} 422m-ifast "-dct;fast;-nosmooth;-${ext}"
${testout}_422m_ifast.${ext} ${testout}_422_ifast_opt.jpg
${MD5_${EXT}_422M_IFAST} ${cjpeg}-${libtype}-422-ifast-opt)
if(sample_bits EQUAL 8)
# CC: YCC->RGB565 SAMP: h2v1 merged IDCT: ifast ENT: huff
@@ -1501,33 +1535,33 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize/h2v2 FDCT: ifast ENT: prog huff
add_bittest(${cjpeg} 420-q100-ifast-prog
"-sample;2x2;-quality;100;-dct;fast;-scans;${TESTIMAGES}/test.scan"
${testout}_420_q100_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm
${testout}_420_q100_ifast_prog.jpg ${SRCIMG}
${MD5_JPEG_420_IFAST_Q100_PROG})
# CC: YCC->RGB SAMP: fullsize/h2v2 fancy IDCT: ifast ENT: prog huff
add_bittest(${djpeg} 420-q100-ifast-prog "-dct;fast"
${testout}_420_q100_ifast.ppm ${testout}_420_q100_ifast_prog.jpg
${MD5_PPM_420_Q100_IFAST} ${cjpeg}-${libtype}-420-q100-ifast-prog)
add_bittest(${djpeg} 420-q100-ifast-prog "-dct;fast;-${ext}"
${testout}_420_q100_ifast.${ext} ${testout}_420_q100_ifast_prog.jpg
${MD5_${EXT}_420_Q100_IFAST} ${cjpeg}-${libtype}-420-q100-ifast-prog)
# CC: YCC->RGB SAMP: h2v2 merged IDCT: ifast ENT: prog huff
add_bittest(${djpeg} 420m-q100-ifast-prog "-dct;fast;-nosmooth"
${testout}_420m_q100_ifast.ppm ${testout}_420_q100_ifast_prog.jpg
${MD5_PPM_420M_Q100_IFAST} ${cjpeg}-${libtype}-420-q100-ifast-prog)
add_bittest(${djpeg} 420m-q100-ifast-prog "-dct;fast;-nosmooth;-${ext}"
${testout}_420m_q100_ifast.${ext} ${testout}_420_q100_ifast_prog.jpg
${MD5_${EXT}_420M_Q100_IFAST} ${cjpeg}-${libtype}-420-q100-ifast-prog)
# CC: RGB->Gray SAMP: fullsize FDCT: islow ENT: huff
add_bittest(${cjpeg} gray-islow "-gray;-dct;int"
${testout}_gray_islow.jpg ${TESTIMAGES}/testorig.ppm
add_bittest(${cjpeg} gray-islow "-gray;-dct;int;-noicc"
${testout}_gray_islow.jpg ${SRCIMG}
${MD5_JPEG_GRAY_ISLOW})
# CC: Gray->Gray SAMP: fullsize IDCT: islow ENT: huff
add_bittest(${djpeg} gray-islow "-dct;int"
${testout}_gray_islow.ppm ${testout}_gray_islow.jpg
${MD5_PPM_GRAY_ISLOW} ${cjpeg}-${libtype}-gray-islow)
add_bittest(${djpeg} gray-islow "-dct;int;-${ext}"
${testout}_gray_islow.${ext} ${testout}_gray_islow.jpg
${MD5_${EXT}_GRAY_ISLOW} ${cjpeg}-${libtype}-gray-islow)
# CC: Gray->RGB SAMP: fullsize IDCT: islow ENT: huff
add_bittest(${djpeg} gray-islow-rgb "-dct;int;-rgb"
${testout}_gray_islow_rgb.ppm ${testout}_gray_islow.jpg
${MD5_PPM_GRAY_ISLOW_RGB} ${cjpeg}-${libtype}-gray-islow)
add_bittest(${djpeg} gray-islow-rgb "-dct;int;-rgb;-${ext}"
${testout}_gray_islow_rgb.${ext} ${testout}_gray_islow.jpg
${MD5_${EXT}_GRAY_ISLOW_RGB} ${cjpeg}-${libtype}-gray-islow)
if(sample_bits EQUAL 8)
# CC: Gray->RGB565 SAMP: fullsize IDCT: islow ENT: huff
@@ -1544,36 +1578,36 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: RGB->YCC SAMP: fullsize smooth/h2v2 smooth FDCT: islow
# ENT: 2-pass huff
add_bittest(${cjpeg} 420s-ifast-opt "-sample;2x2;-smooth;1;-dct;int;-opt"
${testout}_420s_ifast_opt.jpg ${TESTIMAGES}/testorig.ppm
${testout}_420s_ifast_opt.jpg ${SRCIMG}
${MD5_JPEG_420S_IFAST_OPT})
if(FLOATTEST${sample_bits})
# CC: RGB->YCC SAMP: fullsize/int FDCT: float ENT: prog huff
add_bittest(${cjpeg} 3x2-float-prog "-sample;3x2;-dct;float;-prog"
${testout}_3x2_float_prog.jpg ${TESTIMAGES}/testorig.ppm
${testout}_3x2_float_prog.jpg ${SRCIMG}
${MD5_JPEG_3x2_FLOAT_PROG_${FLOATTEST${sample_bits}_UC}})
# CC: YCC->RGB SAMP: fullsize/int IDCT: float ENT: prog huff
add_bittest(${djpeg} 3x2-float-prog "-dct;float"
${testout}_3x2_float.ppm ${testout}_3x2_float_prog.jpg
${MD5_PPM_3x2_FLOAT_${FLOATTEST${sample_bits}_UC}}
add_bittest(${djpeg} 3x2-float-prog "-dct;float;-${ext}"
${testout}_3x2_float.${ext} ${testout}_3x2_float_prog.jpg
${MD5_${EXT}_3x2_FLOAT_${FLOATTEST${sample_bits}_UC}}
${cjpeg}-${libtype}-3x2-float-prog)
endif()
# CC: RGB->YCC SAMP: fullsize/int FDCT: ifast ENT: prog huff
add_bittest(${cjpeg} 3x2-ifast-prog "-sample;3x2;-dct;fast;-prog"
${testout}_3x2_ifast_prog.jpg ${TESTIMAGES}/testorig.ppm
${testout}_3x2_ifast_prog.jpg ${SRCIMG}
${MD5_JPEG_3x2_IFAST_PROG})
# CC: YCC->RGB SAMP: fullsize/int IDCT: ifast ENT: prog huff
add_bittest(${djpeg} 3x2-ifast-prog "-dct;fast"
${testout}_3x2_ifast.ppm ${testout}_3x2_ifast_prog.jpg
${MD5_PPM_3x2_IFAST} ${cjpeg}-${libtype}-3x2-ifast-prog)
add_bittest(${djpeg} 3x2-ifast-prog "-dct;fast;-${ext}"
${testout}_3x2_ifast.${ext} ${testout}_3x2_ifast_prog.jpg
${MD5_${EXT}_3x2_IFAST} ${cjpeg}-${libtype}-3x2-ifast-prog)
if(WITH_ARITH_ENC AND sample_bits EQUAL 8)
# CC: YCC->RGB SAMP: fullsize/h2v2 FDCT: islow ENT: arith
add_bittest(${cjpeg} 420-islow-ari "-dct;int;-arithmetic"
${testout}_420_islow_ari.jpg ${TESTIMAGES}/testorig.ppm
${testout}_420_islow_ari.jpg ${SRCIMG}
${MD5_JPEG_420_ISLOW_ARI})
add_bittest(${jpegtran} 420-islow-ari "-arithmetic"
@@ -1583,15 +1617,15 @@ foreach(libtype ${TEST_LIBTYPES})
# CC: YCC->RGB SAMP: fullsize FDCT: islow ENT: prog arith
add_bittest(${cjpeg} 444-islow-progari
"-sample;1x1;-dct;int;-prog;-arithmetic"
${testout}_444_islow_progari.jpg ${TESTIMAGES}/testorig.ppm
${testout}_444_islow_progari.jpg ${SRCIMG}
${MD5_JPEG_444_ISLOW_PROGARI})
endif()
if(WITH_ARITH_DEC AND sample_bits EQUAL 8)
# CC: RGB->YCC SAMP: h2v2 merged IDCT: ifast ENT: arith
add_bittest(${djpeg} 420m-ifast-ari "-fast;-skip;1,20;-ppm"
${testout}_420m_ifast_ari.ppm ${TESTIMAGES}/testimgari.jpg
${MD5_PPM_420M_IFAST_ARI})
add_bittest(${djpeg} 420m-ifast-ari "-fast;-skip;1,20;-${ext}"
${testout}_420m_ifast_ari.${ext} ${TESTIMAGES}/testimgari.jpg
${MD5_${EXT}_420M_IFAST_ARI})
add_bittest(${jpegtran} 420-islow ""
${testout}_420_islow.jpg ${TESTIMAGES}/testimgari.jpg
@@ -1620,36 +1654,36 @@ foreach(libtype ${TEST_LIBTYPES})
foreach(scale 2_1 15_8 13_8 11_8 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8)
string(REGEX REPLACE "_" "/" scalearg ${scale})
add_bittest(${djpeg} 420m-islow-${scale}
"-dct;int;-scale;${scalearg};-nosmooth;-ppm"
${testout}_420m_islow_${scale}.ppm ${TESTIMAGES}/${TESTORIG}
${MD5_PPM_420M_ISLOW_${scale}})
"-dct;int;-scale;${scalearg};-nosmooth;-${ext}"
${testout}_420m_islow_${scale}.${ext} ${JPEGIMG}
${MD5_${EXT}_420M_ISLOW_${scale}})
endforeach()
if(sample_bits EQUAL 8)
# CC: YCC->RGB (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
add_bittest(${djpeg} 420-islow-256 "-dct;int;-colors;256;-bmp"
${testout}_420_islow_256.bmp ${TESTIMAGES}/${TESTORIG}
${testout}_420_islow_256.bmp ${JPEGIMG}
${MD5_BMP_420_ISLOW_256})
# CC: YCC->RGB565 SAMP: h2v2 fancy IDCT: islow ENT: huff
add_bittest(${djpeg} 420-islow-565 "-dct;int;-rgb565;-dither;none;-bmp"
${testout}_420_islow_565.bmp ${TESTIMAGES}/${TESTORIG}
${testout}_420_islow_565.bmp ${JPEGIMG}
${MD5_BMP_420_ISLOW_565})
# CC: YCC->RGB565 (dithered) SAMP: h2v2 fancy IDCT: islow ENT: huff
add_bittest(${djpeg} 420-islow-565D "-dct;int;-rgb565;-bmp"
${testout}_420_islow_565D.bmp ${TESTIMAGES}/${TESTORIG}
${testout}_420_islow_565D.bmp ${JPEGIMG}
${MD5_BMP_420_ISLOW_565D})
# CC: YCC->RGB565 SAMP: h2v2 merged IDCT: islow ENT: huff
add_bittest(${djpeg} 420m-islow-565
"-dct;int;-nosmooth;-rgb565;-dither;none;-bmp"
${testout}_420m_islow_565.bmp ${TESTIMAGES}/${TESTORIG}
${testout}_420m_islow_565.bmp ${JPEGIMG}
${MD5_BMP_420M_ISLOW_565})
# CC: YCC->RGB565 (dithered) SAMP: h2v2 merged IDCT: islow ENT: huff
add_bittest(${djpeg} 420m-islow-565D "-dct;int;-nosmooth;-rgb565;-bmp"
${testout}_420m_islow_565D.bmp ${TESTIMAGES}/${TESTORIG}
${testout}_420m_islow_565D.bmp ${JPEGIMG}
${MD5_BMP_420M_ISLOW_565D})
endif()
@@ -1657,68 +1691,70 @@ foreach(libtype ${TEST_LIBTYPES})
# effect)
add_bittest(${cjpeg} lossless
"-lossless;4;-restart;1;-quality;1;-grayscale;-optimize;-dct;float;-smooth;100;-baseline;-qslots;1,0,0;-sample;1x2,3x4,2x1"
${testout}_lossless.jpg ${TESTIMAGES}/testorig.ppm
${testout}_lossless.jpg ${SRCIMG}
${MD5_JPEG_LOSSLESS})
add_bittest(${djpeg} lossless
"-fast;-scale;1/8;-dct;float;-dither;none;-nosmooth;-onepass"
${testout}_lossless.ppm ${testout}_lossless.jpg
${MD5_PPM_LOSSLESS} ${cjpeg}-${libtype}-lossless)
"-fast;-scale;1/8;-dct;float;-dither;none;-nosmooth;-onepass;-${ext}"
${testout}_lossless.${ext} ${testout}_lossless.jpg
${MD5_${EXT}_LOSSLESS} ${cjpeg}-${libtype}-lossless)
# Partial decode tests. These tests are designed to cover all of the
# possible code paths in jpeg_skip_scanlines().
# Context rows: Yes Intra-iMCU row: Yes iMCU row prefetch: No
# ENT: huff
add_bittest(${djpeg} 420-islow-skip15_31 "-dct;int;-skip;15,31;-ppm"
${testout}_420_islow_skip15,31.ppm ${TESTIMAGES}/${TESTORIG}
${MD5_PPM_420_ISLOW_SKIP15_31})
add_bittest(${djpeg} 420-islow-skip15_31 "-dct;int;-skip;15,31;-${ext}"
${testout}_420_islow_skip15,31.${ext} ${JPEGIMG}
${MD5_${EXT}_420_ISLOW_SKIP15_31})
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: Yes
# ENT: arith
if(WITH_ARITH_DEC AND sample_bits EQUAL 8)
add_bittest(${djpeg} 420-islow-ari-skip16_139
"-dct;int;-skip;16,139;-ppm"
${testout}_420_islow_ari_skip16,139.ppm ${TESTIMAGES}/testimgari.jpg
${MD5_PPM_420_ISLOW_ARI_SKIP16_139})
"-dct;int;-skip;16,139;-${ext}"
${testout}_420_islow_ari_skip16,139.${ext} ${TESTIMAGES}/testimgari.jpg
${MD5_${EXT}_420_ISLOW_ARI_SKIP16_139})
endif()
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No
# ENT: prog huff
add_test(NAME ${cjpeg}-${libtype}-420-islow-prog
COMMAND cjpeg${suffix} -dct int -prog -precision ${sample_bits}
-outfile ${testout}_420_islow_prog.jpg ${TESTIMAGES}/testorig.ppm)
-outfile ${testout}_420_islow_prog.jpg ${SRCIMG})
add_bittest(${djpeg} 420-islow-prog-crop62x62_71_71
"-dct;int;-crop;62x62+71+71;-ppm"
${testout}_420_islow_prog_crop62x62,71,71.ppm
${testout}_420_islow_prog.jpg ${MD5_PPM_420_ISLOW_PROG_CROP62x62_71_71}
"-dct;int;-crop;62x62+71+71;-${ext}"
${testout}_420_islow_prog_crop62x62,71,71.${ext}
${testout}_420_islow_prog.jpg
${MD5_${EXT}_420_ISLOW_PROG_CROP62x62_71_71}
${cjpeg}-${libtype}-420-islow-prog)
# Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No
# ENT: arith
if(WITH_ARITH_DEC AND sample_bits EQUAL 8)
add_bittest(${djpeg} 420-islow-ari-crop53x53_4_4
"-dct;int;-crop;53x53+4+4;-ppm"
${testout}_420_islow_ari_crop53x53,4,4.ppm ${TESTIMAGES}/testimgari.jpg
${MD5_PPM_420_ISLOW_ARI_CROP53x53_4_4})
"-dct;int;-crop;53x53+4+4;-${ext}"
${testout}_420_islow_ari_crop53x53,4,4.${ext}
${TESTIMAGES}/testimgari.jpg
${MD5_${EXT}_420_ISLOW_ARI_CROP53x53_4_4})
endif()
# Context rows: No Intra-iMCU row: Yes ENT: huff
add_test(NAME ${cjpeg}-${libtype}-444-islow
COMMAND cjpeg${suffix} -dct int -sample 1x1 -precision ${sample_bits}
-outfile ${testout}_444_islow.jpg ${TESTIMAGES}/testorig.ppm)
add_bittest(${djpeg} 444-islow-skip1_6 "-dct;int;-skip;1,6;-ppm"
${testout}_444_islow_skip1,6.ppm ${testout}_444_islow.jpg
${MD5_PPM_444_ISLOW_SKIP1_6} ${cjpeg}-${libtype}-444-islow)
-outfile ${testout}_444_islow.jpg ${SRCIMG})
add_bittest(${djpeg} 444-islow-skip1_6 "-dct;int;-skip;1,6;-${ext}"
${testout}_444_islow_skip1,6.${ext} ${testout}_444_islow.jpg
${MD5_${EXT}_444_ISLOW_SKIP1_6} ${cjpeg}-${libtype}-444-islow)
# Context rows: No Intra-iMCU row: No ENT: prog huff
add_test(NAME ${cjpeg}-${libtype}-444-islow-prog
COMMAND cjpeg${suffix} -dct int -prog -precision ${sample_bits}
-sample 1x1 -outfile ${testout}_444_islow_prog.jpg
${TESTIMAGES}/testorig.ppm)
-sample 1x1 -outfile ${testout}_444_islow_prog.jpg ${SRCIMG})
add_bittest(${djpeg} 444-islow-prog-crop98x98_13_13
"-dct;int;-crop;98x98+13+13;-ppm"
${testout}_444_islow_prog_crop98x98,13,13.ppm
${testout}_444_islow_prog.jpg ${MD5_PPM_444_ISLOW_PROG_CROP98x98_13_13}
"-dct;int;-crop;98x98+13+13;-${ext}"
${testout}_444_islow_prog_crop98x98,13,13.${ext}
${testout}_444_islow_prog.jpg
${MD5_${EXT}_444_ISLOW_PROG_CROP98x98_13_13}
${cjpeg}-${libtype}-444-islow-prog)
# Context rows: No Intra-iMCU row: No ENT: arith
@@ -1726,19 +1762,19 @@ foreach(libtype ${TEST_LIBTYPES})
add_test(NAME ${cjpeg}-${libtype}-444-islow-ari
COMMAND cjpeg${suffix} -dct int -arithmetic -sample 1x1
-precision ${sample_bits} -outfile ${testout}_444_islow_ari.jpg
${TESTIMAGES}/testorig.ppm)
${SRCIMG})
if(WITH_ARITH_DEC)
add_bittest(${djpeg} 444-islow-ari-crop37x37_0_0
"-dct;int;-crop;37x37+0+0;-ppm"
${testout}_444_islow_ari_crop37x37,0,0.ppm
${testout}_444_islow_ari.jpg ${MD5_PPM_444_ISLOW_ARI_CROP37x37_0_0}
"-dct;int;-crop;37x37+0+0;-${ext}"
${testout}_444_islow_ari_crop37x37,0,0.${ext}
${testout}_444_islow_ari.jpg
${MD5_${EXT}_444_ISLOW_ARI_CROP37x37_0_0}
${cjpeg}-${libtype}-444-islow-ari)
endif()
endif()
add_bittest(${jpegtran} crop "-crop;120x90+20+50;-transpose;-perfect"
${testout}_crop.jpg ${TESTIMAGES}/${TESTORIG}
${MD5_JPEG_CROP})
${testout}_crop.jpg ${JPEGIMG} ${MD5_JPEG_CROP})
unset(EXAMPLE_12BIT_ARG)
if(sample_bits EQUAL 12)
@@ -1755,7 +1791,7 @@ foreach(libtype ${TEST_LIBTYPES})
add_test(NAME example-${sample_bits}bit-${libtype}-decompress
COMMAND example${suffix} decompress ${EXAMPLE_12BIT_ARG}
${TESTIMAGES}/${TESTORIG} ${testout}-example.ppm)
${JPEGIMG} ${testout}-example.ppm)
add_test(NAME example-${sample_bits}bit-${libtype}-decompress-cmp
COMMAND md5cmp ${MD5_PPM_EXAMPLE_DECOMPRESS} ${testout}-example.ppm)
set_tests_properties(example-${sample_bits}bit-${libtype}-decompress-cmp

View File

@@ -106,6 +106,33 @@ in the libjpeg API by setting `cinfo->data_precision = 12` after calling
`jpeg_read_header()`, and in the TurboJPEG API by calling `tj3Decompress12()`
after calling `tj3DecompressHeader()`.
9. cjpeg, djpeg, `tj3LoadImage*()`, and `tj3SaveImage*()` now support
8-bit-per-channel and 16-bit-per-channel true color and grayscale PNG images.
- By default, cjpeg transfers the embedded ICC profile from a PNG input
image to the JPEG image, and djpeg transfers the embedded ICC profile from the
JPEG image to a PNG output image. A new option (`-noicc`) can be used to
disable that behavior.
- If called with a TurboJPEG compression instance, `tj3LoadImage*()`
extracts the embedded ICC profile from a PNG image and associates it with the
TurboJPEG instance if `TJPARAM_SAVEMARKERS` is set to 2 or 4.
- If called with a TurboJPEG decompression instance, `tj3SaveImage*()`
transfers the ICC profile that was previously extracted from the JPEG image to
a PNG image if `TJPARAM_SAVEMARKERS` is set to 2 or 4.
- The PNG writer upscales images with 2-7 and 9-15 bits of data
precision to, respectively, 8-bit-per-channel and 16-bit-per-channel PNG
images. The upscaling algorithm is reversible, so a lossless JPEG image with a
non-standard data precision can be losslessly converted to a PNG image and back
to a lossless JPEG image with the same data precision.
10. The TurboJPEG API has been improved in the following ways:
- `tj3GetICCProfile()` can now be called multiple times to retrieve the
ICC profile that was previously extracted from a JPEG image.
- `tj3GetICCProfile()` can now be used to retrieve the ICC profile
associated with a TurboJPEG compression instance (including an ICC profile
extracted from a PNG image by `tj3LoadImage*()`.)
3.1.4
=====

View File

@@ -8,18 +8,50 @@ libjpeg-turbo is covered by two compatible BSD-style open source licenses:
This license applies to the libjpeg API library and associated programs,
including any code inherited from libjpeg and any modifications to that
code. Note that the libjpeg-turbo SIMD source code bears the
[zlib License](https://opensource.org/licenses/Zlib), but in the context of
the overall libjpeg API library, the terms of the zlib License are subsumed
by the terms of the IJG License.
code.
- The Modified (3-clause) BSD License, which is listed below
This license applies to the TurboJPEG API library and associated programs, as
well as the build system. Note that the TurboJPEG API library wraps the
libjpeg API library, so in the context of the overall TurboJPEG API library,
both the terms of the IJG License and the terms of the Modified (3-clause)
BSD License apply.
This license applies to the TurboJPEG API library and associated programs,
[libspng](https://libspng.org) (which is used by cjpeg and djpeg), and the
build/test system.
* The TurboJPEG API library wraps the libjpeg API library, so in the context
of the overall TurboJPEG API library, both the terms of the IJG License and
the terms of the Modified (3-clause) BSD License apply.
* cjpeg and djpeg use libspng, so in the context of those programs, both the
terms of the IJG License and the terms of the Modified (3-clause) BSD
License apply.
Component Licenses
==================
Some of libjpeg-turbo's modules and internal dependencies are covered by less
restrictive licenses, but in the context of libjpeg-turbo as a whole, the terms
of the less restrictive licenses are subsumed by either the IJG License or the
Modified BSD License. (In other words, the terms of the less restrictive
licenses are satisfied if the terms of the IJG and Modified BSD Licenses are
satisfied.)
- The libjpeg-turbo SIMD source code is covered by the
[zlib License](https://spdx.org/licenses/Zlib.html), which is subsumed by the
IJG License in the context of the libjpeg API library.
- Some of the libspng source code is covered by the
[PNG Reference Library License v2](https://spdx.org/licenses/libpng-2.0.html),
which is subsumed by the IJG License in the context of the cjpeg and djpeg
programs and the TurboJPEG API library.
- Most of the libspng source code is covered by the
[Simplified (2-clause) BSD License](https://spdx.org/licenses/BSD-2-Clause.html),
which is subsumed by the Modified BSD License in the context of the cjpeg and
djpeg programs and the TurboJPEG API library.
- The miniz source code is covered by the
[Zero-Clause BSD License](https://spdx.org/licenses/0BSD.html), which is
subsumed by the Modified BSD License in the context of the cjpeg and djpeg
programs and the TurboJPEG API library.
Complying with the libjpeg-turbo Licenses
@@ -38,7 +70,6 @@ intended solely for clarification.
**Origin**
- Clause 1 of the IJG License
- Clause 1 of the Modified BSD License
- Clauses 1 and 3 of the zlib License
2. You must add your own copyright notice to the header of each source
file you modified, so others can tell that you modified that file. (If
@@ -47,7 +78,6 @@ intended solely for clarification.
**Origin**
- Clause 1 of the IJG License
- Clause 2 of the zlib License
3. You must include the IJG README file, and you must not alter any of the
copyright or license text in that file.
@@ -67,9 +97,9 @@ intended solely for clarification.
**Origin**
- Clause 2 of the IJG license
2. If your binary distribution includes or uses the TurboJPEG API, then
your product documentation must include the text of the Modified BSD
License (see below.)
2. If your binary distribution includes or uses the TurboJPEG API or
associated programs, cjpeg, or djpeg, then your product documentation
must include the text of the Modified BSD License (see below.)
**Origin**
- Clause 2 of the Modified BSD License
@@ -81,21 +111,20 @@ intended solely for clarification.
- IJG License
- Clause 3 of the Modified BSD License
4. The IJG and The libjpeg-turbo Project do not warrant libjpeg-turbo to be
free of defects, nor do we accept any liability for undesirable
consequences resulting from your use of the software.
4. The authors and distributors do not warrant libjpeg-turbo to be free of
defects, nor do we accept any liability for undesirable consequences
resulting from your use of the software.
**Origin**
- IJG License
- Modified BSD License
- zlib License
The Modified (3-clause) BSD License
===================================
Copyright (C) 2009-2026 D. R. Commander<br>
Copyright (C) 2015 Viktor Szathmáry
Copyright (C) 2018-2023 Randy <randy408@protonmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -120,16 +149,3 @@ 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.
Why Two Licenses?
=================
The zlib License could have been used instead of the Modified (3-clause) BSD
License, and since the IJG License effectively subsumes the distribution
conditions of the zlib License, this would have effectively placed
libjpeg-turbo binary distributions under the IJG License. However, the IJG
License specifically refers to the Independent JPEG Group and does not extend
attribution and endorsement protections to other entities. Thus, it was
desirable to choose a license that granted us the same protections for new code
that were granted to the IJG for code derived from their software.

View File

@@ -4,7 +4,7 @@ endif()
foreach(FILE 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 jutils.c rdppm.c wrppm.c)
jdsample.c jutils.c rdpng.c rdppm.c wrpng.c wrppm.c)
foreach(BITS 8 12 16)

View File

@@ -1,4 +1,4 @@
.TH CJPEG 1 "30 August 2024"
.TH CJPEG 1 "10 March 2026"
.SH NAME
cjpeg \- compress an image file to a JPEG file
.SH SYNOPSIS
@@ -15,9 +15,9 @@ cjpeg \- compress an image file to a JPEG file
.B cjpeg
compresses the named image file, or the standard input if no file is
named, and produces a JPEG/JFIF file on the standard output.
The currently supported input file formats are: PPM (PBMPLUS color
format), PGM (PBMPLUS grayscale format), BMP, GIF [legacy feature], and Targa
[legacy feature].
The currently supported input file formats are: PNG (true color and grayscale),
PPM (PBMPLUS color format), PGM (PBMPLUS grayscale format), BMP, GIF [legacy
feature], and Targa [legacy feature].
.SH OPTIONS
All switch names may be abbreviated; for example,
.B \-grayscale
@@ -263,7 +263,15 @@ behavior, whereas the integer methods should give the same results on all
machines.
.TP
.BI \-icc " file"
Embed ICC color management profile contained in the specified file.
Embed ICC color management profile contained in the specified file. If neither
this option nor
.B \-noicc
is specified and the input file is a PNG file with an embedded ICC color
management profile, then the profile will be transferred from the input file.
.TP
.BI \-noicc
Do not transfer the embedded ICC color management profile (if any) from a PNG
input file.
.TP
.BI \-restart " N"
Emit a JPEG restart marker every N MCU rows, or every N MCUs if "B" is attached

View File

@@ -1,4 +1,4 @@
.TH DJPEG 1 "3 Mar 2026"
.TH DJPEG 1 "10 March 2026"
.SH NAME
djpeg \- decompress a JPEG file to an image file
.SH SYNOPSIS
@@ -14,8 +14,8 @@ djpeg \- decompress a JPEG file to an image file
.LP
.B djpeg
decompresses the named JPEG file, or the standard input if no file is named,
and produces an image file on the standard output. PBMPLUS (PPM/PGM), BMP,
GIF, or Targa output format can be selected.
and produces an image file on the standard output. PNG, PBMPLUS (PPM/PGM),
BMP, GIF, or Targa output format can be selected.
.SH OPTIONS
All switch names may be abbreviated; for example,
.B \-grayscale
@@ -107,6 +107,17 @@ is specified, or if the JPEG file is grayscale; otherwise, 24-bit full-color
format is emitted. This format can only be used when decompressing
8-bit-per-sample JPEG images.
.TP
.B \-png
Select PNG output format. Grayscale format is emitted if the JPEG file is
grayscale or if
.B \-grayscale
is specified; otherwise true color format is emitted. 16-bit-per-channel
format is emitted if the output data precision is greater than 8 bits. If the
JPEG file contains an ICC color management profile, then it is automatically
transferred to the output image unless
.B \-noicc
is specified.
.TP
.B \-pnm
Select PBMPLUS (PPM/PGM) output format (this is the default format).
PGM is emitted if the JPEG file is grayscale or if
@@ -197,6 +208,10 @@ mode.
.BI \-icc " file"
Extract ICC color management profile to the specified file.
.TP
.BI \-noicc
Do not transfer the embedded ICC color management profile (if any) from the
JPEG file to a PNG output image.
.TP
.BI \-map " file"
Quantize to the colors used in the specified image file [legacy feature]. This
is useful for producing multiple files with identical color maps, or for
@@ -260,8 +275,8 @@ Decompress only a rectangular subregion of the image, starting at point X,Y
with width W and height H. If necessary, X will be shifted left to the nearest
iMCU boundary, and the width will be increased accordingly. Note that if
decompression scaling is being used, then X, Y, W, and H are relative to the
scaled image dimensions. Currently this option only works with the
PBMPLUS (PPM/PGM), GIF, and Targa output formats.
scaled image dimensions. Currently this option does not work with the BMP
output format.
.TP
.BI \-strict
Treat all warnings as fatal. This feature also demonstrates a method by which

View File

@@ -1,5 +1,5 @@
PROJECT_NAME = TurboJPEG
PROJECT_NUMBER = 3.1
PROJECT_NUMBER = 3.2
OUTPUT_DIRECTORY = ../doc/
HTML_OUTPUT = turbojpeg
USE_WINDOWS_ENCODING = NO

View File

@@ -122,10 +122,10 @@ with 2 to 16 bits of data precision per sample. To create a JPEG image with a
particular data precision, set cinfo->data_precision accordingly. Note that
9-bit and higher data precisions cause the sample size to be larger than a
char, which affects the surrounding application's image data. The sample
application djpeg can support 12-bit data precision only for PPM, PGM, and GIF
file formats. The sample applications cjpeg and djpeg can support 2-bit
through 7-bit and 9-bit through 16-bit data precision only for PPM and PGM file
formats.
application djpeg can support 12-bit data precision only for PNG, PPM, PGM, and
GIF file formats. The sample applications cjpeg and djpeg can support 2-bit
through 7-bit and 9-bit through 16-bit data precision only for PNG, PPM, and
PGM file formats.
Note that, when 12-bit data precision is enabled in lossy mode, the library
compresses in Huffman optimization mode by default, in order to generate valid

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>
@@ -336,7 +336,7 @@ Functions</h2></td></tr>
<tr class="memdesc:ga96d2c4b3432f9d88ad14758ae240b8d1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables. <br /></td></tr>
<tr class="separator:ga96d2c4b3432f9d88ad14758ae240b8d1"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ga63dc21a762b26aa217e8f48ac748bef7" id="r_ga63dc21a762b26aa217e8f48ac748bef7"><td class="memItemLeft" align="right" valign="top">DLLEXPORT int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7">tj3GetICCProfile</a> (<a class="el" href="group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763">tjhandle</a> handle, unsigned char **iccBuf, size_t *iccSize)</td></tr>
<tr class="memdesc:ga63dc21a762b26aa217e8f48ac748bef7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieve the ICC (International Color Consortium) color management profile (if any) that was previously extracted from a JPEG image. <br /></td></tr>
<tr class="memdesc:ga63dc21a762b26aa217e8f48ac748bef7"><td class="mdescLeft">&#160;</td><td class="mdescRight">Retrieve the ICC (International Color Consortium) color management profile (if any) that was previously extracted from a JPEG image or associated with a TurboJPEG compression instance. <br /></td></tr>
<tr class="separator:ga63dc21a762b26aa217e8f48ac748bef7"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:gaf9253e0c2e9f464142d389673da085fa" id="r_gaf9253e0c2e9f464142d389673da085fa"><td class="memItemLeft" align="right" valign="top">DLLEXPORT <a class="el" href="structtjscalingfactor.html">tjscalingfactor</a> *&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group___turbo_j_p_e_g.html#gaf9253e0c2e9f464142d389673da085fa">tj3GetScalingFactors</a> (int *numScalingFactors)</td></tr>
<tr class="memdesc:gaf9253e0c2e9f464142d389673da085fa"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a list of fractional scaling factors that the JPEG decompressor supports. <br /></td></tr>
@@ -872,10 +872,10 @@ scalingFactor)</code>. </p>
<tr><td class="fieldname"><a id="ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f" name="ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f"></a>TJPARAM_JPEGHEIGHT&#160;</td><td class="fielddoc"><p>JPEG height (in pixels) [decompression only, read-only]. </p>
</td></tr>
<tr><td class="fieldname"><a id="ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" name="ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8"></a>TJPARAM_PRECISION&#160;</td><td class="fielddoc"><p>Data precision (bits per sample) </p>
<p>The JPEG image uses (decompression) or will use (lossless compression) the specified number of bits per sample. This parameter also specifies the target data precision when loading a PBMPLUS file with <a class="el" href="group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001" title="Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory.">tj3LoadImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44" title="Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory.">tj3LoadImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69" title="Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory.">tj3LoadImage16()</a> and the source data precision when saving a PBMPLUS file with <a class="el" href="group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722" title="Save a packed-pixel image with 2 to 8 bits of data precision per sample from memory to disk.">tj3SaveImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90" title="Save a packed-pixel image with 9 to 12 bits of data precision per sample from memory to disk.">tj3SaveImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71" title="Save a packed-pixel image with 13 to 16 bits of data precision per sample from memory to disk.">tj3SaveImage16()</a>.</p>
<p>The JPEG image uses (decompression) or will use (lossless compression) the specified number of bits per sample. This parameter also specifies the target data precision when loading a PNG or PBMPLUS file with <a class="el" href="group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001" title="Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory.">tj3LoadImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44" title="Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory.">tj3LoadImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69" title="Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory.">tj3LoadImage16()</a> and the source data precision when saving a PNG or PBMPLUS file with <a class="el" href="group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722" title="Save a packed-pixel image with 2 to 8 bits of data precision per sample from memory to disk.">tj3SaveImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90" title="Save a packed-pixel image with 9 to 12 bits of data precision per sample from memory to disk.">tj3SaveImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71" title="Save a packed-pixel image with 13 to 16 bits of data precision per sample from memory to disk.">tj3SaveImage16()</a>.</p>
<p>The data precision is the number of bits in the maximum sample value, which may not be the same as the width of the data type used to store the sample.</p>
<p><b>Value</b></p><ul>
<li><code>8</code> or <code>12</code> for lossy JPEG images; <code>2</code> to <code>16</code> for lossless JPEG and PBMPLUS images</li>
<li><code>8</code> or <code>12</code> for lossy JPEG images; <code>2</code> to <code>16</code> for lossless JPEG, PNG, and PBMPLUS images</li>
</ul>
<p>12-bit JPEG data precision implies <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f0af9afc0b36443751f9ee82b760aa6" title="Huffman table optimization [lossy compression, lossless transformation].">TJPARAM_OPTIMIZE</a> unless <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1c756757384308145602c040524aebf7" title="Arithmetic entropy coding.">TJPARAM_ARITHMETIC</a> is set. </p>
</td></tr>
@@ -1035,7 +1035,7 @@ scalingFactor)</code>. </p>
<li>maximum number of pixels that the decompression, transform, and image loading functions will process <em>[default: <code>0</code> (no limit)]</em> </li>
</ul>
</td></tr>
<tr><td class="fieldname"><a id="ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" name="ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1"></a>TJPARAM_SAVEMARKERS&#160;</td><td class="fielddoc"><p>Marker copying behavior [decompression, lossless transformation]. </p>
<tr><td class="fieldname"><a id="ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" name="ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1"></a>TJPARAM_SAVEMARKERS&#160;</td><td class="fielddoc"><p>Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O]. </p>
<p><b>Value [lossless transformation]</b></p><ul>
<li><code>0</code> Do not copy any extra markers (including comments, JFIF thumbnails, Exif data, and ICC profile data) from the source image to the destination image.</li>
<li><code>1</code> Do not copy any extra markers, except comment (COM) markers, from the source image to the destination image.</li>
@@ -1043,8 +1043,12 @@ scalingFactor)</code>. </p>
<li><code>3</code> Copy all extra markers, except ICC profile data (APP2 markers), from the source image to the destination image.</li>
<li><code>4</code> Do not copy any extra markers, except ICC profile data (APP2 markers), from the source image to the destination image.</li>
</ul>
<p><a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> overrides this parameter for a particular transform. This parameter overrides any ICC profile that was previously associated with the TurboJPEG instance using <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.</p>
<p>When decompressing, <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a> extracts the ICC profile from a JPEG image if this parameter is set to <code>2</code> or <code>4</code>. <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> can then be used to retrieve the profile. </p>
<p><a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> overrides this parameter for a particular transform. This parameter overrides any ICC profile that was previously associated with the TurboJPEG instance using <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>, <a class="el" href="group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001" title="Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory.">tj3LoadImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44" title="Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory.">tj3LoadImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69" title="Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory.">tj3LoadImage16()</a>.</p>
<p>If this parameter is set to <code>2</code> or <code>4</code>:</p><ul>
<li>When decompressing, <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a> extracts the ICC profile from a JPEG image. <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> can then be used to retrieve the profile.</li>
<li>When loading a PNG image using a TurboJPEG compression instance, <a class="el" href="group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001" title="Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory.">tj3LoadImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44" title="Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory.">tj3LoadImage12()</a>, and <a class="el" href="group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69" title="Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory.">tj3LoadImage16()</a> extract the ICC profile from the PNG image and associate the profile with the TurboJPEG instance. <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> can then be used to retrieve the profile.</li>
<li>When saving a PNG image using a TurboJPEG decompression instance, <a class="el" href="group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722" title="Save a packed-pixel image with 2 to 8 bits of data precision per sample from memory to disk.">tj3SaveImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90" title="Save a packed-pixel image with 9 to 12 bits of data precision per sample from memory to disk.">tj3SaveImage12()</a>, and <a class="el" href="group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71" title="Save a packed-pixel image with 13 to 16 bits of data precision per sample from memory to disk.">tj3SaveImage16()</a> transfer the ICC profile that was previously extracted from a JPEG image to the PNG image. </li>
</ul>
</td></tr>
</table>
@@ -1300,7 +1304,7 @@ scalingFactor)</code>. </p>
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to a byte buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to a size_t variable that holds the size of the JPEG buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Otherwise, <code>*jpegSize</code> is ignored. If <code>*jpegBuf</code> points to a JPEG buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is also ignored. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
@@ -1385,7 +1389,7 @@ Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to a byte buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to a size_t variable that holds the size of the JPEG buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Otherwise, <code>*jpegSize</code> is ignored. If <code>*jpegBuf</code> points to a JPEG buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is also ignored. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
@@ -1470,7 +1474,7 @@ Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to a byte buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to a size_t variable that holds the size of the JPEG buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Otherwise, <code>*jpegSize</code> is ignored. If <code>*jpegBuf</code> points to a JPEG buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is also ignored. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
@@ -1548,7 +1552,7 @@ Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to a byte buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to a size_t variable that holds the size of the JPEG buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Otherwise, <code>*jpegSize</code> is ignored. If <code>*jpegBuf</code> points to a JPEG buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is also ignored. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
@@ -1626,7 +1630,7 @@ Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba
<tr><td class="paramname">jpegBuf</td><td>address of a pointer to a byte buffer that will receive the JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to accommodate the size of the JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>*jpegBuf</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> and adding the return value to the size of the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>.) This should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>*jpegBuf</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">jpegSize</td><td>pointer to a size_t variable that holds the size of the JPEG buffer. If <code>*jpegBuf</code> points to a pre-allocated buffer, then <code>*jpegSize</code> should be set to the size of the buffer. Otherwise, <code>*jpegSize</code> is ignored. If <code>*jpegBuf</code> points to a JPEG buffer that is being reused from a previous call to one of the JPEG compression functions, then <code>*jpegSize</code> is also ignored. Upon return, <code>*jpegSize</code> will contain the size of the JPEG image (in bytes.)</td></tr>
@@ -2038,7 +2042,7 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables. </p>
<p>If a JPEG image is passed to this function, then the <a class="el" href="group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82">parameters</a> that describe the JPEG image will be set when the function returns. If a JPEG image is passed to this function and <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>, then the ICC profile (if any) will be extracted from the JPEG image. (<a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> can then be used to retrieve the profile.)</p>
<p>If a JPEG image is passed to this function, then the <a class="el" href="group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82">parameters</a> that describe the JPEG image will be set when the function returns. If a JPEG image is passed to this function and <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>, then the ICC profile (if any) will be extracted from the JPEG image. (<a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> can then be used to retrieve the profile.)</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance that has been initialized for decompression</td></tr>
@@ -2512,11 +2516,13 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</table>
</div><div class="memdoc">
<p>Retrieve the ICC (International Color Consortium) color management profile (if any) that was previously extracted from a JPEG image. </p>
<dl class="section note"><dt>Note</dt><dd>To extract the ICC profile from a JPEG image, call <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a> with <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation].">TJPARAM_SAVEMARKERS</a> set to <code>2</code> or <code>4</code>. Once the ICC profile is retrieved, it must be re-extracted before it can be retrieved again.</dd></dl>
<p>Retrieve the ICC (International Color Consortium) color management profile (if any) that was previously extracted from a JPEG image or associated with a TurboJPEG compression instance. </p>
<dl class="section note"><dt>Note</dt><dd>To extract the ICC profile from a JPEG image, call <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a> with <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> set to <code>2</code> or <code>4</code>.</dd>
<dd>
To associate an ICC profile with a TurboJPEG compression instance, call <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a> or use <a class="el" href="group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001" title="Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory.">tj3LoadImage8()</a>, <a class="el" href="group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44" title="Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory.">tj3LoadImage12()</a>, or <a class="el" href="group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69" title="Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory.">tj3LoadImage16()</a> to load a PNG image with <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance that has been initialized for decompression</td></tr>
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">iccBuf</td><td>address of a pointer to a byte buffer. Upon return:<ul>
<li>If <code>iccBuf</code> is not NULL and there is an ICC profile to retrieve, then <code>*iccBuf</code> will point to a byte buffer containing the ICC profile. This buffer should be freed using <a class="el" href="group___turbo_j_p_e_g.html#gaddb84fb6c81769e9faa0f5a63b296606" title="Free a byte buffer previously allocated by TurboJPEG.">tj3Free()</a>.</li>
<li>If <code>iccBuf</code> is not NULL and there is no ICC profile to retrieve, then <code>*iccBuf</code> will be NULL.</li>
@@ -2682,10 +2688,11 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Load a packed-pixel image with 9 to 12 bits of data precision per sample from disk into memory. </p>
<dl class="section note"><dt>Note</dt><dd>If loading a PNG image using a TurboJPEG compression instance, the ICC profile (if any) embedded in the PNG image is extracted and associated with the TurboJPEG instance if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in PBMPLUS (PPM/PGM) format. The target data precision (from 9 to 12 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 12 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in true color PNG, grayscale PNG, or PBMPLUS (PPM/PGM) format. The target data precision (from 9 to 12 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 12 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PNG or PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">width</td><td>pointer to an integer variable that will receive the width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">align</td><td>row alignment (in samples) of the packed-pixel buffer to be returned (must be a power of 2.) Setting this parameter to n will cause all rows in the buffer to be padded to the nearest multiple of n samples (1 = unpadded.)</td></tr>
<tr><td class="paramname">height</td><td>pointer to an integer variable that will receive the height (in pixels) of the packed-pixel image</td></tr>
@@ -2754,10 +2761,11 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Load a packed-pixel image with 13 to 16 bits of data precision per sample from disk into memory. </p>
<dl class="section note"><dt>Note</dt><dd>If loading a PNG image using a TurboJPEG compression instance, the ICC profile (if any) embedded in the PNG image is extracted and associated with the TurboJPEG instance if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in PBMPLUS (PPM/PGM) format. The target data precision (from 13 to 16 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 16 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in true color PNG, grayscale PNG, or PBMPLUS (PPM/PGM) format. The target data precision (from 13 to 16 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 16 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PNG or PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">width</td><td>pointer to an integer variable that will receive the width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">align</td><td>row alignment (in samples) of the packed-pixel buffer to be returned (must be a power of 2.) Setting this parameter to n will cause all rows in the buffer to be padded to the nearest multiple of n samples (1 = unpadded.)</td></tr>
<tr><td class="paramname">height</td><td>pointer to an integer variable that will receive the height (in pixels) of the packed-pixel image</td></tr>
@@ -2826,10 +2834,11 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Load a packed-pixel image with 2 to 8 bits of data precision per sample from disk into memory. </p>
<dl class="section note"><dt>Note</dt><dd>If loading a PNG image using a TurboJPEG compression instance, the ICC profile (if any) embedded in the PNG image is extracted and associated with the TurboJPEG instance if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in Windows BMP or PBMPLUS (PPM/PGM) format. Windows BMP files require 8-bit-per-sample data precision. When loading a PBMPLUS file, the target data precision (from 2 to 8 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 8 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file containing a packed-pixel image in true color PNG, grayscale PNG, PBMPLUS (PPM/PGM), or Windows BMP format. Windows BMP files require 8-bit-per-sample data precision. When loading a PNG or PBMPLUS file, the target data precision (from 2 to 8 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 8 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range. If the data precision of the PNG or PBMPLUS file does not match the target data precision, then upconverting or downconverting will be performed.</td></tr>
<tr><td class="paramname">width</td><td>pointer to an integer variable that will receive the width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">align</td><td>row alignment (in samples) of the packed-pixel buffer to be returned (must be a power of 2.) Setting this parameter to n will cause all rows in the buffer to be padded to the nearest multiple of n samples (1 = unpadded.)</td></tr>
<tr><td class="paramname">height</td><td>pointer to an integer variable that will receive the height (in pixels) of the packed-pixel image</td></tr>
@@ -2904,15 +2913,16 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Save a packed-pixel image with 9 to 12 bits of data precision per sample from memory to disk. </p>
<dl class="section note"><dt>Note</dt><dd>If saving a PNG image using a TurboJPEG decompression instance, the ICC profile (if any) that was previously extracted from a JPEG image is transferred to the PNG image if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image, which will be stored in PBMPLUS (PPM/PGM) format. The source data precision (from 9 to 12 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 12 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image, which will be stored in PNG or PBMPLUS (PPM/PGM) format. The source data precision (from 9 to 12 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 12 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">buffer</td><td>pointer to a buffer containing a packed-pixel RGB, grayscale, or CMYK image to be saved</td></tr>
<tr><td class="paramname">width</td><td>width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pitch</td><td>samples per row in the packed-pixel image. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in samples) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
<tr><td class="paramname">height</td><td>height (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM format. Otherwise, the image will be stored in PPM format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM or grayscale PNG format. Otherwise, the image will be stored in PPM or true color PNG format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
</table>
</dd>
</dl>
@@ -2977,15 +2987,16 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Save a packed-pixel image with 13 to 16 bits of data precision per sample from memory to disk. </p>
<dl class="section note"><dt>Note</dt><dd>If saving a PNG image using a TurboJPEG decompression instance, the ICC profile (if any) that was previously extracted from a JPEG image is transferred to the PNG image if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image, which will be stored in PBMPLUS (PPM/PGM) format. The source data precision (from 13 to 16 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 16 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image, which will be stored in PNG or PBMPLUS (PPM/PGM) format. The source data precision (from 13 to 16 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 16 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">buffer</td><td>pointer to a buffer containing a packed-pixel RGB, grayscale, or CMYK image to be saved</td></tr>
<tr><td class="paramname">width</td><td>width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pitch</td><td>samples per row in the packed-pixel image. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in samples) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
<tr><td class="paramname">height</td><td>height (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM format. Otherwise, the image will be stored in PPM format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM or grayscale PNG format. Otherwise, the image will be stored in PPM or true color PNG format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
</table>
</dd>
</dl>
@@ -3050,15 +3061,16 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Save a packed-pixel image with 2 to 8 bits of data precision per sample from memory to disk. </p>
<dl class="section note"><dt>Note</dt><dd>If saving a PNG image using a TurboJPEG decompression instance, the ICC profile (if any) that was previously extracted from a JPEG image is transferred to the PNG image if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to <code>2</code> or <code>4</code>.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image. The image will be stored in Windows BMP or PBMPLUS (PPM/PGM) format, depending on the file extension. Windows BMP files require 8-bit-per-sample data precision. When saving a PBMPLUS file, the source data precision (from 2 to 8 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 8 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">filename</td><td>name of a file to which to save the packed-pixel image. The image will be stored in PNG, PBMPLUS (PPM/PGM), or Windows BMP format, depending on the file extension. Windows BMP files require 8-bit-per-sample data precision. When saving a PNG or PBMPLUS file, the source data precision (from 2 to 8 bits per sample) can be specified using <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> and defaults to 8 if <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8" title="Data precision (bits per sample)">TJPARAM_PRECISION</a> is unset or out of range.</td></tr>
<tr><td class="paramname">buffer</td><td>pointer to a buffer containing a packed-pixel RGB, grayscale, or CMYK image to be saved</td></tr>
<tr><td class="paramname">width</td><td>width (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pitch</td><td>samples per row in the packed-pixel image. Setting this parameter to 0 is the equivalent of setting it to <code>width * <a class="el" href="group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c" title="Pixel size (in samples) for a given pixel format.">tjPixelSize</a>[pixelFormat]</code>.</td></tr>
<tr><td class="paramname">height</td><td>height (in pixels) of the packed-pixel image</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in PGM or 8-bit-per-pixel (indexed color) BMP format. Otherwise, the image will be stored in PPM or 24-bit-per-pixel BMP format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
<tr><td class="paramname">pixelFormat</td><td>pixel format of the packed-pixel image (see <a class="el" href="group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a">Pixel formats</a>.) If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a">TJPF_GRAY</a>, then the image will be stored in grayscale PNG, PGM, or 8-bit-per-pixel (indexed color) BMP format. Otherwise, the image will be stored in true color PNG, PPM, or 24-bit-per-pixel BMP format. If this parameter is set to <a class="el" href="group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b">TJPF_CMYK</a>, then the CMYK pixels will be converted to RGB using a quick &amp; dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)</td></tr>
</table>
</dd>
</dl>
@@ -3182,7 +3194,7 @@ It may be desirable to preserve as much of that signal as possible in the decomp
</div><div class="memdoc">
<p>Embed an ICC (International Color Consortium) color management profile in JPEG images generated by subsequent compression and lossless transformation operations. </p>
<dl class="section note"><dt>Note</dt><dd>Lossless transformation operations ignore this ICC profile unless <a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> is specified or <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation].">TJPARAM_SAVEMARKERS</a> is set to something other than <code>2</code> or <code>4</code>. Otherwise the ICC profile in the source image takes precedence, even if the source image has no ICC profile.</dd></dl>
<dl class="section note"><dt>Note</dt><dd>Lossless transformation operations ignore this ICC profile unless <a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> is specified or <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a> is set to something other than <code>2</code> or <code>4</code>. Otherwise the ICC profile in the source image takes precedence, even if the source image has no ICC profile.</dd></dl>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance that has been initialized for compression</td></tr>
@@ -3300,7 +3312,7 @@ It may be desirable to preserve as much of that signal as possible in the decomp
<tr><td class="paramname">dstBufs</td><td>pointer to an array of n byte buffers. <code>dstBufs[i]</code> will receive a JPEG image that has been transformed using the parameters in <code>transforms[i]</code>. TurboJPEG has the ability to reallocate the JPEG destination buffer to accommodate the size of the transformed JPEG image. Thus, you can choose to:<ol type="1">
<li>pre-allocate the JPEG destination buffer with an arbitrary size using <a class="el" href="group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57" title="Allocate a byte buffer for use with TurboJPEG.">tj3Alloc()</a> and let TurboJPEG grow the buffer as needed,</li>
<li>set <code>dstBufs[i]</code> to NULL to tell TurboJPEG to allocate the buffer for you, or</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga1c13482ad590fefe34f30a43ba110d60" title="The maximum size of the buffer (in bytes) required to hold a JPEG image transformed with the given tr...">tj3TransformBufSize()</a>. Under normal circumstances, this should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be. However, if the source image has a large amount of embedded Exif data, then the transformed JPEG image may be larger than the worst-case size. <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> cannot be used in that case unless the embedded data is discarded using <a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> or <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation].">TJPARAM_SAVEMARKERS</a>.)</li>
<li>pre-allocate the buffer to a "worst case" size determined by calling <a class="el" href="group___turbo_j_p_e_g.html#ga1c13482ad590fefe34f30a43ba110d60" title="The maximum size of the buffer (in bytes) required to hold a JPEG image transformed with the given tr...">tj3TransformBufSize()</a>. Under normal circumstances, this should ensure that the buffer never has to be re-allocated. (Setting <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> guarantees that it won't be. However, if the source image has a large amount of embedded Exif data, then the transformed JPEG image may be larger than the worst-case size. <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a> cannot be used in that case unless the embedded data is discarded using <a class="el" href="group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8" title="Do not copy any extra markers (including Exif and ICC profile data) from the source image to the dest...">TJXOPT_COPYNONE</a> or <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a>.)</li>
</ol>
Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b" title="JPEG destination buffer (re)allocation [compression, lossless transformation].">TJPARAM_NOREALLOC</a>, you should always check <code>dstBufs[i]</code> upon return from this function, as it may have changed.</td></tr>
<tr><td class="paramname">dstSizes</td><td>pointer to an array of n size_t variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If <code>dstBufs[i]</code> points to a pre-allocated buffer, then <code>dstSizes[i]</code> should be set to the size of the buffer. Otherwise, <code>dstSizes[i]</code> is ignored. Upon return, <code>dstSizes[i]</code> will contain the size of the transformed JPEG image (in bytes.)</td></tr>
@@ -3339,7 +3351,7 @@ Unless you have set <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba
</div><div class="memdoc">
<p>The maximum size of the buffer (in bytes) required to hold a JPEG image transformed with the given transform parameters and/or cropping region. </p>
<p>This function is a wrapper for <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> that takes into account cropping, transposition of the width and height (which affects the destination image dimensions and level of chrominance subsampling), grayscale conversion, and the ICC profile (if any) that was previously associated with the TurboJPEG instance (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>) or extracted from the source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a> and <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation].">TJPARAM_SAVEMARKERS</a>.) The JPEG header must be read (see <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a>) prior to calling this function.</p>
<p>This function is a wrapper for <a class="el" href="group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4" title="The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.">tj3JPEGBufSize()</a> that takes into account cropping, transposition of the width and height (which affects the destination image dimensions and level of chrominance subsampling), grayscale conversion, and the ICC profile (if any) that was previously associated with the TurboJPEG instance or extracted from the source image (see <a class="el" href="group___turbo_j_p_e_g.html#ga5852aa6e9ee3a457798a1741642dec40" title="Embed an ICC (International Color Consortium) color management profile in JPEG images generated by su...">tj3SetICCProfile()</a>, <a class="el" href="group___turbo_j_p_e_g.html#ga63dc21a762b26aa217e8f48ac748bef7" title="Retrieve the ICC (International Color Consortium) color management profile (if any) that was previous...">tj3GetICCProfile()</a>, and <a class="el" href="group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a259b376e3ea795834c5cdccd7a3fdeb1" title="Marker copying behavior [decompression, lossless transformation, packed-pixel image I/O].">TJPARAM_SAVEMARKERS</a>.) The JPEG header must be read (see <a class="el" href="group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1" title="Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quan...">tj3DecompressHeader()</a>) prior to calling this function.</p>
<dl class="params"><dt>Parameters</dt><dd>
<table class="params">
<tr><td class="paramname">handle</td><td>handle to a TurboJPEG instance that has been initialized for lossless transformation</td></tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -22,7 +22,7 @@
<tbody>
<tr id="projectrow">
<td id="projectalign">
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.1</span>
<div id="projectname">TurboJPEG<span id="projectnumber">&#160;3.2</span>
</div>
</td>
</tr>

View File

@@ -52,11 +52,11 @@ or
djpeg [switches] -outfile imagefile jpegfile
This syntax works on all systems, so it is useful for scripts.
The currently supported image file formats are: PPM (PBMPLUS color format),
PGM (PBMPLUS grayscale format), BMP, GIF [legacy feature], and Targa [legacy
feature]. cjpeg recognizes the input image format automatically, with the
exception of some Targa files. You have to tell djpeg which format to
generate.
The currently supported image file formats are: PNG (true color and grayscale),
PPM (PBMPLUS color format), PGM (PBMPLUS grayscale format), BMP, GIF [legacy
feature], and Targa [legacy feature]. cjpeg recognizes the input image format
automatically, with the exception of some Targa files. You have to tell djpeg
which format to generate.
JPEG files are in the defacto standard JFIF file format. There are other,
less widely used JPEG-based file formats, but we don't support them.
@@ -256,7 +256,13 @@ Switches for advanced users:
same results on all machines.
-icc FILE Embed ICC color management profile contained in the
specified file.
specified file. If neither this option nor -noicc is
specified and the input file is a PNG file with an
embedded ICC color management profile, then the profile
will be transferred from the input file.
-noicc Do not transfer the embedded ICC color management
profile (if any) from a PNG input file.
-restart N Emit a JPEG restart marker every N MCU rows, or every N
MCUs if "B" is attached to the number.
@@ -405,6 +411,15 @@ The basic command line switches for djpeg are:
emitted. This format can only be used when
decompressing 8-bit-per-sample JPEG images.
-png Select PNG output format. Grayscale format is emitted
if the JPEG file is grayscale or if -grayscale is
specified; otherwise true color format is emitted.
16-bit-per-channel format is emitted if the output data
precision is greater than 8 bits. If the JPEG file
contains an ICC color management profile, then it is
automatically transferred to the output image unless
-noicc is specified.
-pnm Select PBMPLUS (PPM/PGM) output format (this is the
default format). PGM is emitted if the JPEG file is
grayscale or if -grayscale is specified; otherwise PPM
@@ -498,6 +513,10 @@ Switches for advanced users:
-icc FILE Extract ICC color management profile to the specified
file.
-noicc Do not transfer the embedded ICC color management
profile (if any) from the JPEG file to a PNG output
image.
-map FILE Quantize to the colors used in the specified image file
[legacy feature]. This is useful for producing
multiple files with identical color maps, or for
@@ -553,8 +572,8 @@ Switches for advanced users:
boundary, and the width will be increased accordingly.
Note that if decompression scaling is being used, then
X, Y, W, and H are relative to the scaled image
dimensions. Currently this option only works with the
PBMPLUS (PPM/PGM), GIF, and Targa output formats.
dimensions. Currently this option does not work with
the BMP output format.
-strict Treat all warnings as fatal. This feature also
demonstrates a method by which applications can guard

View File

@@ -39,12 +39,13 @@ final class TJBench {
private TJBench() {}
private static boolean stopOnWarning, bottomUp, noRealloc = true,
fastUpsample, fastDCT, optimize, progressive, arithmetic, lossless;
fastUpsample, fastDCT, optimize, progressive, arithmetic, lossless, noICC;
private static int precision = 8, maxScans = 0, restartIntervalBlocks = 0,
restartIntervalRows = 0, maxMemory = 0, maxPixels = 0;
private static String ext = null;
private static boolean compOnly, decompOnly, write = true, doTile, doYUV;
private static int sampleSize, pf = TJ.PF_BGR, quiet = 0, yuvAlign = 1;
private static NativeLong iccSize;
static final String[] PIXFORMATSTR = {
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY", "", "", "", "",
@@ -189,12 +190,12 @@ final class TJBench {
TJ.set(handle, TJ.PARAM_SCANLIMIT, maxScans);
TJ.set(handle, TJ.PARAM_MAXMEMORY, maxMemory);
TJ.set(handle, TJ.PARAM_MAXPIXELS, maxPixels);
if (noICC)
TJ.set(handle, TJ.PARAM_SAVEMARKERS, 0);
if (isCropped(cr)) {
try {
TJ.decompressHeader(handle, jpegBufs[0].pointer, jpegSizes[0].value);
} catch (TJ.Exception e) { handleTJException(e); }
}
try {
TJ.decompressHeader(handle, jpegBufs[0].pointer, jpegSizes[0].value);
} catch (TJ.Exception e) { handleTJException(e); }
TJ.setScalingFactor(handle, sf);
TJ.setCroppingRegion(handle, cr);
if (isCropped(cr)) {
@@ -389,6 +390,8 @@ final class TJBench {
(new TJ.NativeLongReference().toArray(ntilesw * ntilesh));
for (int i = 0; i < ntilesw * ntilesh; i++) {
NativeLong jpegBufSize = TJ.jpegBufSize(tilew, tileh, subsamp);
jpegBufSize.setValue(jpegBufSize.longValue() +
iccSize.longValue());
jpegBufs[i].pointer = TJ.alloc(jpegBufSize);
jpegBufSizes[i].value = jpegBufSize;
}
@@ -841,7 +844,7 @@ final class TJBench {
String className = new TJBench().getClass().getName();
System.out.println("\nUSAGE: java " + className);
System.out.println(" <Inputimage (BMP|PPM|PGM)> <Quality or PSV> [options]\n");
System.out.println(" <Inputimage (PNG|PPM||PGM|BMP)> <Quality or PSV> [options]\n");
System.out.println(" java " + className);
System.out.println(" <Inputimage (JPG)> [options]");
@@ -867,6 +870,9 @@ final class TJBench {
System.out.println(" JPEG compression, and lossless transformation [default = no limit]");
System.out.println("-maxpixels N");
System.out.println(" Input image size limit (in pixels) [default = no limit]");
System.out.println("-noicc");
System.out.println(" Do not transfer the embedded ICC profile (if any) from PNG input images or");
System.out.println(" to PNG output images.");
System.out.println("-nowrite");
System.out.println(" Do not write reference or output images (improves consistency of benchmark");
System.out.println(" results)");
@@ -876,6 +882,8 @@ final class TJBench {
System.out.println("-pixelformat cmyk");
System.out.println(" Indirectly test YCCK JPEG compression/decompression (use the CMYK pixel");
System.out.println(" format for packed-pixel source/destination buffers)");
System.out.println("-png");
System.out.println(" Use PNG format for output images [default = PPM or PGM]");
System.out.println("-precision N");
System.out.println(" Use N-bit data precision when compressing [N = 2..16; default = 8; if N is");
System.out.println(" not 8 or 12, then -lossless must also be specified] (-precision 12 implies");
@@ -1000,7 +1008,9 @@ final class TJBench {
String tempStr = argv[0].toLowerCase();
if (tempStr.endsWith(".jpg") || tempStr.endsWith(".jpeg"))
decompOnly = true;
if (tempStr.endsWith(".bmp"))
if (tempStr.endsWith(".png"))
ext = new String("png");
else if (tempStr.endsWith(".bmp"))
ext = new String("bmp");
System.out.println("");
@@ -1137,7 +1147,9 @@ final class TJBench {
if (temp < 0)
usage();
maxMemory = temp;
} else if (matchArg(argv[i], "-nooutput", 4))
} else if (matchArg(argv[i], "-noicc", 4))
noICC = true;
else if (matchArg(argv[i], "-nooutput", 4))
xformOpt |= TJ.XOPT_NOOUTPUT;
else if (matchArg(argv[i], "-nosmooth", 4)) {
System.out.println("Using fastest upsampling algorithm\n");
@@ -1170,6 +1182,10 @@ final class TJBench {
pf = TJ.PF_XRGB;
else
usage();
} else if (matchArg(argv[i], "-png", 3)) {
if (ext == null)
ext = new String("png");
ext = "png";
} else if (matchArg(argv[i], "-precision", 4) &&
i < argv.length - 1) {
int temp = 0;
@@ -1357,6 +1373,8 @@ final class TJBench {
TJ.set(handle, TJ.PARAM_BOTTOMUP, bottomUp ? 1 : 0);
TJ.set(handle, TJ.PARAM_PRECISION, precision);
TJ.set(handle, TJ.PARAM_MAXPIXELS, maxPixels);
if (noICC)
TJ.set(handle, TJ.PARAM_SAVEMARKERS, 0);
IntByReference width = new IntByReference(),
height = new IntByReference(),
@@ -1370,6 +1388,9 @@ final class TJBench {
else
srcBuf = TJ.loadImage16(handle, argv[0], width, 1, height,
pixelFormat);
NativeLongByReference iccSizeRef = new NativeLongByReference();
TJ.getICCProfile(handle, null, iccSizeRef);
iccSize = iccSizeRef.getValue();
w = width.getValue();
h = height.getValue();
pf = pixelFormat.getValue();

View File

@@ -85,6 +85,8 @@ final class TJComp {
System.out.println(" Memory limit (in megabytes) for intermediate buffers used with progressive");
System.out.println(" JPEG compression, lossless JPEG compression, and Huffman table optimization");
System.out.println(" [default = no limit]");
System.out.println("-noicc");
System.out.println(" Do not transfer the embedded ICC profile (if any) from a PNG input image");
System.out.println("-precision N");
System.out.println(" Create a JPEG image with N-bit data precision [N = 2..16; default = 8; if N");
System.out.println(" is not 8 or 12, then -lossless must also be specified] (-precision 12");
@@ -147,6 +149,7 @@ final class TJComp {
progressive = -1, quality = DEFAULT_QUALITY,
restartIntervalBlocks = -1, restartIntervalRows = -1,
subsamp = DEFAULT_SUBSAMP;
boolean noICC = false;
String iccFilename = null;
IntByReference width = new IntByReference(),
height = new IntByReference(),
@@ -188,8 +191,10 @@ final class TJComp {
if (temp < 0)
usage();
maxMemory = temp;
} else if (matchArg(argv[i], "-optimize", 2) ||
matchArg(argv[i], "-optimise", 2))
} else if (matchArg(argv[i], "-noicc", 4))
noICC = true;
else if (matchArg(argv[i], "-optimize", 2) ||
matchArg(argv[i], "-optimise", 2))
optimize = 1;
else if (matchArg(argv[i], "-precision", 4) && i < argv.length - 1) {
int temp = 0;
@@ -277,6 +282,8 @@ final class TJComp {
TJ.set(tjInstance, TJ.PARAM_RESTARTROWS, restartIntervalRows);
if (maxMemory >= 0)
TJ.set(tjInstance, TJ.PARAM_MAXMEMORY, maxMemory);
if (noICC)
TJ.set(tjInstance, TJ.PARAM_SAVEMARKERS, 0);
if (precision <= 8)
srcBuf = TJ.loadImage8(tjInstance, argv[i], width, 1, height,

View File

@@ -96,6 +96,9 @@ final class TJDecomp {
System.out.println("-icc FILE");
System.out.println(" Extract the ICC (International Color Consortium) color profile from the");
System.out.println(" JPEG image to the specified file");
System.out.println("-noicc");
System.out.println(" Do not transfer the embedded ICC profile (if any) from the JPEG image to a");
System.out.println(" PNG output image");
System.out.println("-strict");
System.out.println(" Treat all warnings as fatal; abort immediately if incomplete or corrupt");
System.out.println(" data is encountered in the JPEG image, rather than trying to salvage the");
@@ -169,7 +172,7 @@ final class TJDecomp {
int colorspace, fastDCT = -1, fastUpsample = -1, jpegPrecision,
maxMemory = -1, maxScans = -1, pixelFormat = TJ.PF_UNKNOWN,
precision = -1, stopOnWarning = -1, subsamp;
boolean lossless;
boolean lossless, noICC = false;
TJ.Region croppingRegion = TJ.UNCROPPED;
TJ.ScalingFactor scalingFactor = TJ.UNSCALED;
String iccFilename = null;
@@ -229,7 +232,9 @@ final class TJDecomp {
if (temp < 0)
usage();
maxMemory = temp;
} else if (matchArg(argv[i], "-nosmooth", 2))
} else if (matchArg(argv[i], "-noicc", 4))
noICC = true;
else if (matchArg(argv[i], "-nosmooth", 2))
fastUpsample = 1;
else if (matchArg(argv[i], "-precision", 4) && i < argv.length - 1) {
int temp = 0;
@@ -307,6 +312,8 @@ final class TJDecomp {
if (precision == -1 || lossless || jpegPrecision != 8)
precision = jpegPrecision;
sampleSize = (precision <= 8 ? 1 : 2);
if (noICC)
TJ.set(tjInstance, TJ.PARAM_SAVEMARKERS, 0);
if (iccFilename != null) {
NativeLongByReference iccSize = new NativeLongByReference();

View File

@@ -991,12 +991,15 @@ final class TJUnitTest {
static boolean cmpBitmap(Pointer buf, int width, int pitch, int height,
int pf, boolean bottomUp, boolean gray2rgb,
int targetPrecision) {
int targetPrecision, String ext) {
int roffset = TJ.RED_OFFSET[pf];
int goffset = TJ.GREEN_OFFSET[pf];
int boffset = TJ.BLUE_OFFSET[pf];
int aoffset = TJ.ALPHA_OFFSET[pf];
int ps = TJ.PIXEL_SIZE[pf];
if (ext.equalsIgnoreCase("bmp"))
targetPrecision = 8;
int targetMaxSample = (1 << targetPrecision) - 1;
for (int j = 0; j < height; j++) {
@@ -1011,12 +1014,38 @@ final class TJUnitTest {
if (precision != targetPrecision) {
long halfMaxSample = maxSample / 2;
r = (int)((r * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
// The expected results are slightly different with PNG files,
// because the samples are scaled up to 8 or 16 bits of data
// precision by the PNG writer and scaled down to the target data
// precision by the PNG reader.
if (ext.equalsIgnoreCase("png")) {
if (precision <= 8) {
r = (int)((r * 255 + halfMaxSample) / maxSample);
r = (int)((r * ((1 << targetPrecision) - 1) + 127) / 255);
g = (int)((g * 255 + halfMaxSample) / maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + 127) / 255);
b = (int)((b * 255 + halfMaxSample) / maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + 127) / 255);
} else {
long rtemp = (long)((r * 65535L + halfMaxSample) / maxSample);
long gtemp = (long)((g * 65535L + halfMaxSample) / maxSample);
long btemp = (long)((b * 65535L + halfMaxSample) / maxSample);
r = (int)((rtemp * ((1 << targetPrecision) - 1) + 32767) /
65535);
g = (int)((gtemp * ((1 << targetPrecision) - 1) + 32767) /
65535);
b = (int)((btemp * ((1 << targetPrecision) - 1) + 32767) /
65535);
}
} else {
r = (int)((r * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
}
}
if (pf == TJ.PF_GRAY) {
@@ -1077,6 +1106,26 @@ final class TJUnitTest {
loadHeight = new IntByReference(0), loadPF = new IntByReference(pf);
Pointer buf = null;
String md5ref;
String[] colorPNGRefs = new String[] {
"", "", "d973fcebcb785e9286d2b00f924a2bfc",
"76426aa13d42e2ba67a8ab84f93806e4", "9895df84ae7e67b234cbfb38028d514e",
"381fc9cee6d8f4f013907154c0a3d4a4", "e44dd82241dbcf822ff622e51e17d7a3",
"a6a143a8c16896368cee3b48e29f7e04", "1d9f6c50b5f6acbb882bf975ee85d2ac",
"6e3521e58ccd649001b7f135c9a0d77c", "8498b048f3a42cace76f199831036808",
"270933f0e53a513a331fc06c4d99fced", "14987f4410c740d99320a30814dcee00",
"b0f97624504d6f208a691063d2e83f90", "7baefad230a3fbad7447568d29ad72ad",
"7b5fa7dd6184319f15e02ee575d361e1", "39d5bac5fa6e9413ebcb1fe63a7f4750"
};
String[] grayPNGRefs = new String[] {
"", "", "35bd865b7b3f5c52baa4431d1722c68e",
"a80e6ab4afa043b680e7c61eeba1c49b", "d373a735273e0fd359aa7a43d92883f7",
"e414230904deffffb33e723c10a92150", "ce4426862b998ad1ca18d6d4dfcf8ed2",
"9cb84538b47ff164f5786d8662d39c62", "a1d57ae8785cf85abac187f274452655",
"3134b92be88363989d2e197c7aaa8876", "f7baac93d23bf38bcfbca29eff107799",
"839b9a975ddfb622caaef4496510c3f9", "e1d6704888c8a0d7fa234d9d625ea0eb",
"4c8d7484b3c4a5d195bf19996b350a9e", "33699b2ef9fcce812f26d7272cd98b7c",
"b9c85b94a2c109830f00c203c900f3d9", "3e31a40843885e839b27cfddb69b26f8"
};
String[] colorPPMRefs = new String[] {
"", "", "bad09d9ef38eda566848fb7c0b7fd0a",
"7ef2c87261a8bd6838303b541563cf27", "28a37cf9636ff6bb9ed6b206bdac60db",
@@ -1108,7 +1157,10 @@ final class TJUnitTest {
md5ref = (pf == TJ.PF_GRAY ? "51976530acf75f02beddf5d21149101d" :
"6d659071b9bfcdee2def22cb58ddadca");
maxTargetPrecision = 8;
} else
} else if (ext.equalsIgnoreCase("png"))
md5ref = (pf == TJ.PF_GRAY ? grayPNGRefs[precision] :
colorPNGRefs[precision]);
else
md5ref = (pf == TJ.PF_GRAY ? grayPPMRefs[precision] :
colorPPMRefs[precision]);
@@ -1152,7 +1204,7 @@ final class TJUnitTest {
" are bogus");
pitch = pad(width * TJ.PIXEL_SIZE[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, false,
ext.equalsIgnoreCase("bmp") ? 8 : targetPrecision))
targetPrecision, ext))
throw new Exception("Pixel data in " + filename + " is bogus " +
"(target data precision = " + targetPrecision +
")");
@@ -1172,7 +1224,7 @@ final class TJUnitTest {
pf = loadPF.getValue();
pitch = pad(width * TJ.PIXEL_SIZE[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, true,
ext.equalsIgnoreCase("bmp") ? 8 : targetPrecision))
targetPrecision, ext))
throw new Exception("Converting " + filename + " to RGB failed " +
"(target data precision = " + targetPrecision +
")");
@@ -1191,7 +1243,7 @@ final class TJUnitTest {
pf = loadPF.getValue();
pitch = pad(width * TJ.PIXEL_SIZE[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, true,
ext.equalsIgnoreCase("bmp") ? 8 : targetPrecision))
targetPrecision, ext))
throw new Exception("Converting " + filename +
" to CMYK failed (target data precision = " +
targetPrecision + ")");
@@ -1242,6 +1294,11 @@ final class TJUnitTest {
System.out.println("OK.");
}
System.out.format("%s Top-Down PNG (row alignment = %d samples) ... ",
PIXFORMATSTR[format], align);
doBmpTest("png", width, align, height, format, false);
System.out.println("OK.");
System.out.format("%s Top-Down PPM (row alignment = %d samples) ... ",
PIXFORMATSTR[format], align);
doBmpTest("ppm", width, align, height, format, false);
@@ -1254,6 +1311,11 @@ final class TJUnitTest {
System.out.println("OK.");
}
System.out.format("%s Bottom-Up PNG (row alignment = %d samples) ... ",
PIXFORMATSTR[format], align);
doBmpTest("png", width, align, height, format, true);
System.out.println("OK.");
System.out.format("%s Bottom-Up PPM (row alignment = %d samples) ... ",
PIXFORMATSTR[format], align);
doBmpTest("ppm", width, align, height, format, true);

View File

@@ -40,6 +40,10 @@ if(WITH_SIMD AND (MSVC_IDE OR XCODE))
set_source_files_properties(${SIMD_OBJS} PROPERTIES GENERATED 1)
endif()
if(WITH_TURBOJPEG OR WITH_TOOLS)
add_subdirectory(spng)
endif()
if(WIN32)
set(DEFFILE ../win/jpeg${SO_MAJOR_VERSION}.def)
endif()
@@ -85,25 +89,35 @@ if(WITH_TOOLS)
set(USE_SETMODE "-DUSE_SETMODE")
endif()
set(CDJPEG_COMPILE_FLAGS
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
"-DBMP_SUPPORTED -DGIF_SUPPORTED -DPNG_SUPPORTED -DSPNG_STATIC -DPPM_SUPPORTED -DTARGA_SUPPORTED ${USE_SETMODE}")
add_executable(cjpeg ../src/cjpeg.c ../src/cdjpeg.c ../src/rdbmp.c
../src/rdgif.c
../src/wrapper/rdpng-8.c ../src/wrapper/rdpng-12.c
../src/wrapper/rdpng-16.c $<TARGET_OBJECTS:spng>
../src/wrapper/rdppm-8.c ../src/wrapper/rdppm-12.c
../src/wrapper/rdppm-16.c
../src/rdswitch.c ../src/rdtarga.c)
set_property(TARGET cjpeg PROPERTY COMPILE_FLAGS ${CDJPEG_COMPILE_FLAGS})
target_link_libraries(cjpeg jpeg)
if(UNIX)
target_link_libraries(cjpeg m)
endif()
add_executable(djpeg ../src/djpeg.c ../src/cdjpeg.c
../src/wrapper/rdcolmap-8.c ../src/wrapper/rdcolmap-12.c
../src/rdswitch.c ../src/wrbmp.c
../src/wrapper/wrgif-8.c ../src/wrapper/wrgif-12.c
../src/wrapper/wrpng-8.c ../src/wrapper/wrpng-12.c
../src/wrapper/wrpng-16.c $<TARGET_OBJECTS:spng>
../src/wrapper/wrppm-8.c ../src/wrapper/wrppm-12.c
../src/wrapper/wrppm-16.c
../src/wrtarga.c)
set_property(TARGET djpeg PROPERTY COMPILE_FLAGS ${CDJPEG_COMPILE_FLAGS})
target_link_libraries(djpeg jpeg)
if(UNIX)
target_link_libraries(djpeg m)
endif()
add_executable(jpegtran ../src/jpegtran.c ../src/cdjpeg.c ../src/rdswitch.c
../src/transupp.c)

View File

@@ -0,0 +1,11 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../src/spng)
add_definitions(-DSPNG_STATIC -DSPNG_USE_MINIZ -D_LARGEFILE64_SOURCE)
add_library(spng OBJECT ../../src/spng/spng.c ../../src/spng/miniz.c)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
target_compile_options(spng PRIVATE -w)
endif()
if(CMAKE_C_COMPILER_ID MATCHES SunPro)
target_compile_options(spng PRIVATE -erroff)
endif()

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2009-2017 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2021, 2024, D. R. Commander.
* Copyright (C) 2021, 2024, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -72,6 +72,13 @@ JMESSAGE(JWRN_GIF_CHAR, "Bogus char 0x%02x in GIF file, ignoring")
JMESSAGE(JWRN_GIF_ENDCODE, "Premature end of GIF image")
JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
JMESSAGE(JERR_PNG_BADDEPTH, "Only 8- and 16-bit-per-channel PNG files are supported")
JMESSAGE(JERR_PNG_COLORSPACE, "PNG image must be grayscale or RGB")
JMESSAGE(JERR_PNG_LIBSPNG, "libspng error: %s")
JMESSAGE(JERR_PNG_OUTOFRANGE, "Numeric value out of range in PNG file")
JMESSAGE(JTRC_PNG_GRAYSCALE, "%ux%u %u-bit-per-channel grayscale PNG image")
JMESSAGE(JTRC_PNG_TRUECOLOR, "%ux%u %u-bit-per-channel true color PNG image")
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 2019 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2017, 2019, 2021-2022, D. R. Commander.
* Copyright (C) 2017, 2019, 2021-2022, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -29,6 +29,16 @@ typedef struct cjpeg_source_struct *cjpeg_source_ptr;
struct cjpeg_source_struct {
void (*start_input) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
/* Return the ICC profile (if any) embedded in the packed-pixel image.
*
* The pointer returned by this method will be freed in the body of the
* finish_input() method, so calling applications should make a copy of the
* ICC profile if they want to store it for later use. This method must be
* called after the start_input() method.
*/
boolean (*read_icc_profile) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr,
unsigned int *icc_data_len);
JDIMENSION (*get_pixel_rows) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
void (*finish_input) (j_compress_ptr cinfo, cjpeg_source_ptr sinfo);
@@ -55,6 +65,15 @@ struct djpeg_dest_struct {
* The color map will be ready at this time, if one is needed.
*/
void (*start_output) (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo);
/* Embed an ICC profile in the packed-pixel image.
*
* The pointer passed to this method will be freed in the body of the
* finish_output() method. This method must be called before the
* start_output() method.
*/
void (*write_icc_profile) (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr,
unsigned int icc_data_len);
/* Emit the specified number of pixel rows from the buffer. */
void (*put_pixel_rows) (j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied);
@@ -117,6 +136,16 @@ EXTERN(cjpeg_source_ptr) jinit_read_gif(j_compress_ptr cinfo);
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);
EXTERN(cjpeg_source_ptr) jinit_read_png(j_compress_ptr cinfo);
EXTERN(cjpeg_source_ptr) j12init_read_png(j_compress_ptr cinfo);
#ifdef C_LOSSLESS_SUPPORTED
EXTERN(cjpeg_source_ptr) j16init_read_png(j_compress_ptr cinfo);
#endif
EXTERN(djpeg_dest_ptr) jinit_write_png(j_decompress_ptr cinfo);
EXTERN(djpeg_dest_ptr) j12init_write_png(j_decompress_ptr cinfo);
#ifdef D_LOSSLESS_SUPPORTED
EXTERN(djpeg_dest_ptr) j16init_write_png(j_decompress_ptr cinfo);
#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

View File

@@ -108,6 +108,21 @@ select_file_type(j_compress_ptr cinfo, FILE *infile)
case 'G':
return jinit_read_gif(cinfo);
#endif
#ifdef PNG_SUPPORTED
case 0x89:
if (cinfo->data_precision <= 8)
return jinit_read_png(cinfo);
else if (cinfo->data_precision <= 12)
return j12init_read_png(cinfo);
else {
#ifdef C_LOSSLESS_SUPPORTED
return j16init_read_png(cinfo);
#else
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
break;
#endif
}
#endif
#ifdef PPM_SUPPORTED
case 'P':
if (cinfo->data_precision <= 8)
@@ -147,6 +162,7 @@ select_file_type(j_compress_ptr cinfo, FILE *infile)
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static boolean noicc; /* for -noicc switch */
static char *outfilename; /* for -outfile switch */
static boolean memdst; /* for -memdst switch */
static boolean report; /* for -report switch */
@@ -243,6 +259,7 @@ usage(void)
(JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : ""));
#endif
fprintf(stderr, " -icc FILE Embed ICC profile contained in FILE\n");
fprintf(stderr, " -noicc Do not transfer ICC profile from PNG input file\n");
fprintf(stderr, " -restart N Set restart interval in rows, or in blocks with B\n");
#ifdef INPUT_SMOOTHING_SUPPORTED
fprintf(stderr, " -smooth N Smooth dithered input (N=1..100 is strength)\n");
@@ -297,6 +314,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
simple_progressive = FALSE;
is_targa = FALSE;
icc_filename = NULL;
noicc = FALSE;
outfilename = NULL;
memdst = FALSE;
report = FALSE;
@@ -379,6 +397,9 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv,
usage();
icc_filename = argv[argn];
} else if (keymatch(arg, "noicc", 3)) {
noicc = TRUE;
} else if (keymatch(arg, "lossless", 1)) {
/* Enable lossless mode. */
#ifdef C_LOSSLESS_SUPPORTED
@@ -795,6 +816,14 @@ main(int argc, char **argv)
if (icc_profile != NULL)
jpeg_write_icc_profile(&cinfo, icc_profile, (unsigned int)icc_len);
else if (!noicc) {
JOCTET *src_icc_profile;
unsigned int src_icc_len;
if ((*src_mgr->read_icc_profile) (&cinfo, src_mgr, &src_icc_profile,
&src_icc_len))
jpeg_write_icc_profile(&cinfo, src_icc_profile, src_icc_len);
}
/* Process data */
if (cinfo.data_precision <= 8) {

View File

@@ -62,6 +62,7 @@ typedef enum {
FMT_GIF, /* GIF format (LZW-compressed) */
FMT_GIF0, /* GIF format (uncompressed) */
FMT_OS2, /* BMP format (OS/2 flavor) */
FMT_PNG, /* PNG format */
FMT_PPM, /* PPM/PGM (PBMPLUS formats) */
FMT_TARGA, /* Targa format */
FMT_TIFF /* TIFF format */
@@ -85,6 +86,7 @@ static IMAGE_FORMATS requested_fmt;
static const char *progname; /* program name for error messages */
static char *icc_filename; /* for -icc switch */
static boolean noicc; /* for -noicc switch */
static JDIMENSION max_scans; /* for -maxscans switch */
static char *outfilename; /* for -outfile switch */
static boolean memsrc; /* for -memsrc switch */
@@ -130,6 +132,10 @@ usage(void)
fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s [legacy feature]\n",
(DEFAULT_FMT == FMT_OS2 ? " (default)" : ""));
#endif
#ifdef PNG_SUPPORTED
fprintf(stderr, " -png Select PNG output format%s\n",
(DEFAULT_FMT == FMT_PNG ? " (default)" : ""));
#endif
#ifdef PPM_SUPPORTED
fprintf(stderr, " -pnm Select PBMPLUS (PPM/PGM) output format%s\n",
(DEFAULT_FMT == FMT_PPM ? " (default)" : ""));
@@ -158,6 +164,7 @@ usage(void)
fprintf(stderr, " -dither ordered Use ordered dithering when quantizing colors\n");
fprintf(stderr, " [legacy feature]\n");
fprintf(stderr, " -icc FILE Extract ICC profile to FILE\n");
fprintf(stderr, " -noicc Do not transfer ICC profile to PNG output file\n");
#ifdef QUANT_2PASS_SUPPORTED
fprintf(stderr, " -map FILE Quantize to colors used in named image file [legacy feature]\n");
#endif
@@ -172,7 +179,7 @@ usage(void)
fprintf(stderr, " -report Report decompression progress\n");
fprintf(stderr, " -skip Y0,Y1 Decompress all rows except those between Y0 and Y1 (inclusive)\n");
fprintf(stderr, " -crop WxH+X+Y Decompress only a rectangular subregion of the image\n");
fprintf(stderr, " [requires PBMPLUS (PPM/PGM), GIF, or Targa output format]\n");
fprintf(stderr, " [requires PNG, PBMPLUS (PPM/PGM), Targa, or GIF output format]\n");
fprintf(stderr, " -strict Treat all warnings as fatal\n");
fprintf(stderr, " -verbose or -debug Emit debug output\n");
fprintf(stderr, " -version Print version information and exit\n");
@@ -198,6 +205,7 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
/* Set up default JPEG parameters. */
requested_fmt = DEFAULT_FMT; /* set default output file format */
icc_filename = NULL;
noicc = FALSE;
max_scans = 0;
outfilename = NULL;
memsrc = FALSE;
@@ -322,6 +330,9 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
jpeg_save_markers(cinfo, JPEG_APP0 + 2, 0xFFFF);
#endif
} else if (keymatch(arg, "noicc", 3)) {
noicc = TRUE;
} else if (keymatch(arg, "map", 3)) {
/* Quantize to a color map taken from an input file. */
if (++argn >= argc) /* advance to next argument */
@@ -390,6 +401,10 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv,
/* PPM/PGM output format. */
requested_fmt = FMT_PPM;
} else if (keymatch(arg, "png", 3)) {
/* PNG output format. */
requested_fmt = FMT_PNG;
} else if (keymatch(arg, "precision", 2)) {
/* Set data precision. */
int val;
@@ -671,6 +686,10 @@ main(int argc, char **argv)
jpeg_stdio_src(&cinfo, input_file);
/* Read file header, set default decompression parameters */
#if defined(SAVE_MARKERS_SUPPORTED) && defined(PNG_SUPPORTED)
if (requested_fmt == FMT_PNG)
jpeg_save_markers(&cinfo, JPEG_APP0 + 2, 0xFFFF);
#endif
(void)jpeg_read_header(&cinfo, TRUE);
/* Adjust default decompression parameters by re-parsing the options */
@@ -701,6 +720,20 @@ main(int argc, char **argv)
dest_mgr = jinit_write_gif(&cinfo, FALSE);
break;
#endif
#ifdef PNG_SUPPORTED
case FMT_PNG:
if (cinfo.data_precision <= 8)
dest_mgr = jinit_write_png(&cinfo);
else if (cinfo.data_precision <= 12)
dest_mgr = j12init_write_png(&cinfo);
else
#ifdef D_LOSSLESS_SUPPORTED
dest_mgr = j16init_write_png(&cinfo);
#else
ERREXIT1(&cinfo, JERR_BAD_PRECISION, cinfo.data_precision);
#endif
break;
#endif
#ifdef PPM_SUPPORTED
case FMT_PPM:
if (cinfo.data_precision <= 8)
@@ -726,6 +759,14 @@ main(int argc, char **argv)
}
dest_mgr->output_file = output_file;
if (requested_fmt == FMT_PNG && !noicc) {
JOCTET *icc_profile;
unsigned int icc_len;
if (jpeg_read_icc_profile(&cinfo, &icc_profile, &icc_len))
(*dest_mgr->write_icc_profile) (&cinfo, dest_mgr, icc_profile, icc_len);
}
/* Start decompressor */
(void)jpeg_start_decompress(&cinfo);

View File

@@ -1,7 +1,7 @@
/*
* jsamplecomp.h
*
* Copyright (C) 2022, D. R. Commander.
* Copyright (C) 2022, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*/
@@ -93,10 +93,12 @@
/* Image I/O functions (cdjpeg.h) */
#ifdef C_LOSSLESS_SUPPORTED
#define _jinit_read_png j16init_read_png
#define _jinit_read_ppm j16init_read_ppm
#endif
#ifdef D_LOSSLESS_SUPPORTED
#define _jinit_write_png j16init_write_png
#define _jinit_write_ppm j16init_write_ppm
#endif
@@ -209,6 +211,8 @@
/* Image I/O functions (cdjpeg.h) */
#define _jinit_write_gif j12init_write_gif
#define _jinit_read_png j12init_read_png
#define _jinit_write_png j12init_write_png
#define _jinit_read_ppm j12init_read_ppm
#define _jinit_write_ppm j12init_write_ppm
@@ -323,6 +327,8 @@
/* Image I/O functions (cdjpeg.h) */
#define _jinit_write_gif jinit_write_gif
#define _jinit_read_png jinit_read_png
#define _jinit_write_png jinit_write_png
#define _jinit_read_ppm jinit_read_ppm
#define _jinit_write_ppm jinit_write_ppm

View File

@@ -625,7 +625,7 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
/* Ensure that biWidth * cinfo->input_components doesn't exceed the maximum
value of the JDIMENSION type. This is only a danger with BMP files, since
value of the JDIMENSION type. This is a danger with BMP files, since
their width and height fields are 32-bit integers. */
if ((unsigned long long)biWidth *
(unsigned long long)cinfo->input_components > 0xFFFFFFFFULL)
@@ -642,6 +642,14 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
METHODDEF(boolean)
read_icc_profile_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
return FALSE;
}
/*
* Finish up at the end of the file.
*/
@@ -672,6 +680,7 @@ jinit_read_bmp(j_compress_ptr cinfo, boolean use_inversion_array)
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_bmp;
source->pub.read_icc_profile = read_icc_profile_bmp;
source->pub.finish_input = finish_input_bmp;
source->pub.max_pixels = 0;

View File

@@ -672,6 +672,14 @@ get_interlaced_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
METHODDEF(boolean)
read_icc_profile_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
return FALSE;
}
/*
* Finish up at the end of the file.
*/
@@ -702,6 +710,7 @@ jinit_read_gif(j_compress_ptr cinfo)
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_gif;
source->pub.read_icc_profile = read_icc_profile_gif;
source->pub.finish_input = finish_input_gif;
source->pub.max_pixels = 0;

574
src/rdpng.c Normal file
View File

@@ -0,0 +1,574 @@
/*
* rdpng.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1997, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2015-2017, 2020-2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains routines to read input images in 8-bit-per-channel or
* 16-bit-per-channel PNG format. libspng is required to compile this
* software.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include "cmyk.h"
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "spng/spng.h"
#if defined(PNG_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED))
static int alpha_index[JPEG_NUMCS] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1
};
#define TRY_SPNG(f) { \
int __spng_error = (f); \
if (__spng_error) \
ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(__spng_error)); \
}
/* Private version of data source object */
typedef struct {
struct cjpeg_source_struct pub; /* public fields */
spng_ctx *ctx;
uint8_t png_bit_depth, png_color_type;
int png_alpha;
/* Usually these two pointers point to the same place: */
unsigned char *iobuffer; /* libspng's I/O buffer */
_JSAMPROW pixrow; /* compressor input buffer */
size_t buffer_width; /* width of I/O buffer */
_JSAMPLE *rescale; /* PNG bit depth => data precision remapping
array, or NULL */
} png_source_struct;
typedef png_source_struct *png_source_ptr;
/*
* Read one row of pixels.
*
* We provide several different versions depending on input file format.
* In all cases, input is scaled to cinfo->data_precision.
*
* get_raw_row() is used when the pixel format is JCS_EXT_RGB/JCS_RGB or
* JCS_GRAYSCALE, cinfo->data_precision is 8 or 16, and the PNG file doesn't
* have an alpha channel. Thus, we can read the pixels directly from the PNG
* file.
*/
METHODDEF(JDIMENSION)
get_raw_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_ptr source = (png_source_ptr)sinfo;
int spng_error;
spng_error = spng_decode_row(source->ctx, source->iobuffer,
source->buffer_width);
if (spng_error && spng_error != SPNG_EOI)
ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(spng_error)); \
return 1;
}
#define GRAY_RGB_READ_LOOP(read_op, alpha_set_op, pointer_op) { \
for (col = cinfo->image_width; col > 0; col--) { \
ptr[rindex] = ptr[gindex] = ptr[bindex] = read_op; \
alpha_set_op \
ptr += ps; \
pointer_op \
} \
}
METHODDEF(JDIMENSION)
get_gray_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
* grayscale or grayscale + alpha PNG files.
*/
{
png_source_ptr source = (png_source_ptr)sinfo;
register _JSAMPROW ptr;
register _JSAMPLE *rescale = source->rescale;
JDIMENSION col;
get_raw_row(cinfo, sinfo);
ptr = source->pub._buffer[0];
#if BITS_IN_JSAMPLE != 12
if (source->png_bit_depth == cinfo->data_precision) {
_JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
*ptr++ = *bufferptr++;
bufferptr += source->png_alpha;
}
} else
#endif
if (source->png_bit_depth == 16) {
register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
*ptr++ = rescale[*bufferptr++];
bufferptr += source->png_alpha;
}
} else {
register unsigned char *bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
*ptr++ = rescale[*bufferptr++];
bufferptr += source->png_alpha;
}
}
return 1;
}
METHODDEF(JDIMENSION)
get_gray_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
* grayscale or grayscale + alpha PNG files and converting to extended RGB.
*/
{
png_source_ptr source = (png_source_ptr)sinfo;
register _JSAMPROW ptr;
register _JSAMPLE *rescale = source->rescale;
JDIMENSION col;
register int rindex = rgb_red[cinfo->in_color_space];
register int gindex = rgb_green[cinfo->in_color_space];
register int bindex = rgb_blue[cinfo->in_color_space];
register int aindex = alpha_index[cinfo->in_color_space];
register int ps = rgb_pixelsize[cinfo->in_color_space];
get_raw_row(cinfo, sinfo);
ptr = source->pub._buffer[0];
#if BITS_IN_JSAMPLE != 12
if (source->png_bit_depth == cinfo->data_precision) {
_JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
if (aindex >= 0)
GRAY_RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
bufferptr += source->png_alpha;)
else
GRAY_RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
} else
#endif
if (source->png_bit_depth == 16) {
register unsigned short *bufferptr = (unsigned short *)source->iobuffer;
if (aindex >= 0)
GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
ptr[aindex] = (1 << cinfo->data_precision) - 1;,
bufferptr += source->png_alpha;)
else
GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
bufferptr += source->png_alpha;)
} else {
register unsigned char *bufferptr = source->iobuffer;
if (aindex >= 0)
GRAY_RGB_READ_LOOP(rescale[*bufferptr++],
ptr[aindex] = (1 << cinfo->data_precision) - 1;,
bufferptr += source->png_alpha;)
else
GRAY_RGB_READ_LOOP(rescale[*bufferptr++], {},
bufferptr += source->png_alpha;)
}
return 1;
}
METHODDEF(JDIMENSION)
get_gray_cmyk_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel
* grayscale or grayscale + alpha PNG files and converting to CMYK.
*/
{
png_source_ptr source = (png_source_ptr)sinfo;
register _JSAMPROW ptr;
register _JSAMPLE *rescale = source->rescale;
JDIMENSION col;
get_raw_row(cinfo, sinfo);
ptr = source->pub._buffer[0];
#if BITS_IN_JSAMPLE != 12
if (source->png_bit_depth == cinfo->data_precision) {
register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE gray = *bufferptr++;
bufferptr += source->png_alpha;
rgb_to_cmyk(_MAXJSAMPLE, gray, gray, gray, ptr, ptr + 1, ptr + 2,
ptr + 3);
ptr += 4;
}
} else
#endif
if (source->png_bit_depth == 16) {
unsigned short *bufferptr = (unsigned short *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE gray = rescale[*bufferptr++];
bufferptr += source->png_alpha;
rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
ptr + 1, ptr + 2, ptr + 3);
ptr += 4;
}
} else {
register unsigned char *bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE gray = rescale[*bufferptr++];
bufferptr += source->png_alpha;
rgb_to_cmyk((1 << cinfo->data_precision) - 1, gray, gray, gray, ptr,
ptr + 1, ptr + 2, ptr + 3);
ptr += 4;
}
}
return 1;
}
#define RGB_READ_LOOP(read_op, alpha_set_op, pointer_op) { \
for (col = cinfo->image_width; col > 0; col--) { \
ptr[rindex] = read_op; \
ptr[gindex] = read_op; \
ptr[bindex] = read_op; \
alpha_set_op \
pointer_op \
ptr += ps; \
} \
}
METHODDEF(JDIMENSION)
get_rgb_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel true
* color or true color + alpha PNG files and converting to extended RGB.
*/
{
png_source_ptr source = (png_source_ptr)sinfo;
register _JSAMPROW ptr;
register _JSAMPLE *rescale = source->rescale;
JDIMENSION col;
register int rindex = rgb_red[cinfo->in_color_space];
register int gindex = rgb_green[cinfo->in_color_space];
register int bindex = rgb_blue[cinfo->in_color_space];
register int aindex = alpha_index[cinfo->in_color_space];
register int ps = rgb_pixelsize[cinfo->in_color_space];
get_raw_row(cinfo, sinfo);
ptr = source->pub._buffer[0];
#if BITS_IN_JSAMPLE != 12
if (source->png_bit_depth == cinfo->data_precision) {
register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
if (aindex >= 0)
RGB_READ_LOOP(*bufferptr++, ptr[aindex] = _MAXJSAMPLE;,
bufferptr += source->png_alpha;)
else
RGB_READ_LOOP(*bufferptr++, {}, bufferptr += source->png_alpha;)
} else
#endif
if (source->png_bit_depth == 16) {
unsigned short *bufferptr = (unsigned short *)source->iobuffer;
if (aindex >= 0)
RGB_READ_LOOP(rescale[*bufferptr++],
ptr[aindex] = (1 << cinfo->data_precision) - 1;,
bufferptr += source->png_alpha;)
else
RGB_READ_LOOP(rescale[*bufferptr++], {},
bufferptr += source->png_alpha;)
} else {
register unsigned char *bufferptr = source->iobuffer;
if (aindex >= 0)
RGB_READ_LOOP(rescale[*bufferptr++],
ptr[aindex] = (1 << cinfo->data_precision) - 1;,
bufferptr += source->png_alpha;)
else
RGB_READ_LOOP(rescale[*bufferptr++], {},
bufferptr += source->png_alpha;)
}
return 1;
}
METHODDEF(JDIMENSION)
get_rgb_cmyk_row(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
/* This version is for reading 8-bit-per-channel or 16-bit-per-channel true
* color or true color + alpha PNG files and converting to CMYK.
*/
{
png_source_ptr source = (png_source_ptr)sinfo;
register _JSAMPROW ptr;
register _JSAMPLE *rescale = source->rescale;
JDIMENSION col;
get_raw_row(cinfo, sinfo);
ptr = source->pub._buffer[0];
#if BITS_IN_JSAMPLE != 12
if (source->png_bit_depth == cinfo->data_precision) {
register _JSAMPLE *bufferptr = (_JSAMPLE *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE r = *bufferptr++;
_JSAMPLE g = *bufferptr++;
_JSAMPLE b = *bufferptr++;
bufferptr += source->png_alpha;
rgb_to_cmyk(_MAXJSAMPLE, r, g, b, ptr, ptr + 1, ptr + 2, ptr + 3);
ptr += 4;
}
} else
#endif
if (source->png_bit_depth == 16) {
unsigned short *bufferptr = (unsigned short *)source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE r = rescale[*bufferptr++];
_JSAMPLE g = rescale[*bufferptr++];
_JSAMPLE b = rescale[*bufferptr++];
bufferptr += source->png_alpha;
rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
ptr + 2, ptr + 3);
ptr += 4;
}
} else {
register unsigned char *bufferptr = source->iobuffer;
for (col = cinfo->image_width; col > 0; col--) {
_JSAMPLE r = rescale[*bufferptr++];
_JSAMPLE g = rescale[*bufferptr++];
_JSAMPLE b = rescale[*bufferptr++];
bufferptr += source->png_alpha;
rgb_to_cmyk((1 << cinfo->data_precision) - 1, r, g, b, ptr, ptr + 1,
ptr + 2, ptr + 3);
ptr += 4;
}
}
return 1;
}
/*
* Read the file header; return image size and component count.
*/
METHODDEF(void)
start_input_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_ptr source = (png_source_ptr)sinfo;
struct spng_ihdr ihdr;
int png_components = 3;
boolean use_raw_buffer;
source->ctx = spng_ctx_new(0);
if (!source->ctx)
ERREXITS(cinfo, JERR_PNG_LIBSPNG, "Could not create context");
TRY_SPNG(spng_set_png_file(source->ctx, sinfo->input_file));
TRY_SPNG(spng_get_ihdr(source->ctx, &ihdr));
if (ihdr.width > 65535 || ihdr.height > 65535)
ERREXIT(cinfo, JERR_PNG_OUTOFRANGE);
if (ihdr.bit_depth != 8 && ihdr.bit_depth != 16)
ERREXIT(cinfo, JERR_PNG_BADDEPTH);
if (sinfo->max_pixels &&
(unsigned long long)ihdr.width * ihdr.height > sinfo->max_pixels)
ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels);
cinfo->image_width = (JDIMENSION)ihdr.width;
cinfo->image_height = (JDIMENSION)ihdr.height;
source->png_bit_depth = ihdr.bit_depth;
source->png_color_type = ihdr.color_type;
/* initialize flags to most common settings */
use_raw_buffer = FALSE; /* do we map input buffer onto I/O buffer? */
switch (ihdr.color_type) {
case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
case SPNG_COLOR_TYPE_GRAYSCALE:
if (cinfo->in_color_space == JCS_UNKNOWN ||
cinfo->in_color_space == JCS_RGB)
cinfo->in_color_space = JCS_GRAYSCALE;
TRACEMS3(cinfo, 1, JTRC_PNG_GRAYSCALE, ihdr.width, ihdr.height,
ihdr.bit_depth);
if (cinfo->in_color_space == JCS_GRAYSCALE) {
if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE &&
cinfo->data_precision == ihdr.bit_depth) {
source->pub.get_pixel_rows = get_raw_row;
use_raw_buffer = TRUE;
} else
source->pub.get_pixel_rows = get_gray_row;
} else if (IsExtRGB(cinfo->in_color_space))
source->pub.get_pixel_rows = get_gray_rgb_row;
else if (cinfo->in_color_space == JCS_CMYK)
source->pub.get_pixel_rows = get_gray_cmyk_row;
else
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
if (ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA) {
png_components = 2;
source->png_alpha = 1;
} else {
png_components = 1;
source->png_alpha = 0;
}
break;
case SPNG_COLOR_TYPE_TRUECOLOR:
case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
if (cinfo->in_color_space == JCS_UNKNOWN)
cinfo->in_color_space = JCS_EXT_RGB;
TRACEMS3(cinfo, 1, JTRC_PNG_TRUECOLOR, ihdr.width, ihdr.height,
ihdr.bit_depth);
if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR &&
cinfo->data_precision == ihdr.bit_depth &&
#if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
(cinfo->in_color_space == JCS_EXT_RGB ||
cinfo->in_color_space == JCS_RGB)) {
#else
cinfo->in_color_space == JCS_EXT_RGB) {
#endif
source->pub.get_pixel_rows = get_raw_row;
use_raw_buffer = TRUE;
} else if (IsExtRGB(cinfo->in_color_space))
source->pub.get_pixel_rows = get_rgb_row;
else if (cinfo->in_color_space == JCS_CMYK)
source->pub.get_pixel_rows = get_rgb_cmyk_row;
else
ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
if (ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA) {
png_components = 4;
source->png_alpha = 1;
} else {
png_components = 3;
source->png_alpha = 0;
}
break;
default:
ERREXIT(cinfo, JERR_PNG_COLORSPACE);
}
if (IsExtRGB(cinfo->in_color_space))
cinfo->input_components = rgb_pixelsize[cinfo->in_color_space];
else if (cinfo->in_color_space == JCS_GRAYSCALE)
cinfo->input_components = 1;
else if (cinfo->in_color_space == JCS_CMYK)
cinfo->input_components = 4;
/* Allocate space for I/O buffer: 1 or 3 bytes or words/pixel. */
source->buffer_width =
(size_t)ihdr.width * png_components * source->png_bit_depth / 8;
source->iobuffer = (unsigned char *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
source->buffer_width);
/* Create compressor input buffer. */
if (use_raw_buffer) {
/* For unscaled raw-input case, we can just map it onto the I/O buffer. */
/* Synthesize a _JSAMPARRAY pointer structure */
source->pixrow = (_JSAMPROW)source->iobuffer;
source->pub._buffer = &source->pixrow;
source->pub.buffer_height = 1;
} else {
unsigned int maxval = source->png_bit_depth == 16 ? 65535 : 255;
long val, half_maxval;
/* Need to translate anyway, so make a separate sample buffer. */
source->pub._buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE,
(JDIMENSION)ihdr.width * cinfo->input_components, (JDIMENSION)1);
source->pub.buffer_height = 1;
/* Compute the rescaling array. */
source->rescale = (_JSAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(size_t)(((long)maxval + 1L) *
sizeof(_JSAMPLE)));
memset(source->rescale, 0, (size_t)(((long)maxval + 1L) *
sizeof(_JSAMPLE)));
half_maxval = maxval / 2;
for (val = 0; val <= (long)maxval; val++) {
/* The multiplication here must be done in 32 bits to avoid overflow */
source->rescale[val] =
(_JSAMPLE)((val * ((1 << cinfo->data_precision) - 1) + half_maxval) /
maxval);
}
}
TRY_SPNG(spng_decode_image(source->ctx, NULL, 0, SPNG_FMT_PNG,
SPNG_DECODE_PROGRESSIVE));
}
/*
* Return the ICC profile (if any) embedded in the PNG image.
*/
METHODDEF(boolean)
read_icc_profile_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
png_source_ptr source = (png_source_ptr)sinfo;
struct spng_iccp iccp;
if (!icc_data_ptr || !icc_data_len)
ERREXIT(cinfo, JERR_BUFFER_SIZE);
if (source->ctx && spng_get_iccp(source->ctx, &iccp) == 0) {
*icc_data_ptr = (JOCTET *)iccp.profile;
*icc_data_len = (unsigned int)iccp.profile_len;
return TRUE;
}
return FALSE;
}
/*
* Finish up at the end of the file.
*/
METHODDEF(void)
finish_input_png(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
{
png_source_ptr source = (png_source_ptr)sinfo;
if (source->ctx) {
spng_decode_chunks(source->ctx);
spng_ctx_free(source->ctx);
}
}
/*
* The module selection routine for PNG format input.
*/
GLOBAL(cjpeg_source_ptr)
_jinit_read_png(j_compress_ptr cinfo)
{
png_source_ptr source;
#if BITS_IN_JSAMPLE == 8
if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
#else
if (cinfo->data_precision > BITS_IN_JSAMPLE ||
cinfo->data_precision < BITS_IN_JSAMPLE - 3)
#endif
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Create module interface object */
source = (png_source_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(png_source_struct));
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_png;
source->pub.read_icc_profile = read_icc_profile_png;
source->pub.finish_input = finish_input_png;
source->pub.max_pixels = 0;
return (cjpeg_source_ptr)source;
}
#endif /* defined(PNG_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(C_LOSSLESS_SUPPORTED)) */

View File

@@ -896,6 +896,14 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
METHODDEF(boolean)
read_icc_profile_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
return FALSE;
}
/*
* Finish up at the end of the file.
*/
@@ -930,6 +938,7 @@ _jinit_read_ppm(j_compress_ptr cinfo)
sizeof(ppm_source_struct));
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_ppm;
source->pub.read_icc_profile = read_icc_profile_ppm;
source->pub.finish_input = finish_input_ppm;
source->pub.max_pixels = 0;

View File

@@ -465,6 +465,14 @@ start_input_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
}
METHODDEF(boolean)
read_icc_profile_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo,
JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
return FALSE;
}
/*
* Finish up at the end of the file.
*/
@@ -495,6 +503,7 @@ jinit_read_targa(j_compress_ptr cinfo)
source->cinfo = cinfo; /* make back link for subroutines */
/* Fill in method ptrs, except get_pixel_rows which start_input sets */
source->pub.start_input = start_input_tga;
source->pub.read_icc_profile = read_icc_profile_tga;
source->pub.finish_input = finish_input_tga;
source->pub.max_pixels = 0;

11
src/spng/CMakeLists.txt Normal file
View File

@@ -0,0 +1,11 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_definitions(-DSPNG_STATIC -DSPNG_USE_MINIZ -D_LARGEFILE64_SOURCE)
add_library(spng-static OBJECT spng.c miniz.c)
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
target_compile_options(spng-static PRIVATE -w)
endif()
if(CMAKE_C_COMPILER_ID MATCHES SunPro)
target_compile_options(spng-static PRIVATE -erroff)
endif()

25
src/spng/LICENSE Normal file
View File

@@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2018-2023, Randy <randy408@protonmail.com>
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.
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 HOLDER 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.

View File

@@ -0,0 +1,36 @@
COPYRIGHT NOTICE, DISCLAIMER, and LICENSE
=========================================
PNG Reference Library License version 2
---------------------------------------
* Copyright (c) 1995-2026 The PNG Reference Library Authors.
* Copyright (c) 2018-2026 Cosmin Truta.
* Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
* Copyright (c) 1996-1997 Andreas Dilger.
* Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
The software is supplied "as is", without warranty of any kind,
express or implied, including, without limitation, the warranties
of merchantability, fitness for a particular purpose, title, and
non-infringement. In no event shall the Copyright owners, or
anyone distributing the software, be liable for any damages or
other liability, whether in contract, tort or otherwise, arising
from, out of, or in connection with the software, or the use or
other dealings in the software, even if advised of the possibility
of such damage.
Permission is hereby granted to use, copy, modify, and distribute
this software, or portions hereof, for any purpose, without fee,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you
use this software in a product, an acknowledgment in the product
documentation would be appreciated, but is not required.
2. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
3. This Copyright notice may not be removed or altered from any
source or altered source distribution.

7909
src/spng/miniz.c Normal file

File diff suppressed because it is too large Load Diff

1510
src/spng/miniz.h Normal file

File diff suppressed because it is too large Load Diff

6982
src/spng/spng.c Normal file

File diff suppressed because it is too large Load Diff

537
src/spng/spng.h Normal file
View File

@@ -0,0 +1,537 @@
/* SPDX-License-Identifier: BSD-2-Clause */
#ifndef SPNG_H
#define SPNG_H
#ifdef __cplusplus
extern "C" {
#endif
#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(SPNG_STATIC)
#if defined(SPNG__BUILD)
#define SPNG_API __declspec(dllexport)
#else
#define SPNG_API __declspec(dllimport)
#endif
#else
#define SPNG_API
#endif
#if defined(_MSC_VER)
#define SPNG_CDECL __cdecl
#else
#define SPNG_CDECL
#endif
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#define SPNG_VERSION_MAJOR 0
#define SPNG_VERSION_MINOR 7
#define SPNG_VERSION_PATCH 4
enum spng_errno
{
SPNG_IO_ERROR = -2,
SPNG_IO_EOF = -1,
SPNG_OK = 0,
SPNG_EINVAL,
SPNG_EMEM,
SPNG_EOVERFLOW,
SPNG_ESIGNATURE,
SPNG_EWIDTH,
SPNG_EHEIGHT,
SPNG_EUSER_WIDTH,
SPNG_EUSER_HEIGHT,
SPNG_EBIT_DEPTH,
SPNG_ECOLOR_TYPE,
SPNG_ECOMPRESSION_METHOD,
SPNG_EFILTER_METHOD,
SPNG_EINTERLACE_METHOD,
SPNG_EIHDR_SIZE,
SPNG_ENOIHDR,
SPNG_ECHUNK_POS,
SPNG_ECHUNK_SIZE,
SPNG_ECHUNK_CRC,
SPNG_ECHUNK_TYPE,
SPNG_ECHUNK_UNKNOWN_CRITICAL,
SPNG_EDUP_PLTE,
SPNG_EDUP_CHRM,
SPNG_EDUP_GAMA,
SPNG_EDUP_ICCP,
SPNG_EDUP_SBIT,
SPNG_EDUP_SRGB,
SPNG_EDUP_BKGD,
SPNG_EDUP_HIST,
SPNG_EDUP_TRNS,
SPNG_EDUP_PHYS,
SPNG_EDUP_TIME,
SPNG_EDUP_OFFS,
SPNG_EDUP_EXIF,
SPNG_ECHRM,
SPNG_EPLTE_IDX,
SPNG_ETRNS_COLOR_TYPE,
SPNG_ETRNS_NO_PLTE,
SPNG_EGAMA,
SPNG_EICCP_NAME,
SPNG_EICCP_COMPRESSION_METHOD,
SPNG_ESBIT,
SPNG_ESRGB,
SPNG_ETEXT,
SPNG_ETEXT_KEYWORD,
SPNG_EZTXT,
SPNG_EZTXT_COMPRESSION_METHOD,
SPNG_EITXT,
SPNG_EITXT_COMPRESSION_FLAG,
SPNG_EITXT_COMPRESSION_METHOD,
SPNG_EITXT_LANG_TAG,
SPNG_EITXT_TRANSLATED_KEY,
SPNG_EBKGD_NO_PLTE,
SPNG_EBKGD_PLTE_IDX,
SPNG_EHIST_NO_PLTE,
SPNG_EPHYS,
SPNG_ESPLT_NAME,
SPNG_ESPLT_DUP_NAME,
SPNG_ESPLT_DEPTH,
SPNG_ETIME,
SPNG_EOFFS,
SPNG_EEXIF,
SPNG_EIDAT_TOO_SHORT,
SPNG_EIDAT_STREAM,
SPNG_EZLIB,
SPNG_EFILTER,
SPNG_EBUFSIZ,
SPNG_EIO,
SPNG_EOF,
SPNG_EBUF_SET,
SPNG_EBADSTATE,
SPNG_EFMT,
SPNG_EFLAGS,
SPNG_ECHUNKAVAIL,
SPNG_ENCODE_ONLY,
SPNG_EOI,
SPNG_ENOPLTE,
SPNG_ECHUNK_LIMITS,
SPNG_EZLIB_INIT,
SPNG_ECHUNK_STDLEN,
SPNG_EINTERNAL,
SPNG_ECTXTYPE,
SPNG_ENOSRC,
SPNG_ENODST,
SPNG_EOPSTATE,
SPNG_ENOTFINAL
};
enum spng_text_type
{
SPNG_TEXT = 1,
SPNG_ZTXT = 2,
SPNG_ITXT = 3
};
enum spng_color_type
{
SPNG_COLOR_TYPE_GRAYSCALE = 0,
SPNG_COLOR_TYPE_TRUECOLOR = 2,
SPNG_COLOR_TYPE_INDEXED = 3,
SPNG_COLOR_TYPE_GRAYSCALE_ALPHA = 4,
SPNG_COLOR_TYPE_TRUECOLOR_ALPHA = 6
};
enum spng_filter
{
SPNG_FILTER_NONE = 0,
SPNG_FILTER_SUB = 1,
SPNG_FILTER_UP = 2,
SPNG_FILTER_AVERAGE = 3,
SPNG_FILTER_PAETH = 4
};
enum spng_filter_choice
{
SPNG_DISABLE_FILTERING = 0,
SPNG_FILTER_CHOICE_NONE = 8,
SPNG_FILTER_CHOICE_SUB = 16,
SPNG_FILTER_CHOICE_UP = 32,
SPNG_FILTER_CHOICE_AVG = 64,
SPNG_FILTER_CHOICE_PAETH = 128,
SPNG_FILTER_CHOICE_ALL = (8|16|32|64|128)
};
enum spng_interlace_method
{
SPNG_INTERLACE_NONE = 0,
SPNG_INTERLACE_ADAM7 = 1
};
/* Channels are always in byte-order */
enum spng_format
{
SPNG_FMT_RGBA8 = 1,
SPNG_FMT_RGBA16 = 2,
SPNG_FMT_RGB8 = 4,
/* Partially implemented, see documentation */
SPNG_FMT_GA8 = 16,
SPNG_FMT_GA16 = 32,
SPNG_FMT_G8 = 64,
/* No conversion or scaling */
SPNG_FMT_PNG = 256,
SPNG_FMT_RAW = 512 /* big-endian (everything else is host-endian) */
};
enum spng_ctx_flags
{
SPNG_CTX_IGNORE_ADLER32 = 1, /* Ignore checksum in DEFLATE streams */
SPNG_CTX_ENCODER = 2 /* Create an encoder context */
};
enum spng_decode_flags
{
SPNG_DECODE_USE_TRNS = 1, /* Deprecated */
SPNG_DECODE_USE_GAMA = 2, /* Deprecated */
SPNG_DECODE_USE_SBIT = 8, /* Undocumented */
SPNG_DECODE_TRNS = 1, /* Apply transparency */
SPNG_DECODE_GAMMA = 2, /* Apply gamma correction */
SPNG_DECODE_PROGRESSIVE = 256 /* Initialize for progressive reads */
};
enum spng_crc_action
{
/* Default for critical chunks */
SPNG_CRC_ERROR = 0,
/* Discard chunk, invalid for critical chunks.
Since v0.6.2: default for ancillary chunks */
SPNG_CRC_DISCARD = 1,
/* Ignore and don't calculate checksum.
Since v0.6.2: also ignores checksums in DEFLATE streams */
SPNG_CRC_USE = 2
};
enum spng_encode_flags
{
SPNG_ENCODE_PROGRESSIVE = 1, /* Initialize for progressive writes */
SPNG_ENCODE_FINALIZE = 2 /* Finalize PNG after encoding image */
};
struct spng_ihdr
{
uint32_t width;
uint32_t height;
uint8_t bit_depth;
uint8_t color_type;
uint8_t compression_method;
uint8_t filter_method;
uint8_t interlace_method;
};
struct spng_plte_entry
{
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t alpha; /* Reserved for internal use */
};
struct spng_plte
{
uint32_t n_entries;
struct spng_plte_entry entries[256];
};
struct spng_trns
{
uint16_t gray;
uint16_t red;
uint16_t green;
uint16_t blue;
uint32_t n_type3_entries;
uint8_t type3_alpha[256];
};
struct spng_chrm_int
{
uint32_t white_point_x;
uint32_t white_point_y;
uint32_t red_x;
uint32_t red_y;
uint32_t green_x;
uint32_t green_y;
uint32_t blue_x;
uint32_t blue_y;
};
struct spng_chrm
{
double white_point_x;
double white_point_y;
double red_x;
double red_y;
double green_x;
double green_y;
double blue_x;
double blue_y;
};
struct spng_iccp
{
char profile_name[80];
size_t profile_len;
char *profile;
};
struct spng_sbit
{
uint8_t grayscale_bits;
uint8_t red_bits;
uint8_t green_bits;
uint8_t blue_bits;
uint8_t alpha_bits;
};
struct spng_text
{
char keyword[80];
int type;
size_t length;
char *text;
uint8_t compression_flag; /* iTXt only */
uint8_t compression_method; /* iTXt, ztXt only */
char *language_tag; /* iTXt only */
char *translated_keyword; /* iTXt only */
};
struct spng_bkgd
{
uint16_t gray; /* Only for gray/gray alpha */
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t plte_index; /* Only for indexed color */
};
struct spng_hist
{
uint16_t frequency[256];
};
struct spng_phys
{
uint32_t ppu_x, ppu_y;
uint8_t unit_specifier;
};
struct spng_splt_entry
{
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t alpha;
uint16_t frequency;
};
struct spng_splt
{
char name[80];
uint8_t sample_depth;
uint32_t n_entries;
struct spng_splt_entry *entries;
};
struct spng_time
{
uint16_t year;
uint8_t month;
uint8_t day;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
struct spng_offs
{
int32_t x, y;
uint8_t unit_specifier;
};
struct spng_exif
{
size_t length;
char *data;
};
struct spng_chunk
{
size_t offset;
uint32_t length;
uint8_t type[4];
uint32_t crc;
};
enum spng_location
{
SPNG_AFTER_IHDR = 1,
SPNG_AFTER_PLTE = 2,
SPNG_AFTER_IDAT = 8
};
struct spng_unknown_chunk
{
uint8_t type[4];
size_t length;
void *data;
enum spng_location location;
};
enum spng_option
{
SPNG_KEEP_UNKNOWN_CHUNKS = 1,
SPNG_IMG_COMPRESSION_LEVEL,
SPNG_IMG_WINDOW_BITS,
SPNG_IMG_MEM_LEVEL,
SPNG_IMG_COMPRESSION_STRATEGY,
SPNG_TEXT_COMPRESSION_LEVEL,
SPNG_TEXT_WINDOW_BITS,
SPNG_TEXT_MEM_LEVEL,
SPNG_TEXT_COMPRESSION_STRATEGY,
SPNG_FILTER_CHOICE,
SPNG_CHUNK_COUNT_LIMIT,
SPNG_ENCODE_TO_BUFFER
};
typedef void* SPNG_CDECL spng_malloc_fn(size_t size);
typedef void* SPNG_CDECL spng_realloc_fn(void* ptr, size_t size);
typedef void* SPNG_CDECL spng_calloc_fn(size_t count, size_t size);
typedef void SPNG_CDECL spng_free_fn(void* ptr);
struct spng_alloc
{
spng_malloc_fn *malloc_fn;
spng_realloc_fn *realloc_fn;
spng_calloc_fn *calloc_fn;
spng_free_fn *free_fn;
};
struct spng_row_info
{
uint32_t scanline_idx;
uint32_t row_num; /* deinterlaced row index */
int pass;
uint8_t filter;
};
typedef struct spng_ctx spng_ctx;
typedef int spng_read_fn(spng_ctx *ctx, void *user, void *dest, size_t length);
typedef int spng_write_fn(spng_ctx *ctx, void *user, void *src, size_t length);
typedef int spng_rw_fn(spng_ctx *ctx, void *user, void *dst_src, size_t length);
SPNG_API spng_ctx *spng_ctx_new(int flags);
SPNG_API spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags);
SPNG_API void spng_ctx_free(spng_ctx *ctx);
SPNG_API int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size);
SPNG_API int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user);
SPNG_API int spng_set_png_file(spng_ctx *ctx, FILE *file);
SPNG_API void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error);
SPNG_API int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height);
SPNG_API int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height);
SPNG_API int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_size);
SPNG_API int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_size);
SPNG_API int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary);
SPNG_API int spng_set_option(spng_ctx *ctx, enum spng_option option, int value);
SPNG_API int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value);
SPNG_API int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len);
/* Decode */
SPNG_API int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags);
/* Progressive decode */
SPNG_API int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_row(spng_ctx *ctx, void *out, size_t len);
SPNG_API int spng_decode_chunks(spng_ctx *ctx);
/* Encode/decode */
SPNG_API int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info);
/* Encode */
SPNG_API int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags);
/* Progressive encode */
SPNG_API int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len);
SPNG_API int spng_encode_row(spng_ctx *ctx, const void *row, size_t len);
SPNG_API int spng_encode_chunks(spng_ctx *ctx);
SPNG_API int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_get_gama(spng_ctx *ctx, double *gamma);
SPNG_API int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int);
SPNG_API int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent);
SPNG_API int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text);
SPNG_API int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt);
SPNG_API int spng_get_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks);
/* Official extensions */
SPNG_API int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr);
SPNG_API int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte);
SPNG_API int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns);
SPNG_API int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm);
SPNG_API int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int);
SPNG_API int spng_set_gama(spng_ctx *ctx, double gamma);
SPNG_API int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma);
SPNG_API int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp);
SPNG_API int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit);
SPNG_API int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent);
SPNG_API int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text);
SPNG_API int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd);
SPNG_API int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist);
SPNG_API int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys);
SPNG_API int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt);
SPNG_API int spng_set_time(spng_ctx *ctx, struct spng_time *time);
SPNG_API int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks);
/* Official extensions */
SPNG_API int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs);
SPNG_API int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif);
SPNG_API const char *spng_strerror(int err);
SPNG_API const char *spng_version_string(void);
#ifdef __cplusplus
}
#endif
#endif /* SPNG_H */

View File

@@ -97,10 +97,11 @@ static int tjErrorLine = -1, tjErrorCode = -1;
static int stopOnWarning = 0, bottomUp = 0, noRealloc = 1, precision = 8,
fastUpsample = 0, fastDCT = 0, optimize = 0, progressive = 0, maxScans = 0,
arithmetic = 0, lossless = 0, restartIntervalBlocks = 0,
restartIntervalRows = 0, maxMemory = 0, maxPixels = 0;
restartIntervalRows = 0, maxMemory = 0, maxPixels = 0, noICC = 0;
static char *ext = "ppm";
static int sampleSize, compOnly = 0, decompOnly = 0, doWrite = 1,
pf = TJPF_BGR, quiet = 0, doTile = 0, doYUV = 0, yuvAlign = 1;
static size_t iccSize = 0;
static const char *pixFormatStr[TJ_NUMPF] = {
"RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY", "", "", "", "", "CMYK"
};
@@ -211,11 +212,11 @@ static int decomp(unsigned char **jpegBufs, size_t *jpegSizes, void *dstBuf,
THROW_TJ();
if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1)
THROW_TJ();
if (noICC && tj3Set(handle, TJPARAM_SAVEMARKERS, 0) == -1)
THROW_TJ();
if (IS_CROPPED(cr)) {
if (tj3DecompressHeader(handle, jpegBufs[0], jpegSizes[0]) == -1)
THROW_TJ();
}
if (tj3DecompressHeader(handle, jpegBufs[0], jpegSizes[0]) == -1)
THROW_TJ();
if (tj3SetScalingFactor(handle, sf) == -1)
THROW_TJ();
if (tj3SetCroppingRegion(handle, cr) == -1)
@@ -423,7 +424,7 @@ static int fullTest(tjhandle handle, void *srcBuf, int w, int h, int subsamp,
ntilesh)) == NULL)
THROW_UNIX("allocating JPEG buffer size array");
for (i = 0; i < ntilesw * ntilesh; i++) {
size_t jpegBufSize = tj3JPEGBufSize(tilew, tileh, subsamp);
size_t jpegBufSize = tj3JPEGBufSize(tilew, tileh, subsamp) + iccSize;
if (jpegBufSize == 0)
THROW_TJG();
@@ -917,7 +918,7 @@ static void usage(char *progName)
int i;
printf("USAGE: %s\n", progName);
printf(" <Inputimage (BMP|PPM|PGM)> <Quality or PSV> [options]\n\n");
printf(" <Inputimage (PNG|PPM|PGM|BMP)> <Quality or PSV> [options]\n\n");
printf(" %s\n", progName);
printf(" <Inputimage (JPG)> [options]\n");
@@ -943,6 +944,9 @@ static void usage(char *progName)
printf(" JPEG compression, and lossless transformation [default = no limit]\n");
printf("-maxpixels N\n");
printf(" Input image size limit (in pixels) [default = no limit]\n");
printf("-noicc\n");
printf(" Do not transfer the embedded ICC profile (if any) from PNG input images or\n");
printf(" to PNG output images.\n");
printf("-nowrite\n");
printf(" Do not write reference or output images (improves consistency of benchmark\n");
printf(" results)\n");
@@ -952,6 +956,8 @@ static void usage(char *progName)
printf("-pixelformat cmyk\n");
printf(" Indirectly test YCCK JPEG compression/decompression (use the CMYK pixel\n");
printf(" format for packed-pixel source/destination buffers)\n");
printf("-png\n");
printf(" Use PNG format for output images [default = PPM or PGM]\n");
printf("-precision N\n");
printf(" Use N-bit data precision when compressing [N = 2..16; default = 8; if N is\n");
printf(" not 8 or 12, then -lossless must also be specified] (-precision 12 implies\n");
@@ -1056,7 +1062,8 @@ int main(int argc, char *argv[])
temp = strrchr(argv[1], '.');
if (temp != NULL) {
if (!strcasecmp(temp, ".bmp")) ext = "bmp";
if (!strcasecmp(temp, ".png")) ext = "png";
else if (!strcasecmp(temp, ".bmp")) ext = "bmp";
if (!strcasecmp(temp, ".jpg") || !strcasecmp(temp, ".jpeg"))
decompOnly = 1;
}
@@ -1162,7 +1169,9 @@ int main(int argc, char *argv[])
if (tempi < 0) usage(argv[0]);
maxMemory = tempi;
} else if (MATCH_ARG(argv[i], "-nooutput", 4))
} else if (MATCH_ARG(argv[i], "-noicc", 4))
noICC = 1;
else if (MATCH_ARG(argv[i], "-nooutput", 4))
xformOpt |= TJXOPT_NOOUTPUT;
else if (MATCH_ARG(argv[i], "-nosmooth", 4)) {
printf("Using fastest upsampling algorithm\n\n");
@@ -1194,7 +1203,9 @@ int main(int argc, char *argv[])
pf = TJPF_XRGB;
else
usage(argv[0]);
} else if (MATCH_ARG(argv[i], "-precision", 4) && i < argc - 1) {
} else if (MATCH_ARG(argv[i], "-png", 3))
ext = "png";
else if (MATCH_ARG(argv[i], "-precision", 4) && i < argc - 1) {
int tempi = atoi(argv[++i]);
if (tempi < 2 || tempi > 16)
@@ -1363,6 +1374,8 @@ int main(int argc, char *argv[])
THROW_TJ();
if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1)
THROW_TJ();
if (noICC && tj3Set(handle, TJPARAM_SAVEMARKERS, 0) == -1)
THROW_TJ();
if (precision <= 8) {
if ((srcBuf = tj3LoadImage8(handle, argv[1], &w, 1, &h, &pf)) == NULL)
@@ -1374,6 +1387,8 @@ int main(int argc, char *argv[])
if ((srcBuf = tj3LoadImage16(handle, argv[1], &w, 1, &h, &pf)) == NULL)
THROW_TJ();
}
if (tj3GetICCProfile(handle, NULL, &iccSize) == -1)
THROW_TJ();
temp = strrchr(argv[1], '.');
if (temp != NULL) *temp = '\0';
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2012, 2014-2015, 2017, 2019, 2021-2025 D. R. Commander
* Copyright (C) 2011-2012, 2014-2015, 2017, 2019, 2021-2026 D. R. Commander
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -106,6 +106,8 @@ static void usage(char *programName)
printf(" Memory limit (in megabytes) for intermediate buffers used with progressive\n");
printf(" JPEG compression, lossless JPEG compression, and Huffman table optimization\n");
printf(" [default = no limit]\n");
printf("-noicc\n");
printf(" Do not transfer the embedded ICC profile (if any) from a PNG input image\n");
printf("-precision N\n");
printf(" Create a JPEG image with N-bit data precision [N = 2..16; default = 8; if N\n");
printf(" is not 8 or 12, then -lossless must also be specified] (-precision 12\n");
@@ -149,10 +151,10 @@ int main(int argc, char **argv)
{
int i, retval = 0;
int arithmetic = -1, colorspace = -1, fastDCT = -1, losslessPSV = -1,
losslessPt = -1, maxMemory = -1, optimize = -1, pixelFormat = TJPF_UNKNOWN,
precision = 8, progressive = -1, quality = DEFAULT_QUALITY,
restartIntervalBlocks = -1, restartIntervalRows = -1,
subsamp = DEFAULT_SUBSAMP;
losslessPt = -1, maxMemory = -1, noICC = 0, optimize = -1,
pixelFormat = TJPF_UNKNOWN, precision = 8, progressive = -1,
quality = DEFAULT_QUALITY, restartIntervalBlocks = -1,
restartIntervalRows = -1, subsamp = DEFAULT_SUBSAMP;
char *iccFilename = NULL;
tjhandle tjInstance = NULL;
void *srcBuf = NULL;
@@ -185,8 +187,10 @@ int main(int argc, char **argv)
if (tempi < 0) usage(argv[0]);
maxMemory = tempi;
} else if (MATCH_ARG(argv[i], "-optimize", 2) ||
MATCH_ARG(argv[i], "-optimise", 2))
} else if (MATCH_ARG(argv[i], "-noicc", 4))
noICC = 1;
else if (MATCH_ARG(argv[i], "-optimize", 2) ||
MATCH_ARG(argv[i], "-optimise", 2))
optimize = 1;
else if (MATCH_ARG(argv[i], "-precision", 4) && i < argc - 1) {
int tempi = atoi(argv[++i]);
@@ -276,6 +280,8 @@ int main(int argc, char **argv)
THROW_TJ("setting TJPARAM_RESTARTROWS");
if (maxMemory >= 0 && tj3Set(tjInstance, TJPARAM_MAXMEMORY, maxMemory) < 0)
THROW_TJ("setting TJPARAM_MAXMEMORY");
if (noICC && tj3Set(tjInstance, TJPARAM_SAVEMARKERS, 0) < 0)
THROW_TJ("setting TJPARAM_SAVEMARKERS");
if (precision <= 8) {
if ((srcBuf = tj3LoadImage8(tjInstance, argv[i], &width, 1, &height,

View File

@@ -104,6 +104,9 @@ static void usage(char *programName)
printf("-icc FILE\n");
printf(" Extract the ICC (International Color Consortium) color profile from the\n");
printf(" JPEG image to the specified file\n");
printf("-noicc\n");
printf(" Do not transfer the embedded ICC profile (if any) from the JPEG image to a\n");
printf(" PNG output image\n");
printf("-strict\n");
printf(" Treat all warnings as fatal; abort immediately if incomplete or corrupt\n");
printf(" data is encountered in the JPEG image, rather than trying to salvage the\n");
@@ -160,8 +163,8 @@ int main(int argc, char **argv)
{
int i, retval = 0;
int colorspace, fastDCT = -1, fastUpsample = -1, jpegPrecision, lossless,
maxMemory = -1, maxScans = -1, pixelFormat = TJPF_UNKNOWN, precision = -1,
stopOnWarning = -1, subsamp;
maxMemory = -1, maxScans = -1, noICC = 0, pixelFormat = TJPF_UNKNOWN,
precision = -1, stopOnWarning = -1, subsamp;
tjregion croppingRegion = TJUNCROPPED;
tjscalingfactor scalingFactor = TJUNSCALED;
char *iccFilename = NULL;
@@ -208,7 +211,9 @@ int main(int argc, char **argv)
if (tempi < 0) usage(argv[0]);
maxMemory = tempi;
} else if (MATCH_ARG(argv[i], "-nosmooth", 2))
} else if (MATCH_ARG(argv[i], "-noicc", 4))
noICC = 1;
else if (MATCH_ARG(argv[i], "-nosmooth", 2))
fastUpsample = 1;
else if (MATCH_ARG(argv[i], "-precision", 4) && i < argc - 1) {
int tempi = atoi(argv[++i]);
@@ -258,6 +263,8 @@ int main(int argc, char **argv)
THROW_TJ("setting TJPARAM_SCANLIMIT");
if (maxMemory >= 0 && tj3Set(tjInstance, TJPARAM_MAXMEMORY, maxMemory) < 0)
THROW_TJ("setting TJPARAM_MAXMEMORY");
if (noICC && tj3Set(tjInstance, TJPARAM_SAVEMARKERS, 0) < 0)
THROW_TJ("setting TJPARAM_SAVEMARKERS");
if ((jpegFile = fopen(argv[i++], "rb")) == NULL)
THROW_UNIX("opening input file");

View File

@@ -1002,15 +1002,19 @@ static void cmyk_to_rgb(int c, int m, int y, int k, int *r, int *g, int *b,
}
static int cmpBitmap(void *buf, int width, int pitch, int height, int pf,
int bottomUp, int gray2rgb, int targetPrecision)
int bottomUp, int gray2rgb, int targetPrecision,
const char *ext)
{
int roffset = tjRedOffset[pf];
int goffset = tjGreenOffset[pf];
int boffset = tjBlueOffset[pf];
int aoffset = tjAlphaOffset[pf];
int ps = tjPixelSize[pf];
int i, j;
int targetMaxSample = (1 << targetPrecision) - 1;
int targetMaxSample, i, j;
if (!strcasecmp(ext, "bmp"))
targetPrecision = 8;
targetMaxSample = (1 << targetPrecision) - 1;
for (j = 0; j < height; j++) {
int row = bottomUp ? height - j - 1 : j;
@@ -1024,12 +1028,39 @@ static int cmpBitmap(void *buf, int width, int pitch, int height, int pf,
if (precision != targetPrecision) {
long halfMaxSample = maxSample / 2;
r = (int)((r * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
/* The expected results are slightly different with PNG files, because
* the samples are scaled up to 8 or 16 bits of data precision by the
* PNG writer and scaled down to the target data precision by the
* reader.
*/
if (!strcasecmp(ext, "png")) {
if (precision <= 8) {
r = (int)((r * 255 + halfMaxSample) / maxSample);
r = (int)((r * ((1 << targetPrecision) - 1) + 127) / 255);
g = (int)((g * 255 + halfMaxSample) / maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + 127) / 255);
b = (int)((b * 255 + halfMaxSample) / maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + 127) / 255);
} else {
unsigned int rtemp =
(unsigned int)((r * 65535U + halfMaxSample) / maxSample);
unsigned int gtemp =
(unsigned int)((g * 65535U + halfMaxSample) / maxSample);
unsigned int btemp =
(unsigned int)((b * 65535U + halfMaxSample) / maxSample);
r = (int)((rtemp * ((1 << targetPrecision) - 1) + 32767) / 65535);
g = (int)((gtemp * ((1 << targetPrecision) - 1) + 32767) / 65535);
b = (int)((btemp * ((1 << targetPrecision) - 1) + 32767) / 65535);
}
} else {
r = (int)((r * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
g = (int)((g * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
b = (int)((b * ((1 << targetPrecision) - 1) + halfMaxSample) /
maxSample);
}
}
if (pf == TJPF_GRAY) {
@@ -1083,6 +1114,26 @@ static int doBmpTest(const char *ext, int width, int align, int height, int pf,
loadHeight = 0, retval = 0, pixelFormat = pf;
void *buf = NULL;
char *md5ref;
char *colorPNGRefs[17] = {
"", "", "d973fcebcb785e9286d2b00f924a2bfc",
"76426aa13d42e2ba67a8ab84f93806e4", "9895df84ae7e67b234cbfb38028d514e",
"381fc9cee6d8f4f013907154c0a3d4a4", "e44dd82241dbcf822ff622e51e17d7a3",
"a6a143a8c16896368cee3b48e29f7e04", "1d9f6c50b5f6acbb882bf975ee85d2ac",
"6e3521e58ccd649001b7f135c9a0d77c", "8498b048f3a42cace76f199831036808",
"270933f0e53a513a331fc06c4d99fced", "14987f4410c740d99320a30814dcee00",
"b0f97624504d6f208a691063d2e83f90", "7baefad230a3fbad7447568d29ad72ad",
"7b5fa7dd6184319f15e02ee575d361e1", "39d5bac5fa6e9413ebcb1fe63a7f4750"
};
char *grayPNGRefs[17] = {
"", "", "35bd865b7b3f5c52baa4431d1722c68e",
"a80e6ab4afa043b680e7c61eeba1c49b", "d373a735273e0fd359aa7a43d92883f7",
"e414230904deffffb33e723c10a92150", "ce4426862b998ad1ca18d6d4dfcf8ed2",
"9cb84538b47ff164f5786d8662d39c62", "a1d57ae8785cf85abac187f274452655",
"3134b92be88363989d2e197c7aaa8876", "f7baac93d23bf38bcfbca29eff107799",
"839b9a975ddfb622caaef4496510c3f9", "e1d6704888c8a0d7fa234d9d625ea0eb",
"4c8d7484b3c4a5d195bf19996b350a9e", "33699b2ef9fcce812f26d7272cd98b7c",
"b9c85b94a2c109830f00c203c900f3d9", "3e31a40843885e839b27cfddb69b26f8"
};
char *colorPPMRefs[17] = {
"", "", "0bad09d9ef38eda566848fb7c0b7fd0a",
"7ef2c87261a8bd6838303b541563cf27", "28a37cf9636ff6bb9ed6b206bdac60db",
@@ -1114,7 +1165,10 @@ static int doBmpTest(const char *ext, int width, int align, int height, int pf,
md5ref = (pf == TJPF_GRAY ? "51976530acf75f02beddf5d21149101d" :
"6d659071b9bfcdee2def22cb58ddadca");
maxTargetPrecision = 8;
} else
} else if (!strcasecmp(ext, "png"))
md5ref = (pf == TJPF_GRAY ? grayPNGRefs[precision] :
colorPNGRefs[precision]);
else
md5ref = (pf == TJPF_GRAY ? grayPPMRefs[precision] :
colorPPMRefs[precision]);
@@ -1166,8 +1220,8 @@ static int doBmpTest(const char *ext, int width, int align, int height, int pf,
retval = -1; goto bailout;
}
pitch = PAD(width * tjPixelSize[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, 0,
!strcasecmp(ext, "bmp") ? 8 : targetPrecision)) {
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, 0, targetPrecision,
ext)) {
printf("\n Pixel data in %s is bogus\n", filename);
printf(" (target data precision = %d)\n", targetPrecision);
retval = -1; goto bailout;
@@ -1191,7 +1245,7 @@ static int doBmpTest(const char *ext, int width, int align, int height, int pf,
}
pitch = PAD(width * tjPixelSize[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, 1,
!strcasecmp(ext, "bmp") ? 8 : targetPrecision)) {
targetPrecision, ext)) {
printf("\n Converting %s to RGB failed\n", filename);
printf(" (target data precision = %d)\n", targetPrecision);
retval = -1; goto bailout;
@@ -1214,7 +1268,7 @@ static int doBmpTest(const char *ext, int width, int align, int height, int pf,
}
pitch = PAD(width * tjPixelSize[pf], align);
if (!cmpBitmap(buf, width, pitch, height, pf, bottomUp, 1,
!strcasecmp(ext, "bmp") ? 8 : targetPrecision)) {
targetPrecision, ext)) {
printf("\n Converting %s to CMYK failed\n", filename);
printf(" (target data precision = %d)\n", targetPrecision);
retval = -1; goto bailout;
@@ -1274,6 +1328,12 @@ static int bmpTest(void)
printf("OK.\n");
}
printf("%s Top-Down PNG (row alignment = %d samples) ... ",
pixFormatStr[format], align);
if (doBmpTest("png", width, align, height, format, 0) == -1)
return -1;
printf("OK.\n");
printf("%s Top-Down PPM (row alignment = %d samples) ... ",
pixFormatStr[format], align);
if (doBmpTest("ppm", width, align, height, format, 0) == -1)
@@ -1288,6 +1348,12 @@ static int bmpTest(void)
printf("OK.\n");
}
printf("%s Bottom-Up PNG (row alignment = %d samples) ... ",
pixFormatStr[format], align);
if (doBmpTest("png", width, align, height, format, 1) == -1)
return -1;
printf("OK.\n");
printf("%s Bottom-Up PPM (row alignment = %d samples) ... ",
pixFormatStr[format], align);
if (doBmpTest("ppm", width, align, height, format, 1) == -1)

View File

@@ -33,6 +33,8 @@
#define _JSAMPLE JSAMPLE
#define _JSAMPROW JSAMPROW
#define _buffer buffer
#define _jinit_read_png jinit_read_png
#define _jinit_write_png jinit_write_png
#define _jinit_read_ppm jinit_read_ppm
#define _jinit_write_ppm jinit_write_ppm
#define _jpeg_crop_scanline jpeg_crop_scanline
@@ -43,6 +45,8 @@
#define _JSAMPLE J12SAMPLE
#define _JSAMPROW J12SAMPROW
#define _buffer buffer12
#define _jinit_read_png j12init_read_png
#define _jinit_write_png j12init_write_png
#define _jinit_read_ppm j12init_read_ppm
#define _jinit_write_ppm j12init_write_ppm
#define _jpeg_crop_scanline jpeg12_crop_scanline
@@ -53,6 +57,8 @@
#define _JSAMPLE J16SAMPLE
#define _JSAMPROW J16SAMPROW
#define _buffer buffer16
#define _jinit_read_png j16init_read_png
#define _jinit_write_png j16init_write_png
#define _jinit_read_ppm j16init_read_ppm
#define _jinit_write_ppm j16init_write_ppm
#define _jpeg_read_scanlines jpeg16_read_scanlines
@@ -347,6 +353,17 @@ _JSAMPLE *GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE)
if ((src = jinit_read_bmp(cinfo, FALSE)) == NULL)
THROW("Could not initialize bitmap loader");
invert = !this->bottomUp;
} else if (tempc == 0x89) {
#if BITS_IN_JSAMPLE == 8
if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE)
#else
if (this->precision >= BITS_IN_JSAMPLE - 3 &&
this->precision <= BITS_IN_JSAMPLE)
#endif
cinfo->data_precision = this->precision;
if ((src = _jinit_read_png(cinfo)) == NULL)
THROW("Could not initialize PNG loader");
invert = this->bottomUp;
} else if (tempc == 'P') {
#if BITS_IN_JSAMPLE == 8
if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE)
@@ -373,6 +390,14 @@ _JSAMPLE *GET_NAME(_tj3LoadImageFromFileHandle, BITS_IN_JSAMPLE)
this->yDensity = cinfo->Y_density;
this->densityUnits = cinfo->density_unit;
}
} else if (tempc == 0x89 && (this->init & COMPRESS) &&
(this->saveMarkers == 2 || this->saveMarkers == 4)) {
JOCTET *iccBuf = NULL;
unsigned int iccLen = 0;
if ((*src->read_icc_profile) (cinfo, src, &iccBuf, &iccLen) && iccBuf &&
iccLen)
tj3SetICCProfile(handle, (unsigned char *)iccBuf, iccLen);
}
(*cinfo->mem->realize_virt_arrays) ((j_common_ptr)cinfo);
@@ -546,6 +571,28 @@ DLLEXPORT int GET_NAME(tj3SaveImage, BITS_IN_JSAMPLE)
dinfo->X_density = (UINT16)this->xDensity;
dinfo->Y_density = (UINT16)this->yDensity;
dinfo->density_unit = (UINT8)this->densityUnits;
} else if (ptr && !strcasecmp(ptr, ".png")) {
#if BITS_IN_JSAMPLE == 8
if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE)
#else
if (this->precision >= BITS_IN_JSAMPLE - 3 &&
this->precision <= BITS_IN_JSAMPLE)
#endif
dinfo->data_precision = this->precision;
if ((dst = _jinit_write_png(dinfo)) == NULL)
THROW("Could not initialize PNG writer");
invert = this->bottomUp;
if ((this->init & DECOMPRESS) && this->decompICCBuf &&
this->decompICCSize) {
unsigned char *iccBuf = (unsigned char *)malloc(this->decompICCSize);
if (!iccBuf)
THROW("Memory allocation failure");
memcpy(iccBuf, this->decompICCBuf, this->decompICCSize);
(*dst->write_icc_profile) (dinfo, dst, iccBuf,
(unsigned int)this->decompICCSize);
}
} else {
#if BITS_IN_JSAMPLE == 8
if (this->precision >= 2 && this->precision <= BITS_IN_JSAMPLE)
@@ -603,6 +650,8 @@ bailout:
#undef _JSAMPLE
#undef _JSAMPROW
#undef _buffer
#undef _jinit_read_png
#undef _jinit_write_png
#undef _jinit_read_ppm
#undef _jinit_write_ppm
#undef _jpeg_crop_scanline

View File

@@ -139,8 +139,8 @@ typedef struct _tjinstance {
int maxMemory;
int maxPixels;
int saveMarkers;
unsigned char *iccBuf, *tempICCBuf;
size_t iccSize, tempICCSize;
unsigned char *iccBuf, *decompICCBuf;
size_t iccSize, decompICCSize;
} tjinstance;
static tjhandle _tjInitCompress(tjinstance *this);
@@ -593,7 +593,7 @@ DLLEXPORT void tj3Destroy(tjhandle handle)
if (this->init & COMPRESS) jpeg_destroy_compress(cinfo);
if (this->init & DECOMPRESS) jpeg_destroy_decompress(dinfo);
free(this->iccBuf);
free(this->tempICCBuf);
free(this->decompICCBuf);
free(this);
}
@@ -790,8 +790,6 @@ DLLEXPORT int tj3Set(tjhandle handle, int param, int value)
SET_PARAM(maxPixels, 0, -1);
break;
case TJPARAM_SAVEMARKERS:
if (!(this->init & DECOMPRESS))
THROW("TJPARAM_SAVEMARKERS is not applicable to compression instances.");
SET_PARAM(saveMarkers, 0, 4);
break;
default:
@@ -1852,9 +1850,9 @@ DLLEXPORT int tj3DecompressHeader(tjhandle handle,
if (this->saveMarkers == 2 || this->saveMarkers == 4) {
if (jpeg_read_icc_profile(dinfo, &iccPtr, &iccLen)) {
free(this->tempICCBuf);
this->tempICCBuf = iccPtr;
this->tempICCSize = (size_t)iccLen;
free(this->decompICCBuf);
this->decompICCBuf = iccPtr;
this->decompICCSize = (size_t)iccLen;
}
}
@@ -1930,25 +1928,31 @@ DLLEXPORT int tj3GetICCProfile(tjhandle handle, unsigned char **iccBuf,
int retval = 0;
GET_TJINSTANCE(handle, -1);
if ((this->init & DECOMPRESS) == 0)
THROW("Instance has not been initialized for decompression");
if (iccSize == NULL)
THROW("Invalid argument");
if (!this->tempICCBuf || !this->tempICCSize) {
if (iccBuf) *iccBuf = NULL;
*iccSize = 0;
this->jerr.warning = TRUE;
THROW("No ICC profile data has been extracted");
}
*iccSize = this->tempICCSize;
if (this->init & DECOMPRESS) {
if (!this->decompICCBuf || !this->decompICCSize) {
if (iccBuf) *iccBuf = NULL;
*iccSize = 0;
this->jerr.warning = TRUE;
THROW("No ICC profile data has been extracted");
}
*iccSize = this->decompICCSize;
} else
*iccSize = this->iccSize;
if (iccBuf == NULL)
return 0;
*iccBuf = this->tempICCBuf;
this->tempICCBuf = NULL;
this->tempICCSize = 0;
if (*iccSize) {
if ((*iccBuf = (unsigned char *)malloc(*iccSize)) == NULL)
THROW("Memory allocation failure");
if (this->init & DECOMPRESS)
memcpy(*iccBuf, this->decompICCBuf, *iccSize);
else
memcpy(*iccBuf, this->iccBuf, *iccSize);
} else
*iccBuf = NULL;
bailout:
return retval;
@@ -2857,7 +2861,7 @@ DLLEXPORT size_t tj3TransformBufSize(tjhandle handle,
retval = tj3JPEGBufSize(dstWidth, dstHeight, dstSubsamp);
if ((this->saveMarkers == 2 || this->saveMarkers == 4) &&
!(transform->options & TJXOPT_COPYNONE))
retval += this->tempICCSize;
retval += this->decompICCSize;
else
retval += this->iccSize;

View File

@@ -576,18 +576,18 @@ enum TJPARAM {
*
* The JPEG image uses (decompression) or will use (lossless compression) the
* specified number of bits per sample. This parameter also specifies the
* target data precision when loading a PBMPLUS file with #tj3LoadImage8(),
* #tj3LoadImage12(), or #tj3LoadImage16() and the source data precision when
* saving a PBMPLUS file with #tj3SaveImage8(), #tj3SaveImage12(), or
* #tj3SaveImage16().
* target data precision when loading a PNG or PBMPLUS file with
* #tj3LoadImage8(), #tj3LoadImage12(), or #tj3LoadImage16() and the source
* data precision when saving a PNG or PBMPLUS file with #tj3SaveImage8(),
* #tj3SaveImage12(), or #tj3SaveImage16().
*
* The data precision is the number of bits in the maximum sample value,
* which may not be the same as the width of the data type used to store the
* sample.
*
* **Value**
* - `8` or `12` for lossy JPEG images; `2` to `16` for lossless JPEG and
* PBMPLUS images
* - `8` or `12` for lossy JPEG images; `2` to `16` for lossless JPEG, PNG,
* and PBMPLUS images
*
* 12-bit JPEG data precision implies #TJPARAM_OPTIMIZE unless
* #TJPARAM_ARITHMETIC is set.
@@ -923,7 +923,8 @@ enum TJPARAM {
*/
TJPARAM_MAXPIXELS,
/**
* Marker copying behavior [decompression, lossless transformation]
* Marker copying behavior [decompression, lossless transformation,
* packed-pixel image I/O]
*
* **Value [lossless transformation]**
* - `0` Do not copy any extra markers (including comments, JFIF thumbnails,
@@ -940,11 +941,22 @@ enum TJPARAM {
*
* #TJXOPT_COPYNONE overrides this parameter for a particular transform.
* This parameter overrides any ICC profile that was previously associated
* with the TurboJPEG instance using #tj3SetICCProfile().
* with the TurboJPEG instance using #tj3SetICCProfile(), #tj3LoadImage8(),
* #tj3LoadImage12(), or #tj3LoadImage16().
*
* When decompressing, #tj3DecompressHeader() extracts the ICC profile from a
* JPEG image if this parameter is set to `2` or `4`. #tj3GetICCProfile()
* can then be used to retrieve the profile.
* If this parameter is set to `2` or `4`:
* - When decompressing, #tj3DecompressHeader() extracts the ICC profile from
* a JPEG image. #tj3GetICCProfile() can then be used to retrieve the
* profile.
* - When loading a PNG image using a TurboJPEG compression instance,
* #tj3LoadImage8(), #tj3LoadImage12(), and #tj3LoadImage16() extract the
* ICC profile from the PNG image and associate the profile with the
* TurboJPEG instance. #tj3GetICCProfile() can then be used to retrieve
* the profile.
* - When saving a PNG image using a TurboJPEG decompression instance,
* #tj3SaveImage8(), #tj3SaveImage12(), and #tj3SaveImage16() transfer the
* ICC profile that was previously extracted from a JPEG image to the PNG
* image.
*/
TJPARAM_SAVEMARKERS
};
@@ -1498,8 +1510,9 @@ DLLEXPORT int tj3SetICCProfile(tjhandle handle, unsigned char *iccBuf,
* -# pre-allocate the buffer to a "worst case" size determined by calling
* #tj3JPEGBufSize() and adding the return value to the size of the ICC profile
* (if any) that was previously associated with the TurboJPEG instance (see
* #tj3SetICCProfile().) This should ensure that the buffer never has to be
* re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.)
* #tj3SetICCProfile() and #tj3GetICCProfile().) This should ensure that the
* buffer never has to be re-allocated. (Setting #TJPARAM_NOREALLOC guarantees
* that it won't be.)
* .
* Unless you have set #TJPARAM_NOREALLOC, you should always check `*jpegBuf`
* upon return from this function, as it may have changed.
@@ -1558,8 +1571,9 @@ DLLEXPORT int tj3Compress8(tjhandle handle, const unsigned char *srcBuf,
* -# pre-allocate the buffer to a "worst case" size determined by calling
* #tj3JPEGBufSize() and adding the return value to the size of the ICC profile
* (if any) that was previously associated with the TurboJPEG instance (see
* #tj3SetICCProfile().) This should ensure that the buffer never has to be
* re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.)
* #tj3SetICCProfile() and #tj3GetICCProfile().) This should ensure that the
* buffer never has to be re-allocated. (Setting #TJPARAM_NOREALLOC guarantees
* that it won't be.)
* .
* Unless you have set #TJPARAM_NOREALLOC, you should always check `*jpegBuf`
* upon return from this function, as it may have changed.
@@ -1619,8 +1633,9 @@ DLLEXPORT int tj3Compress12(tjhandle handle, const short *srcBuf, int width,
* -# pre-allocate the buffer to a "worst case" size determined by calling
* #tj3JPEGBufSize() and adding the return value to the size of the ICC profile
* (if any) that was previously associated with the TurboJPEG instance (see
* #tj3SetICCProfile().) This should ensure that the buffer never has to be
* re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.)
* #tj3SetICCProfile() and #tj3GetICCProfile().) This should ensure that the
* buffer never has to be re-allocated. (Setting #TJPARAM_NOREALLOC guarantees
* that it won't be.)
* .
* Unless you have set #TJPARAM_NOREALLOC, you should always check `*jpegBuf`
* upon return from this function, as it may have changed.
@@ -1684,8 +1699,9 @@ DLLEXPORT int tj3Compress16(tjhandle handle, const unsigned short *srcBuf,
* -# pre-allocate the buffer to a "worst case" size determined by calling
* #tj3JPEGBufSize() and adding the return value to the size of the ICC profile
* (if any) that was previously associated with the TurboJPEG instance (see
* #tj3SetICCProfile().) This should ensure that the buffer never has to be
* re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.)
* #tj3SetICCProfile() and #tj3GetICCProfile().) This should ensure that the
* buffer never has to be re-allocated. (Setting #TJPARAM_NOREALLOC guarantees
* that it won't be.)
* .
* Unless you have set #TJPARAM_NOREALLOC, you should always check `*jpegBuf`
* upon return from this function, as it may have changed.
@@ -1746,8 +1762,9 @@ DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle,
* -# pre-allocate the buffer to a "worst case" size determined by calling
* #tj3JPEGBufSize() and adding the return value to the size of the ICC profile
* (if any) that was previously associated with the TurboJPEG instance (see
* #tj3SetICCProfile().) This should ensure that the buffer never has to be
* re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.)
* #tj3SetICCProfile() and #tj3GetICCProfile().) This should ensure that the
* buffer never has to be re-allocated. (Setting #TJPARAM_NOREALLOC guarantees
* that it won't be.)
* .
* Unless you have set #TJPARAM_NOREALLOC, you should always check `*jpegBuf`
* upon return from this function, as it may have changed.
@@ -1906,15 +1923,18 @@ DLLEXPORT int tj3DecompressHeader(tjhandle handle,
/**
* Retrieve the ICC (International Color Consortium) color management profile
* (if any) that was previously extracted from a JPEG image.
* (if any) that was previously extracted from a JPEG image or associated with
* a TurboJPEG compression instance.
*
* @note To extract the ICC profile from a JPEG image, call
* #tj3DecompressHeader() with #TJPARAM_SAVEMARKERS set to `2` or `4`. Once
* the ICC profile is retrieved, it must be re-extracted before it can be
* retrieved again.
* #tj3DecompressHeader() with #TJPARAM_SAVEMARKERS set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance that has been initialized for
* decompression
* @note To associate an ICC profile with a TurboJPEG compression instance,
* call #tj3SetICCProfile() or use #tj3LoadImage8(), #tj3LoadImage12(), or
* #tj3LoadImage16() to load a PNG image with #TJPARAM_SAVEMARKERS set to `2`
* or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param iccBuf address of a pointer to a byte buffer. Upon return:
* - If `iccBuf` is not NULL and there is an ICC profile to retrieve, then
@@ -2279,10 +2299,10 @@ DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf,
* cropping, transposition of the width and height (which affects the
* destination image dimensions and level of chrominance subsampling),
* grayscale conversion, and the ICC profile (if any) that was previously
* associated with the TurboJPEG instance (see #tj3SetICCProfile()) or
* extracted from the source image (see #tj3GetICCProfile() and
* #TJPARAM_SAVEMARKERS.) The JPEG header must be read (see
* tj3DecompressHeader()) prior to calling this function.
* associated with the TurboJPEG instance or extracted from the source image
* (see #tj3SetICCProfile(), #tj3GetICCProfile(), and #TJPARAM_SAVEMARKERS.)
* The JPEG header must be read (see #tj3DecompressHeader()) prior to calling
* this function.
*
* @param handle handle to a TurboJPEG instance that has been initialized for
* lossless transformation
@@ -2365,15 +2385,20 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf,
* Load a packed-pixel image with 2 to 8 bits of data precision per sample from
* disk into memory.
*
* @note If loading a PNG image using a TurboJPEG compression instance, the
* ICC profile (if any) embedded in the PNG image is extracted and associated
* with the TurboJPEG instance if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file containing a packed-pixel image in Windows
* BMP or PBMPLUS (PPM/PGM) format. Windows BMP files require 8-bit-per-sample
* data precision. When loading a PBMPLUS file, the target data precision
* (from 2 to 8 bits per sample) can be specified using #TJPARAM_PRECISION and
* defaults to 8 if #TJPARAM_PRECISION is unset or out of range. If the data
* precision of the PBMPLUS file does not match the target data precision, then
* upconverting or downconverting will be performed.
* @param filename name of a file containing a packed-pixel image in true color
* PNG, grayscale PNG, PBMPLUS (PPM/PGM), or Windows BMP format. Windows BMP
* files require 8-bit-per-sample data precision. When loading a PNG or
* PBMPLUS file, the target data precision (from 2 to 8 bits per sample) can be
* specified using #TJPARAM_PRECISION and defaults to 8 if #TJPARAM_PRECISION
* is unset or out of range. If the data precision of the PNG or PBMPLUS file
* does not match the target data precision, then upconverting or
* downconverting will be performed.
*
* @param width pointer to an integer variable that will receive the width (in
* pixels) of the packed-pixel image
@@ -2417,14 +2442,18 @@ DLLEXPORT unsigned char *tj3LoadImage8(tjhandle handle, const char *filename,
* Load a packed-pixel image with 9 to 12 bits of data precision per sample
* from disk into memory.
*
* @note If loading a PNG image using a TurboJPEG compression instance, the
* ICC profile (if any) embedded in the PNG image is extracted and associated
* with the TurboJPEG instance if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file containing a packed-pixel image in PBMPLUS
* (PPM/PGM) format. The target data precision (from 9 to 12 bits per sample)
* can be specified using #TJPARAM_PRECISION and defaults to 12 if
* #TJPARAM_PRECISION is unset or out of range. If the data precision of the
* PBMPLUS file does not match the target data precision, then upconverting or
* downconverting will be performed.
* @param filename name of a file containing a packed-pixel image in true color
* PNG, grayscale PNG, or PBMPLUS (PPM/PGM) format. The target data precision
* (from 9 to 12 bits per sample) can be specified using #TJPARAM_PRECISION and
* defaults to 12 if #TJPARAM_PRECISION is unset or out of range. If the data
* precision of the PNG or PBMPLUS file does not match the target data
* precision, then upconverting or downconverting will be performed.
*
* @param width pointer to an integer variable that will receive the width (in
* pixels) of the packed-pixel image
@@ -2467,14 +2496,18 @@ DLLEXPORT short *tj3LoadImage12(tjhandle handle, const char *filename,
* Load a packed-pixel image with 13 to 16 bits of data precision per sample
* from disk into memory.
*
* @note If loading a PNG image using a TurboJPEG compression instance, the
* ICC profile (if any) embedded in the PNG image is extracted and associated
* with the TurboJPEG instance if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file containing a packed-pixel image in PBMPLUS
* (PPM/PGM) format. The target data precision (from 13 to 16 bits per sample)
* can be specified using #TJPARAM_PRECISION and defaults to 16 if
* #TJPARAM_PRECISION is unset or out of range. If the data precision of the
* PBMPLUS file does not match the target data precision, then upconverting or
* downconverting will be performed.
* @param filename name of a file containing a packed-pixel image in true color
* PNG, grayscale PNG, or PBMPLUS (PPM/PGM) format. The target data precision
* (from 13 to 16 bits per sample) can be specified using #TJPARAM_PRECISION
* and defaults to 16 if #TJPARAM_PRECISION is unset or out of range. If the
* data precision of the PNG or PBMPLUS file does not match the target data
* precision, then upconverting or downconverting will be performed.
*
* @param width pointer to an integer variable that will receive the width (in
* pixels) of the packed-pixel image
@@ -2518,14 +2551,19 @@ DLLEXPORT unsigned short *tj3LoadImage16(tjhandle handle, const char *filename,
* Save a packed-pixel image with 2 to 8 bits of data precision per sample from
* memory to disk.
*
* @note If saving a PNG image using a TurboJPEG decompression instance, the
* ICC profile (if any) that was previously extracted from a JPEG image is
* transferred to the PNG image if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file to which to save the packed-pixel image. The
* image will be stored in Windows BMP or PBMPLUS (PPM/PGM) format, depending
* on the file extension. Windows BMP files require 8-bit-per-sample data
* precision. When saving a PBMPLUS file, the source data precision (from 2 to
* 8 bits per sample) can be specified using #TJPARAM_PRECISION and defaults to
* 8 if #TJPARAM_PRECISION is unset or out of range.
* image will be stored in PNG, PBMPLUS (PPM/PGM), or Windows BMP format,
* depending on the file extension. Windows BMP files require 8-bit-per-sample
* data precision. When saving a PNG or PBMPLUS file, the source data
* precision (from 2 to 8 bits per sample) can be specified using
* #TJPARAM_PRECISION and defaults to 8 if #TJPARAM_PRECISION is unset or out
* of range.
*
* @param buffer pointer to a buffer containing a packed-pixel RGB, grayscale,
* or CMYK image to be saved
@@ -2540,12 +2578,13 @@ DLLEXPORT unsigned short *tj3LoadImage16(tjhandle handle, const char *filename,
*
* @param pixelFormat pixel format of the packed-pixel image (see @ref TJPF
* "Pixel formats".) If this parameter is set to @ref TJPF_GRAY, then the
* image will be stored in PGM or 8-bit-per-pixel (indexed color) BMP format.
* Otherwise, the image will be stored in PPM or 24-bit-per-pixel BMP format.
* If this parameter is set to @ref TJPF_CMYK, then the CMYK pixels will be
* converted to RGB using a quick & dirty algorithm that is suitable only for
* testing purposes. (Proper conversion between CMYK and other formats
* requires a color management system.)
* image will be stored in grayscale PNG, PGM, or 8-bit-per-pixel (indexed
* color) BMP format. Otherwise, the image will be stored in true color PNG,
* PPM, or 24-bit-per-pixel BMP format. If this parameter is set to
* @ref TJPF_CMYK, then the CMYK pixels will be converted to RGB using a quick
* & dirty algorithm that is suitable only for testing purposes. (Proper
* conversion between CMYK and other formats requires a color management
* system.)
*
* @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr().)
*/
@@ -2557,12 +2596,17 @@ DLLEXPORT int tj3SaveImage8(tjhandle handle, const char *filename,
* Save a packed-pixel image with 9 to 12 bits of data precision per sample
* from memory to disk.
*
* @note If saving a PNG image using a TurboJPEG decompression instance, the
* ICC profile (if any) that was previously extracted from a JPEG image is
* transferred to the PNG image if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file to which to save the packed-pixel image,
* which will be stored in PBMPLUS (PPM/PGM) format. The source data precision
* (from 9 to 12 bits per sample) can be specified using #TJPARAM_PRECISION and
* defaults to 12 if #TJPARAM_PRECISION is unset or out of range.
* which will be stored in PNG or PBMPLUS (PPM/PGM) format. The source data
* precision (from 9 to 12 bits per sample) can be specified using
* #TJPARAM_PRECISION and defaults to 12 if #TJPARAM_PRECISION is unset or out
* of range.
*
* @param buffer pointer to a buffer containing a packed-pixel RGB, grayscale,
* or CMYK image to be saved
@@ -2577,11 +2621,12 @@ DLLEXPORT int tj3SaveImage8(tjhandle handle, const char *filename,
*
* @param pixelFormat pixel format of the packed-pixel image (see @ref TJPF
* "Pixel formats".) If this parameter is set to @ref TJPF_GRAY, then the
* image will be stored in PGM format. Otherwise, the image will be stored in
* PPM format. If this parameter is set to @ref TJPF_CMYK, then the CMYK
* pixels will be converted to RGB using a quick & dirty algorithm that is
* suitable only for testing purposes. (Proper conversion between CMYK and
* other formats requires a color management system.)
* image will be stored in PGM or grayscale PNG format. Otherwise, the image
* will be stored in PPM or true color PNG format. If this parameter is set to
* @ref TJPF_CMYK, then the CMYK pixels will be converted to RGB using a quick
* & dirty algorithm that is suitable only for testing purposes. (Proper
* conversion between CMYK and other formats requires a color management
* system.)
*
* @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr().)
*/
@@ -2593,12 +2638,17 @@ DLLEXPORT int tj3SaveImage12(tjhandle handle, const char *filename,
* Save a packed-pixel image with 13 to 16 bits of data precision per sample
* from memory to disk.
*
* @note If saving a PNG image using a TurboJPEG decompression instance, the
* ICC profile (if any) that was previously extracted from a JPEG image is
* transferred to the PNG image if #TJPARAM_SAVEMARKERS is set to `2` or `4`.
*
* @param handle handle to a TurboJPEG instance
*
* @param filename name of a file to which to save the packed-pixel image,
* which will be stored in PBMPLUS (PPM/PGM) format. The source data precision
* (from 13 to 16 bits per sample) can be specified using #TJPARAM_PRECISION
* and defaults to 16 if #TJPARAM_PRECISION is unset or out of range.
* which will be stored in PNG or PBMPLUS (PPM/PGM) format. The source data
* precision (from 13 to 16 bits per sample) can be specified using
* #TJPARAM_PRECISION and defaults to 16 if #TJPARAM_PRECISION is unset or out
* of range.
*
* @param buffer pointer to a buffer containing a packed-pixel RGB, grayscale,
* or CMYK image to be saved
@@ -2613,11 +2663,12 @@ DLLEXPORT int tj3SaveImage12(tjhandle handle, const char *filename,
*
* @param pixelFormat pixel format of the packed-pixel image (see @ref TJPF
* "Pixel formats".) If this parameter is set to @ref TJPF_GRAY, then the
* image will be stored in PGM format. Otherwise, the image will be stored in
* PPM format. If this parameter is set to @ref TJPF_CMYK, then the CMYK
* pixels will be converted to RGB using a quick & dirty algorithm that is
* suitable only for testing purposes. (Proper conversion between CMYK and
* other formats requires a color management system.)
* image will be stored in PGM or grayscale PNG format. Otherwise, the image
* will be stored in PPM or true color PNG format. If this parameter is set to
* @ref TJPF_CMYK, then the CMYK pixels will be converted to RGB using a quick
* & dirty algorithm that is suitable only for testing purposes. (Proper
* conversion between CMYK and other formats requires a color management
* system.)
*
* @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr().)
*/

14
src/wrapper/rdpng-12.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* rdpng-12.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling rdpng.c to support 9 to 12 bits of
* data precision. rdpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 12
#include "../rdpng.c"

14
src/wrapper/rdpng-16.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* rdpng-16.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling rdpng.c to support 13 to 16 bits of
* data precision. rdpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 16
#include "../rdpng.c"

14
src/wrapper/rdpng-8.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* rdpng-8.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling rdpng.c to support 2 to 8 bits of
* data precision. rdpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 8
#include "../rdpng.c"

View File

@@ -1,7 +1,7 @@
/*
* @WRAPPER_FILE@
*
* Copyright (C) 2025, D. R. Commander.
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*

14
src/wrapper/wrpng-12.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* wrpng-12.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling wrpng.c to support 9 to 12 bits of
* data precision. wrpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 12
#include "../wrpng.c"

14
src/wrapper/wrpng-16.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* wrpng-16.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling wrpng.c to support 13 to 16 bits of
* data precision. wrpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 16
#include "../wrpng.c"

14
src/wrapper/wrpng-8.c Normal file
View File

@@ -0,0 +1,14 @@
/*
* wrpng-8.c
*
* Copyright (C) 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file is a wrapper for compiling wrpng.c to support 2 to 8 bits of
* data precision. wrpng.c should not be compiled directly.
*/
#define BITS_IN_JSAMPLE 8
#include "../wrpng.c"

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1994-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2013, Linaro Limited.
* Copyright (C) 2014-2015, 2017, 2019, 2022, 2024, D. R. Commander.
* Copyright (C) 2014-2015, 2017, 2019, 2022, 2024, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -428,6 +428,13 @@ start_output_bmp(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
}
METHODDEF(void)
write_icc_profile_bmp(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr, unsigned int icc_data_len)
{
}
METHODDEF(void)
finish_output_bmp(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
@@ -488,6 +495,7 @@ jinit_write_bmp(j_decompress_ptr cinfo, boolean is_os2,
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(bmp_dest_struct));
dest->pub.start_output = start_output_bmp;
dest->pub.write_icc_profile = write_icc_profile_bmp;
dest->pub.finish_output = finish_output_bmp;
dest->pub.calc_buffer_dimensions = NULL;
dest->is_os2 = is_os2;

View File

@@ -5,7 +5,7 @@
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 2015-2019 by Guido Vollbeding.
* libjpeg-turbo Modifications:
* Copyright (C) 2015, 2017, 2022-2023, D. R. Commander.
* Copyright (C) 2015, 2017, 2022-2023, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -487,6 +487,13 @@ put_raw_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
}
METHODDEF(void)
write_icc_profile_gif(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr, unsigned int icc_data_len)
{
}
/*
* Finish up at the end of the file.
*/
@@ -537,6 +544,7 @@ _jinit_write_gif(j_decompress_ptr cinfo, boolean is_lzw)
sizeof(gif_dest_struct));
dest->cinfo = cinfo; /* make back link for subroutines */
dest->pub.start_output = start_output_gif;
dest->pub.write_icc_profile = write_icc_profile_gif;
dest->pub.finish_output = finish_output_gif;
dest->pub.calc_buffer_dimensions = calc_buffer_dimensions_gif;

471
src/wrpng.c Normal file
View File

@@ -0,0 +1,471 @@
/*
* wrpng.c
*
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2017, 2019-2020, 2022, 2024, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
* This file contains routines to write output images in 8-bit-per-channel or
* 16-bit-per-channel PNG format. libspng is required to compile this
* software.
*/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_DEPRECATE
#endif
#include "cmyk.h"
#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
#include "spng/spng.h"
#if defined(PNG_SUPPORTED) && \
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED))
#if BITS_IN_JSAMPLE == 8
#define PNG_BIT_DEPTH 8
#define BYTESPERSAMPLE 1
typedef unsigned char PNGSAMPLE;
#else
#define PNG_BIT_DEPTH 16
#define BYTESPERSAMPLE 2
typedef unsigned short PNGSAMPLE;
#endif
#define TRY_SPNG(f) { \
int __spng_error = (f); \
if (__spng_error) \
ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(__spng_error)); \
}
/* Private version of data destination object */
typedef struct {
struct djpeg_dest_struct pub; /* public fields */
spng_ctx *ctx;
/* Usually these two pointers point to the same place: */
PNGSAMPLE *iobuffer; /* libspng's I/O buffer */
_JSAMPROW pixrow; /* decompressor output buffer */
size_t buffer_width; /* width of I/O buffer */
PNGSAMPLE *rescale; /* data precision => PNG bit depth remapping
array, or NULL */
} png_dest_struct;
typedef png_dest_struct *png_dest_ptr;
/*
* Write some pixel data.
* In this module rows_supplied will always be 1.
*
* put_pixel_rows() is used when the pixel format is JCS_EXT_RGB/JCS_RGB or
* JCS_GRAYSCALE and cinfo->data_precision is 8 or 16, so we can write the
* pixels directly to the PNG file.
*/
METHODDEF(void)
put_pixel_rows(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
int spng_error;
spng_error = spng_encode_row(dest->ctx, dest->iobuffer, dest->buffer_width);
if (spng_error && spng_error != SPNG_EOI)
ERREXITS(cinfo, JERR_PNG_LIBSPNG, spng_strerror(spng_error)); \
}
/*
* Convert extended RGB to RGB.
*/
METHODDEF(void)
put_rgb(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo, JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
register PNGSAMPLE *bufferptr, *rescale = dest->rescale;
register _JSAMPROW ptr;
register JDIMENSION col;
register int rindex = rgb_red[cinfo->out_color_space];
register int gindex = rgb_green[cinfo->out_color_space];
register int bindex = rgb_blue[cinfo->out_color_space];
register int ps = rgb_pixelsize[cinfo->out_color_space];
ptr = dest->pub._buffer[0];
bufferptr = dest->iobuffer;
#if BITS_IN_JSAMPLE == PNG_BIT_DEPTH
if (cinfo->data_precision == PNG_BIT_DEPTH) {
for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = ptr[rindex];
*bufferptr++ = ptr[gindex];
*bufferptr++ = ptr[bindex];
ptr += ps;
}
} else
#endif
{
for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = rescale[ptr[rindex]];
*bufferptr++ = rescale[ptr[gindex]];
*bufferptr++ = rescale[ptr[bindex]];
ptr += ps;
}
}
put_pixel_rows(cinfo, dinfo, rows_supplied);
}
/*
* Convert CMYK to RGB.
*/
METHODDEF(void)
put_cmyk(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
register PNGSAMPLE *bufferptr, *rescale = dest->rescale;
register _JSAMPROW ptr;
register JDIMENSION col;
ptr = dest->pub._buffer[0];
bufferptr = dest->iobuffer;
#if BITS_IN_JSAMPLE == PNG_BIT_DEPTH
if (cinfo->data_precision == PNG_BIT_DEPTH) {
for (col = cinfo->output_width; col > 0; col--) {
_JSAMPLE r, g, b, c = *ptr++, m = *ptr++, y = *ptr++, k = *ptr++;
cmyk_to_rgb((1 << cinfo->data_precision) - 1, c, m, y, k, &r, &g, &b);
*bufferptr++ = r;
*bufferptr++ = g;
*bufferptr++ = b;
}
} else
#endif
{
for (col = cinfo->output_width; col > 0; col--) {
_JSAMPLE r, g, b, c = *ptr++, m = *ptr++, y = *ptr++, k = *ptr++;
cmyk_to_rgb((1 << cinfo->data_precision) - 1, c, m, y, k, &r, &g, &b);
*bufferptr++ = rescale[r];
*bufferptr++ = rescale[g];
*bufferptr++ = rescale[b];
}
}
put_pixel_rows(cinfo, dinfo, rows_supplied);
}
/*
* Convert N-bit grayscale to 8-bit or 16-bit grayscale
*/
METHODDEF(void)
put_gray(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
register PNGSAMPLE *bufferptr, *rescale = dest->rescale;
register _JSAMPROW ptr;
register JDIMENSION col;
ptr = dest->pub._buffer[0];
bufferptr = dest->iobuffer;
for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = rescale[*ptr++];
}
put_pixel_rows(cinfo, dinfo, rows_supplied);
}
/*
* Write some pixel data when color quantization is in effect.
* We have to demap the color index values to straight data.
*/
METHODDEF(void)
put_demapped_rgb(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
register int pixval;
register PNGSAMPLE *bufferptr, *rescale = dest->rescale;
register _JSAMPROW ptr;
register _JSAMPROW color_map0 = ((_JSAMPARRAY)cinfo->colormap)[0];
register _JSAMPROW color_map1 = ((_JSAMPARRAY)cinfo->colormap)[1];
register _JSAMPROW color_map2 = ((_JSAMPARRAY)cinfo->colormap)[2];
register JDIMENSION col;
ptr = dest->pub._buffer[0];
bufferptr = dest->iobuffer;
#if BITS_IN_JSAMPLE == PNG_BIT_DEPTH
if (cinfo->data_precision == PNG_BIT_DEPTH) {
for (col = cinfo->output_width; col > 0; col--) {
pixval = *ptr++;
*bufferptr++ = color_map0[pixval];
*bufferptr++ = color_map1[pixval];
*bufferptr++ = color_map2[pixval];
}
} else
#endif
{
for (col = cinfo->output_width; col > 0; col--) {
pixval = *ptr++;
*bufferptr++ = rescale[color_map0[pixval]];
*bufferptr++ = rescale[color_map1[pixval]];
*bufferptr++ = rescale[color_map2[pixval]];
}
}
put_pixel_rows(cinfo, dinfo, rows_supplied);
}
METHODDEF(void)
put_demapped_gray(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
JDIMENSION rows_supplied)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
register PNGSAMPLE *bufferptr, *rescale = dest->rescale;
register _JSAMPROW ptr;
register _JSAMPROW color_map = ((_JSAMPARRAY)cinfo->colormap)[0];
register JDIMENSION col;
ptr = dest->pub._buffer[0];
bufferptr = dest->iobuffer;
#if BITS_IN_JSAMPLE == PNG_BIT_DEPTH
if (cinfo->data_precision == PNG_BIT_DEPTH) {
for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = color_map[*ptr++];
}
} else
#endif
{
for (col = cinfo->output_width; col > 0; col--) {
*bufferptr++ = rescale[color_map[*ptr++]];
}
}
put_pixel_rows(cinfo, dinfo, rows_supplied);
}
/*
* Embed an ICC profile in the PNG image.
*
* NOTE: The pointer passed to this function will be freed by spng_ctx_free()
* in the body of finish_output_png().
*/
METHODDEF(void)
write_icc_profile_png(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr, unsigned int icc_data_len)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
struct spng_iccp iccp;
if (!icc_data_ptr || !icc_data_len)
ERREXIT(cinfo, JERR_INPUT_EMPTY);
SNPRINTF(iccp.profile_name, 80, "ICC Profile");
iccp.profile_len = icc_data_len;
iccp.profile = (char *)icc_data_ptr;
TRY_SPNG(spng_set_iccp(dest->ctx, &iccp));
}
/*
* Startup: write the file header.
*/
METHODDEF(void)
start_output_png(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
struct spng_ihdr ihdr;
uint8_t color_type = 0;
switch (cinfo->out_color_space) {
case JCS_GRAYSCALE:
color_type = SPNG_COLOR_TYPE_GRAYSCALE;
break;
case JCS_RGB:
case JCS_EXT_RGB:
case JCS_EXT_RGBX:
case JCS_EXT_BGR:
case JCS_EXT_BGRX:
case JCS_EXT_XBGR:
case JCS_EXT_XRGB:
case JCS_EXT_RGBA:
case JCS_EXT_BGRA:
case JCS_EXT_ABGR:
case JCS_EXT_ARGB:
case JCS_CMYK:
if (!IsExtRGB(cinfo->out_color_space) && cinfo->quantize_colors)
ERREXIT(cinfo, JERR_PNG_COLORSPACE);
color_type = SPNG_COLOR_TYPE_TRUECOLOR;
break;
default:
ERREXIT(cinfo, JERR_PNG_COLORSPACE);
}
TRY_SPNG(spng_set_png_file(dest->ctx, dinfo->output_file));
memset(&ihdr, 0, sizeof(struct spng_ihdr));
ihdr.width = (uint32_t)cinfo->output_width;
ihdr.height = (uint32_t)cinfo->output_height;
ihdr.bit_depth = PNG_BIT_DEPTH;
ihdr.color_type = color_type;
TRY_SPNG(spng_set_ihdr(dest->ctx, &ihdr));
TRY_SPNG(spng_encode_image(dest->ctx, NULL, 0, SPNG_FMT_PNG,
SPNG_ENCODE_PROGRESSIVE));
}
/*
* Finish up at the end of the file.
*/
METHODDEF(void)
finish_output_png(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
if (dest->ctx) {
spng_encode_chunks(dest->ctx);
spng_ctx_free(dest->ctx);
}
/* Make sure we wrote the output file OK */
fflush(dinfo->output_file);
if (ferror(dinfo->output_file))
ERREXIT(cinfo, JERR_FILE_WRITE);
}
/*
* Re-calculate buffer dimensions based on output dimensions.
*/
METHODDEF(void)
calc_buffer_dimensions_png(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
{
png_dest_ptr dest = (png_dest_ptr)dinfo;
JDIMENSION samples_per_row;
if (cinfo->out_color_space == JCS_GRAYSCALE)
samples_per_row = cinfo->output_width * cinfo->out_color_components;
else
samples_per_row = cinfo->output_width * 3;
dest->buffer_width = samples_per_row * BYTESPERSAMPLE;
}
/*
* The module selection routine for PNG format output.
*/
GLOBAL(djpeg_dest_ptr)
_jinit_write_png(j_decompress_ptr cinfo)
{
png_dest_ptr dest;
#if BITS_IN_JSAMPLE == 8
if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)
#else
if (cinfo->data_precision > BITS_IN_JSAMPLE ||
cinfo->data_precision < BITS_IN_JSAMPLE - 3)
#endif
ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
/* Create module interface object, fill in method pointers */
dest = (png_dest_ptr)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(png_dest_struct));
dest->pub.start_output = start_output_png;
dest->pub.write_icc_profile = write_icc_profile_png;
dest->pub.finish_output = finish_output_png;
dest->pub.calc_buffer_dimensions = calc_buffer_dimensions_png;
/* Calculate output image dimensions so we can allocate space */
jpeg_calc_output_dimensions(cinfo);
/* Create physical I/O buffer */
dest->pub.calc_buffer_dimensions(cinfo, (djpeg_dest_ptr)dest);
dest->iobuffer = (PNGSAMPLE *)(*cinfo->mem->alloc_small)
((j_common_ptr)cinfo, JPOOL_IMAGE, dest->buffer_width);
if (cinfo->quantize_colors || cinfo->data_precision != PNG_BIT_DEPTH ||
(cinfo->out_color_space != JCS_EXT_RGB &&
#if RGB_RED == 0 && RGB_GREEN == 1 && RGB_BLUE == 2 && RGB_PIXELSIZE == 3
cinfo->out_color_space != JCS_RGB &&
#endif
cinfo->out_color_space != JCS_GRAYSCALE)) {
/* When quantizing, we need an output buffer for colormap indexes
* that's separate from the physical I/O buffer. We also need a
* separate buffer if pixel format translation must take place.
*/
dest->pub._buffer = (_JSAMPARRAY)(*cinfo->mem->alloc_sarray)
((j_common_ptr)cinfo, JPOOL_IMAGE,
cinfo->output_width * cinfo->output_components, (JDIMENSION)1);
dest->pub.buffer_height = 1;
if (!cinfo->quantize_colors) {
if (IsExtRGB(cinfo->out_color_space))
dest->pub.put_pixel_rows = put_rgb;
else if (cinfo->out_color_space == JCS_CMYK)
dest->pub.put_pixel_rows = put_cmyk;
else
dest->pub.put_pixel_rows = put_gray;
} else if (cinfo->out_color_space == JCS_GRAYSCALE)
dest->pub.put_pixel_rows = put_demapped_gray;
else
dest->pub.put_pixel_rows = put_demapped_rgb;
/* Scale up samples with 2-7 or 9-15 bits of data precision so they can be
* stored in, respectively, 8-bit-per-channel and 16-bit-per-channel PNG
* files. This scaling algorithm is fully reversible, i.e. you can get
* back the same samples with 2-7 or 9-15 bits of data precision, if you
* similarly scale down the 8-bit or 16-bit samples from the PNG file
* (which our PNG reader does.)
*/
if (cinfo->data_precision != PNG_BIT_DEPTH) {
unsigned int maxval = (1 << cinfo->data_precision) - 1;
long val, half_maxval = maxval / 2;
/* Compute the rescaling array. */
dest->rescale = (PNGSAMPLE *)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
(size_t)(((long)maxval + 1L) *
sizeof(PNGSAMPLE)));
memset(dest->rescale, 0, (size_t)(((long)maxval + 1L) *
sizeof(PNGSAMPLE)));
half_maxval = maxval / 2;
for (val = 0; val <= (long)maxval; val++) {
/* The multiplication here must be done in 32 bits to avoid overflow */
dest->rescale[val] =
(PNGSAMPLE)((val * ((1 << PNG_BIT_DEPTH) - 1) + half_maxval) /
maxval);
}
}
} else {
/* We will write directly from decompressor output buffer. */
/* Synthesize a _JSAMPARRAY pointer structure */
dest->pixrow = (_JSAMPROW)dest->iobuffer;
dest->pub._buffer = &dest->pixrow;
dest->pub.buffer_height = 1;
dest->pub.put_pixel_rows = put_pixel_rows;
}
dest->ctx = spng_ctx_new(SPNG_CTX_ENCODER);
if (!dest->ctx)
ERREXITS(cinfo, JERR_PNG_LIBSPNG, "Could not create context");
return (djpeg_dest_ptr)dest;
}
#endif /* defined(PNG_SUPPORTED) &&
(BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)) */

View File

@@ -268,6 +268,13 @@ start_output_ppm(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
}
METHODDEF(void)
write_icc_profile_ppm(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr, unsigned int icc_data_len)
{
}
/*
* Finish up at the end of the file.
*/
@@ -321,6 +328,7 @@ _jinit_write_ppm(j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(ppm_dest_struct));
dest->pub.start_output = start_output_ppm;
dest->pub.write_icc_profile = write_icc_profile_ppm;
dest->pub.finish_output = finish_output_ppm;
dest->pub.calc_buffer_dimensions = calc_buffer_dimensions_ppm;

View File

@@ -4,7 +4,7 @@
* This file was part of the Independent JPEG Group's software:
* Copyright (C) 1991-1996, Thomas G. Lane.
* libjpeg-turbo Modifications:
* Copyright (C) 2017, 2019, 2022, D. R. Commander.
* Copyright (C) 2017, 2019, 2022, 2026, D. R. Commander.
* For conditions of distribution and use, see the accompanying README.ijg
* file.
*
@@ -194,6 +194,13 @@ start_output_tga(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo)
}
METHODDEF(void)
write_icc_profile_tga(j_decompress_ptr cinfo, djpeg_dest_ptr dinfo,
const JOCTET *icc_data_ptr, unsigned int icc_data_len)
{
}
/*
* Finish up at the end of the file.
*/
@@ -238,6 +245,7 @@ jinit_write_targa(j_decompress_ptr cinfo)
(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,
sizeof(tga_dest_struct));
dest->pub.start_output = start_output_tga;
dest->pub.write_icc_profile = write_icc_profile_tga;
dest->pub.finish_output = finish_output_tga;
dest->pub.calc_buffer_dimensions = calc_buffer_dimensions_tga;

View File

@@ -19,15 +19,14 @@ runme()
"$@"
}
EXT=bmp
IMAGES="vgl_5674_0098.${EXT} vgl_6434_0018a.${EXT} vgl_6548_0026a.${EXT} shira_bird8.${EXT}"
IMAGES="vgl_5674_0098.png vgl_6434_0018a.bmp vgl_6548_0026a.bmp shira_bird8.bmp"
IMGDIR=@CMAKE_SOURCE_DIR@/testimages
OUTDIR=`mktemp -d /tmp/__tjbenchtest_output.XXXXXX`
EXEDIR=@CMAKE_BINARY_DIR@
JAVA="@Java_JAVA_EXECUTABLE@"
JNAARGS="-cp $EXEDIR/jna/turbojpeg-jna.jar:@WITH_JNA@ -Djna.library.path=$EXEDIR"
TJBENCH=$EXEDIR/tjbench
BMPARG=
FMTARG=
NSARG=
YUVARG=
ALLOC=0
@@ -41,7 +40,6 @@ x1SUBSAMP="444 GRAY"
x24SUBSAMP="422 440 420 411 441"
ALLSUBSAMP="444 422 440 420 411 441 GRAY"
PRECISION=8
if [ "$EXT" = "bmp" ]; then BMPARG=-b; fi
if [ -d $OUTDIR ]; then
rm -rf $OUTDIR
@@ -70,7 +68,7 @@ while [ $# -gt 0 ]; do
# results to tj3Decompress*() if decompression scaling is enabled. This latter
# phenomenon is not yet fully understood but is also believed to be some sort
# of round-off error.)
IMAGES="vgl_6548_0026a.${EXT}"
IMAGES="vgl_6548_0026a.bmp"
;;
-alloc)
ALLOCARG=-alloc
@@ -109,9 +107,7 @@ while [ $# -gt 0 ]; do
shift
PRECISION=$1
if [ $PRECISION != 8 ]; then
EXT=ppm
IMAGES="monkey16.${EXT}"
BMPARG=
IMAGES="monkey16.png"
fi
;;
esac
@@ -120,12 +116,12 @@ done
if [ $PRECISION = 8 -a "$YUVARG" = "" ]; then
if [ "$ENTROPYARG" = "-optimize" ]; then
IMAGES="vgl_6434_0018a.${EXT}"
IMAGES="vgl_6434_0018a.bmp"
elif [ "$ENTROPYARG" = "-progressive" ]; then
IMAGES="vgl_6548_0026a.${EXT}"
IMAGES="vgl_6548_0026a.bmp"
elif [ "$ENTROPYARG" = "-arithmetic" -o \
"$ENTROPYARG" = "-progressive-arithmetic" ]; then
IMAGES="shira_bird8.${EXT}"
IMAGES="shira_bird8.bmp"
fi
fi
@@ -145,7 +141,14 @@ XFORMARGS=("-f h -r 2" "-f v" "-t -r 1b" -transv "-ro 90 -r 1" "-ro 180" "-ro 27
for image in $IMAGES; do
cp $IMGDIR/$image $OUTDIR
basename=`basename $image .${EXT}`
basename=${image%.*}
EXT=${image##*.}
FMTARG=
if [ "$EXT" = "png" ]; then
FMTARG=-png
elif [ "$EXT" = "bmp" ]; then
FMTARG=-b
fi
r1barg=
if [ "$LOSSLSARG" != "-l" ]; then
r1barg="-r 1b"
@@ -165,12 +168,12 @@ for image in $IMAGES; do
runme $EXEDIR/cjpeg -q 95 -pre $PRECISION -dc i $ENTROPYARG $LOSSLSARG $LOSSLSPSV -sa 2x1 -outf $OUTDIR/${basename}_422_accurate_cjpeg.jpg $IMGDIR/${basename}.${EXT}
runme $EXEDIR/cjpeg -q 95 -pre $PRECISION -dc i $ENTROPYARG $LOSSLSARG $LOSSLSPSV -sa 1x1 -outf $OUTDIR/${basename}_444_accurate_cjpeg.jpg $IMGDIR/${basename}.${EXT}
for samp in $ALLSUBSAMP; do
runme $EXEDIR/djpeg -dc fa -rg $NSARG $BMPARG -outf $OUTDIR/${basename}_${samp}_fast_djpeg.${EXT} $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
runme $EXEDIR/djpeg -dc i -rg $NSARG $BMPARG -outf $OUTDIR/${basename}_${samp}_accurate_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
runme $EXEDIR/djpeg -dc fa -rg $NSARG $FMTARG -outf $OUTDIR/${basename}_${samp}_fast_djpeg.${EXT} $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
runme $EXEDIR/djpeg -dc i -rg $NSARG $FMTARG -outf $OUTDIR/${basename}_${samp}_accurate_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
done
for samp in $x24SUBSAMP; do
runme $EXEDIR/djpeg -dc fa -nos $BMPARG -outf $OUTDIR/${basename}_${samp}_fast_nosmooth_djpeg.${EXT} $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
runme $EXEDIR/djpeg -dc i -nos $BMPARG -outf $OUTDIR/${basename}_${samp}_accurate_nosmooth_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
runme $EXEDIR/djpeg -dc fa -nos $FMTARG -outf $OUTDIR/${basename}_${samp}_fast_nosmooth_djpeg.${EXT} $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg
runme $EXEDIR/djpeg -dc i -nos $FMTARG -outf $OUTDIR/${basename}_${samp}_accurate_nosmooth_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
done
# Compression
@@ -273,7 +276,7 @@ for image in $IMAGES; do
# Tiled decompression
if [ "$LOSSLSARG" != "-l" ]; then
for samp in $x1SUBSAMP; do
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG -ti -q -be 0.01 -w 0 ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG -ti -q -be 0.01 -w 0 ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG
if [ $ALLOC = 1 ]; then
runme cmp $OUTDIR/${basename}_${samp}_Q95_full.${EXT} $OUTDIR/${basename}_${samp}_${dct}_djpeg.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_full.${EXT}
@@ -286,7 +289,7 @@ for image in $IMAGES; do
fi
done
for samp in $x24SUBSAMP; do
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG -ti -q -be 0.01 -w 0 -nos ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG -ti -q -be 0.01 -w 0 -nos ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG
if [ $ALLOC = 1 ]; then
runme cmp $OUTDIR/${basename}_${samp}_Q95_full.${EXT} $OUTDIR/${basename}_${samp}_${dct}_nosmooth_djpeg.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_full.${EXT}
@@ -347,13 +350,13 @@ for image in $IMAGES; do
SCALE=full
fi
for samp in $ALLSUBSAMP; do
runme $EXEDIR/djpeg -rg -s ${scalearg} $NSARG $BMPARG -outf $OUTDIR/${basename}_${samp}_${scale}_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
runme $EXEDIR/djpeg -rg -s ${scalearg} $NSARG $FMTARG -outf $OUTDIR/${basename}_${samp}_${scale}_djpeg.${EXT} $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg
if [ "$LOSSLSARG" = "-l" ]; then
runme $TJBENCH $OUTDIR/${basename}_LOSSLS_PSV${TJQUAL}.jpg $BMPARG -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG
runme $TJBENCH $OUTDIR/${basename}_LOSSLS_PSV${TJQUAL}.jpg $FMTARG -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG
runme cmp $OUTDIR/${basename}_LOSSLS_PSV${TJQUAL}_${SCALE}.${EXT} $OUTDIR/${basename}_${samp}_${scale}_djpeg.${EXT}
rm $OUTDIR/${basename}_LOSSLS_PSV${TJQUAL}_${SCALE}.${EXT}
else
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q${TJQUAL}.jpg $BMPARG -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q${TJQUAL}.jpg $FMTARG -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG
runme cmp $OUTDIR/${basename}_${samp}_Q${TJQUAL}_${SCALE}.${EXT} $OUTDIR/${basename}_${samp}_${scale}_djpeg.${EXT}
rm $OUTDIR/${basename}_${samp}_Q${TJQUAL}_${SCALE}.${EXT}
fi
@@ -371,8 +374,12 @@ for image in $IMAGES; do
done
for xform in {0..6}; do
for samp in $x1SUBSAMP; do
runme $EXEDIR/djpeg -rg $BMPARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG
NOICCARG=
if [ "$EXT" = "png" ]; then
NOICCARG=-noi
fi
runme $EXEDIR/djpeg -rg $FMTARG $NOICCARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG $NOICCARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG
if [ $ALLOC = 1 ]; then
runme cmp $OUTDIR/${basename}_${samp}_Q95_full.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_full.${EXT}
@@ -385,8 +392,8 @@ for image in $IMAGES; do
fi
done
for samp in $x24SUBSAMP; do
runme $EXEDIR/djpeg -nos -rg $BMPARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 -nos $YUVARG $ALLOCARG $ENTROPYARG
runme $EXEDIR/djpeg -nos -rg $FMTARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 -nos $YUVARG $ALLOCARG $ENTROPYARG
if [ $ALLOC = 1 ]; then
runme cmp $OUTDIR/${basename}_${samp}_Q95_full.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_full.${EXT}
@@ -411,7 +418,11 @@ for image in $IMAGES; do
# Grayscale transform
for xform in {0..6}; do
for samp in $ALLSUBSAMP; do
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 -g $YUVARG $ALLOCARG $ENTROPYARG
NOICCARG=
if [ "$EXT" = "png" ]; then
NOICCARG=-noi
fi
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG $NOICCARG ${XFORMARGS[$xform]} -ti -q -be 0.01 -w 0 -g $YUVARG $ALLOCARG $ENTROPYARG
if [ $ALLOC = 1 ]; then
runme cmp $OUTDIR/${basename}_${samp}_Q95_full.${EXT} $OUTDIR/${basename}_GRAY_${XFORMNAME[$xform]}_jpegtran.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_full.${EXT}
@@ -439,8 +450,8 @@ for image in $IMAGES; do
for samp in $ALLSUBSAMP; do
for scale in 2_1 15_8 7_4 13_8 3_2 11_8 5_4 9_8 7_8 3_4 5_8 1_2 3_8 1_4 1_8; do
scalearg=`echo $scale | sed 's/\_/\//g'`
runme $EXEDIR/djpeg -rg -s ${scalearg} $NSARG $BMPARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_${scale}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $BMPARG ${XFORMARGS[$xform]} -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG
runme $EXEDIR/djpeg -rg -s ${scalearg} $NSARG $FMTARG -outf $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_${scale}_jpegtran.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_jpegtran.jpg
runme $TJBENCH $OUTDIR/${basename}_${samp}_Q95.jpg $FMTARG ${XFORMARGS[$xform]} -s ${scalearg} -q -be 0.01 -w 0 $YUVARG $ALLOCARG $ENTROPYARG
runme cmp $OUTDIR/${basename}_${samp}_Q95_${scale}.${EXT} $OUTDIR/${basename}_${samp}_${XFORMNAME[$xform]}_${scale}_jpegtran.${EXT}
rm $OUTDIR/${basename}_${samp}_Q95_${scale}.${EXT}
done

View File

@@ -60,11 +60,15 @@ SAMPOPT=(1x1 2x1 1x2 2x2 4x1 1x4)
for precision in 8 12; do
if [ $precision -le 8 ]; then
RGBIMG=$IMGDIR/testorig.ppm
GRAYIMG=$IMGDIR/testorig.pgm
GRAYIMG=$IMGDIR/testorig.png
basename=testorig
else
RGBIMG=$IMGDIR/monkey16.ppm
RGBIMG=$IMGDIR/monkey16.png
GRAYIMG=$IMGDIR/monkey16.pgm
basename=monkey16
fi
RGBEXT=${RGBIMG##*.}
GRAYEXT=${GRAYIMG##*.}
if [ $precision -eq 8 ]; then
prearg=
else
@@ -89,13 +93,17 @@ for precision in 8 12; do
blarg=-baseline
fi
for sampi in {0..5}; do
basename=`basename $RGBIMG .ppm`
noiccarg=
if [ $sampi = 4 -a "$RGBEXT" = "png" ]; then
noiccarg=-noicc
fi
runme $TJCOMP $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg -s ${SUBSAMPOPT[$sampi]} \
$RGBIMG $OUTDIR/${basename}-tjcomp.jpg
$noiccarg $RGBIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg $blarg -sa ${SAMPOPT[$sampi]} \
-outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$noiccarg -outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjcomp.jpg \
$OUTDIR/${basename}-cjpeg.jpg | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjcomp.jpg \
@@ -105,10 +113,10 @@ for precision in 8 12; do
runme $TJCOMP $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg -s ${SUBSAMPOPT[$sampi]} \
-g $RGBIMG $OUTDIR/${basename}-tjcomp.jpg
$noiccarg -g $RGBIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg $blarg -sa ${SAMPOPT[$sampi]} \
-gr -outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$noiccarg -gr -outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjcomp.jpg \
$OUTDIR/${basename}-cjpeg.jpg | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjcomp.jpg \
@@ -118,10 +126,10 @@ for precision in 8 12; do
runme $TJCOMP $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg -s ${SUBSAMPOPT[$sampi]} \
-rg $RGBIMG $OUTDIR/${basename}-tjcomp.jpg
$noiccarg -rg $RGBIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg $blarg -sa ${SAMPOPT[$sampi]} \
-rgb -outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$noiccarg -rgb -outf $OUTDIR/${basename}-cjpeg.jpg $RGBIMG
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjcomp.jpg \
$OUTDIR/${basename}-cjpeg.jpg | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjcomp.jpg \
@@ -129,13 +137,17 @@ for precision in 8 12; do
rm $OUTDIR/${basename}-tjcomp.jpg $OUTDIR/${basename}-cjpeg.jpg
echo
basename=`basename $GRAYIMG .pgm`
noiccarg=
if [ $sampi = 4 -a "$GRAYEXT" = "png" ]; then
noiccarg=-noicc
fi
runme $TJCOMP $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg -s ${SUBSAMPOPT[$sampi]} \
$GRAYIMG $OUTDIR/${basename}-tjcomp.jpg
$noiccarg $GRAYIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg $restartarg $ariarg $dctarg \
$optarg $progarg $qualarg $blarg -sa ${SAMPOPT[$sampi]} \
-outf $OUTDIR/${basename}-cjpeg.jpg $GRAYIMG
$noiccarg -outf $OUTDIR/${basename}-cjpeg.jpg $GRAYIMG
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjcomp.jpg \
$OUTDIR/${basename}-cjpeg.jpg | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjcomp.jpg \
@@ -154,10 +166,12 @@ done
for precision in {2..16}; do
if [ $precision -le 8 ]; then
RGBIMG=$IMGDIR/testorig.ppm
GRAYIMG=$IMGDIR/testorig.pgm
GRAYIMG=$IMGDIR/testorig.png
basename=testorig
else
RGBIMG=$IMGDIR/monkey16.ppm
RGBIMG=$IMGDIR/monkey16.png
GRAYIMG=$IMGDIR/monkey16.pgm
basename=monkey16
fi
if [ $precision -eq 8 ]; then
prearg=
@@ -170,7 +184,6 @@ for precision in {2..16}; do
continue
fi
for restartarg in "" "-r 1 -icc $IMGDIR/test3.icc"; do
basename=`basename $RGBIMG .ppm`
runme $TJCOMP $prearg -l $psv,$pt $restartarg \
$RGBIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg -l $psv,$pt $restartarg \
@@ -181,7 +194,6 @@ for precision in {2..16}; do
rm $OUTDIR/${basename}-tjcomp.jpg $OUTDIR/${basename}-cjpeg.jpg
echo
basename=`basename $GRAYIMG .pgm`
runme $TJCOMP $prearg -l $psv,$pt $restartarg \
$GRAYIMG $OUTDIR/${basename}-tjcomp.jpg
runme $EXEDIR/cjpeg $prearg -l $psv,$pt $restartarg \

View File

@@ -60,30 +60,39 @@ SAMPOPT=(1x1 2x1 1x2 2x2 4x1 1x4 4x2)
for precision in 8 12; do
if [ $precision -le 8 ]; then
RGBIMG=$IMGDIR/testorig.ppm
GRAYIMG=$IMGDIR/testorig.pgm
RGBFMTARG=
GRAYIMG=$IMGDIR/testorig.png
GRAYFMTARG=-png
basename=testorig
else
RGBIMG=$IMGDIR/monkey16.ppm
RGBIMG=$IMGDIR/monkey16.png
RGBFMTARG=-png
GRAYIMG=$IMGDIR/monkey16.pgm
GRAYFMTARG=
basename=monkey16
fi
RGBEXT=${RGBIMG##*.}
GRAYEXT=${GRAYIMG##*.}
for sampi in {0..6}; do
iccarg=
if [ $sampi = 3 ]; then
iccarg="-icc $IMGDIR/test1.icc"
elif [ $sampi = 4 -a "$RGBEXT" = "png" ]; then
iccarg=-noicc
fi
runme $EXEDIR/cjpeg -pre $precision -sa ${SAMPOPT[$sampi]} $iccarg \
-outf $OUTDIR/`basename $RGBIMG .ppm`-${SUBSAMPOPT[$sampi]}.jpg $RGBIMG
-outf $OUTDIR/${basename}-${SUBSAMPOPT[$sampi]}.jpg $RGBIMG
if [ $precision -gt 8 ]; then
runme $EXEDIR/cjpeg -pre 8 -sa ${SAMPOPT[$sampi]} $iccarg \
-outf $OUTDIR/`basename $RGBIMG .ppm`-${SUBSAMPOPT[$sampi]}-8.jpg \
$RGBIMG
-outf $OUTDIR/${basename}-${SUBSAMPOPT[$sampi]}-8.jpg $RGBIMG
fi
done
runme $EXEDIR/cjpeg -pre $precision \
-outf $OUTDIR/`basename $GRAYIMG .pgm`-gray.jpg $GRAYIMG
-outf $OUTDIR/${basename}-gray.jpg $GRAYIMG
if [ $precision -gt 8 ]; then
runme $EXEDIR/cjpeg -pre 8 \
-outf $OUTDIR/`basename $GRAYIMG .pgm`-gray-8.jpg $GRAYIMG
-outf $OUTDIR/${basename}-gray-8.jpg $GRAYIMG
fi
echo
@@ -113,78 +122,82 @@ for precision in 8 12; do
continue
fi
if [ "$subsamp" = "gray" ]; then
basename=`basename $GRAYIMG .pgm`
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
$OUTDIR/${basename}-$subsamp.jpg \
$OUTDIR/${basename}-tjdecomp.pgm
$OUTDIR/${basename}-tjdecomp.$GRAYEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-outf $OUTDIR/${basename}-djpeg.pgm \
$GRAYFMTARG -outf $OUTDIR/${basename}-djpeg.$GRAYEXT \
$OUTDIR/${basename}-$subsamp.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
rm $OUTDIR/${basename}-tjdecomp.pgm $OUTDIR/${basename}-djpeg.pgm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
echo
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
-r $OUTDIR/${basename}-$subsamp.jpg \
$OUTDIR/${basename}-tjdecomp.ppm
$OUTDIR/${basename}-tjdecomp.$RGBEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-rg -outf $OUTDIR/${basename}-djpeg.ppm \
$RGBFMTARG -rg -outf $OUTDIR/${basename}-djpeg.$RGBEXT \
$OUTDIR/${basename}-$subsamp.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
rm $OUTDIR/${basename}-tjdecomp.ppm $OUTDIR/${basename}-djpeg.ppm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
echo
if [ $precision -gt 8 ]; then
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
$OUTDIR/${basename}-$subsamp-8.jpg \
$OUTDIR/${basename}-tjdecomp.pgm
$OUTDIR/${basename}-tjdecomp.$GRAYEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-outf $OUTDIR/${basename}-djpeg.pgm \
$GRAYFMTARG -outf $OUTDIR/${basename}-djpeg.$GRAYEXT \
$OUTDIR/${basename}-$subsamp-8.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
rm $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT | \
sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
echo
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
-r $OUTDIR/${basename}-$subsamp-8.jpg \
$OUTDIR/${basename}-tjdecomp.ppm
$OUTDIR/${basename}-tjdecomp.$RGBEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-rg -outf $OUTDIR/${basename}-djpeg.ppm \
$RGBFMTARG -rg -outf $OUTDIR/${basename}-djpeg.$RGBEXT \
$OUTDIR/${basename}-$subsamp-8.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
rm $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT | \
sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
echo
fi
else
basename=`basename $RGBIMG .ppm`
iccarg=
if [ "$subsamp" = "420" ]; then
iccarg="-icc $OUTDIR/${basename}-tjdecomp.icc"
elif [ "$subsamp" = "411" -a "$RGBEXT" = "png" ]; then
iccarg=-noicc
fi
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg $iccarg \
$OUTDIR/${basename}-$subsamp.jpg \
$OUTDIR/${basename}-tjdecomp.ppm
$OUTDIR/${basename}-tjdecomp.$RGBEXT
if [ "$subsamp" = "420" ]; then
iccarg="-icc $OUTDIR/${basename}-djpeg.icc"
elif [ "$subsamp" = "411" -a "$RGBEXT" = "png" ]; then
iccarg=-noicc
fi
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg $iccarg \
-outf $OUTDIR/${basename}-djpeg.ppm \
$RGBFMTARG -outf $OUTDIR/${basename}-djpeg.$RGBEXT \
$OUTDIR/${basename}-$subsamp.jpg
if [ "$subsamp" = "420" ]; then
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.icc \
@@ -194,26 +207,28 @@ for precision in 8 12; do
rm $OUTDIR/${basename}-tjdecomp.icc \
$OUTDIR/${basename}-djpeg.icc
fi
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
rm $OUTDIR/${basename}-tjdecomp.ppm $OUTDIR/${basename}-djpeg.ppm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
echo
if [[ "$nsarg" = "" ]]; then
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
-g $OUTDIR/${basename}-$subsamp.jpg \
$OUTDIR/${basename}-tjdecomp.pgm
$OUTDIR/${basename}-tjdecomp.$GRAYEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-gr -outf $OUTDIR/${basename}-djpeg.pgm \
$GRAYFMTARG -gr -outf $OUTDIR/${basename}-djpeg.$GRAYEXT \
$OUTDIR/${basename}-$subsamp.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
rm $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT | \
sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
echo
fi
@@ -221,15 +236,19 @@ for precision in 8 12; do
iccarg=
if [ "$subsamp" = "420" ]; then
iccarg="-icc $OUTDIR/${basename}-tjdecomp.icc"
elif [ "$subsamp" = "411" -a "$RGBEXT" = "png" ]; then
iccarg=-noicc
fi
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg $iccarg \
$OUTDIR/${basename}-$subsamp-8.jpg \
$OUTDIR/${basename}-tjdecomp.ppm
$OUTDIR/${basename}-tjdecomp.$RGBEXT
if [ "$subsamp" = "420" ]; then
iccarg="-icc $OUTDIR/${basename}-djpeg.icc"
elif [ "$subsamp" = "411" -a "$RGBEXT" = "png" ]; then
iccarg=-noicc
fi
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg $iccarg \
-outf $OUTDIR/${basename}-djpeg.ppm \
$RGBFMTARG -outf $OUTDIR/${basename}-djpeg.$RGBEXT \
$OUTDIR/${basename}-$subsamp-8.jpg
if [ "$subsamp" = "420" ]; then
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.icc \
@@ -239,27 +258,29 @@ for precision in 8 12; do
rm $OUTDIR/${basename}-tjdecomp.icc \
$OUTDIR/${basename}-djpeg.icc
fi
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
rm $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT | \
sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT
echo
if [[ "$nsarg" = "" ]]; then
runme $TJDECOMP $croparg $dctarg $nsarg $scalearg \
-g $OUTDIR/${basename}-$subsamp-8.jpg \
$OUTDIR/${basename}-tjdecomp.pgm
$OUTDIR/${basename}-tjdecomp.$GRAYEXT
runme $EXEDIR/djpeg $croparg $dctarg $nsarg $scalearg \
-gr -outf $OUTDIR/${basename}-djpeg.pgm \
$GRAYFMTARG -gr -outf $OUTDIR/${basename}-djpeg.$GRAYEXT \
$OUTDIR/${basename}-$subsamp-8.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
rm $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT | \
sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT
echo
fi
fi
@@ -278,41 +299,47 @@ done
for precision in {2..16}; do
if [ $precision -le 8 ]; then
RGBIMG=$IMGDIR/testorig.ppm
GRAYIMG=$IMGDIR/testorig.pgm
RGBFMTARG=
GRAYIMG=$IMGDIR/testorig.png
GRAYFMTARG=-png
basename=testorig
else
RGBIMG=$IMGDIR/monkey16.ppm
RGBIMG=$IMGDIR/monkey16.png
RGBFMTARG=-png
GRAYIMG=$IMGDIR/monkey16.pgm
GRAYFMTARG=
basename=monkey16
fi
RGBEXT=${RGBIMG##*.}
GRAYEXT=${GRAYIMG##*.}
basename=`basename $RGBIMG .ppm`
runme $EXEDIR/cjpeg -pre $precision -l 1 \
-outf $OUTDIR/${basename}-rgb.jpg $RGBIMG
echo
runme $TJDECOMP $OUTDIR/${basename}-rgb.jpg \
$OUTDIR/${basename}-tjdecomp.ppm
runme $EXEDIR/djpeg -outf $OUTDIR/${basename}-djpeg.ppm \
$OUTDIR/${basename}-tjdecomp.$RGBEXT
runme $EXEDIR/djpeg $RGBFMTARG -outf $OUTDIR/${basename}-djpeg.$RGBEXT \
$OUTDIR/${basename}-rgb.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.ppm \
$OUTDIR/${basename}-djpeg.ppm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.ppm $OUTDIR/${basename}-djpeg.ppm
rm $OUTDIR/${basename}-tjdecomp.ppm $OUTDIR/${basename}-djpeg.ppm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$RGBEXT \
$OUTDIR/${basename}-djpeg.$RGBEXT | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$RGBEXT $OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-tjdecomp.$RGBEXT $OUTDIR/${basename}-djpeg.$RGBEXT
rm $OUTDIR/${basename}-rgb.jpg
echo
basename=`basename $GRAYIMG .pgm`
runme $EXEDIR/cjpeg -pre $precision -l 1 \
-outf $OUTDIR/${basename}-gray.jpg $GRAYIMG
echo
runme $TJDECOMP $OUTDIR/${basename}-gray.jpg \
$OUTDIR/${basename}-tjdecomp.pgm
runme $EXEDIR/djpeg -outf $OUTDIR/${basename}-djpeg.pgm \
$OUTDIR/${basename}-tjdecomp.$GRAYEXT
runme $EXEDIR/djpeg $GRAYFMTARG -outf $OUTDIR/${basename}-djpeg.$GRAYEXT \
$OUTDIR/${basename}-gray.jpg
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.pgm \
$OUTDIR/${basename}-djpeg.pgm | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.pgm $OUTDIR/${basename}-djpeg.pgm
rm $OUTDIR/${basename}-tjdecomp.pgm $OUTDIR/${basename}-djpeg.pgm
$EXEDIR/test/md5sum $OUTDIR/${basename}-tjdecomp.$GRAYEXT \
$OUTDIR/${basename}-djpeg.$GRAYEXT | sed "s@$OUTDIR@\$OUTDIR@g"
cmp $OUTDIR/${basename}-tjdecomp.$GRAYEXT $OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-tjdecomp.$GRAYEXT $OUTDIR/${basename}-djpeg.$GRAYEXT
rm $OUTDIR/${basename}-gray.jpg
echo
done

View File

@@ -60,10 +60,12 @@ SAMPOPT=(1x1 2x1 1x2 2x2 4x1 1x4 4x2)
for precision in 8 12; do
if [ $precision -le 8 ]; then
RGBIMG=$IMGDIR/testorig.ppm
GRAYIMG=$IMGDIR/testorig.pgm
GRAYIMG=$IMGDIR/testorig.png
basename=testorig
else
RGBIMG=$IMGDIR/monkey16.ppm
RGBIMG=$IMGDIR/monkey16.png
GRAYIMG=$IMGDIR/monkey16.pgm
basename=monkey16
fi
for sampi in {0..6}; do
@@ -78,32 +80,26 @@ for precision in 8 12; do
EXTRA_ARGS="-r 1"
fi
runme $EXEDIR/cjpeg -pre $precision -sa ${SAMPOPT[$sampi]} $EXTRA_ARGS \
-outf $OUTDIR/`basename $RGBIMG .ppm`-${SUBSAMPOPT[$sampi]}.jpg $RGBIMG
-outf $OUTDIR/${basename}-${SUBSAMPOPT[$sampi]}.jpg $RGBIMG
if [[ $sampi = 3 || $sampi = 4 ]]; then
$EXEDIR/wrjpgcom -comment "This is a test" \
$OUTDIR/`basename $RGBIMG .ppm`-${SUBSAMPOPT[$sampi]}.jpg \
>$OUTDIR/temp.jpg
mv $OUTDIR/temp.jpg \
$OUTDIR/`basename $RGBIMG .ppm`-${SUBSAMPOPT[$sampi]}.jpg
$OUTDIR/${basename}-${SUBSAMPOPT[$sampi]}.jpg >$OUTDIR/temp.jpg
mv $OUTDIR/temp.jpg $OUTDIR/${basename}-${SUBSAMPOPT[$sampi]}.jpg
fi
done
runme $EXEDIR/cjpeg -pre $precision \
-outf $OUTDIR/`basename $GRAYIMG .pgm`-gray.jpg $GRAYIMG
-outf $OUTDIR/${basename}-gray.jpg $GRAYIMG
echo
for subsamp in ${SUBSAMPOPT[*]} gray; do
if [ "$subsamp" = "gray" ]; then
basename=`basename $GRAYIMG .pgm`
else
basename=`basename $RGBIMG .ppm`
fi
for ariarg in "" "-a"; do
for copyarg in "" "-c i" "-c n"; do
if [[ "$copyarg" = "-c n" && "$subsamp" != "411" && \
"$subsamp" != "420" ]]; then
continue
fi
if [[ "$copyarg" = "-c i" && "$subsamp" != "420" ]]; then
if [[ "$copyarg" = "-c i" && "$subsamp" != "420" && \
( "$subsamp" != "444" || $precision -eq 8 ) ]]; then
continue
fi
for croparg in "" "-cr 14x14+23+23" "-cr 21x21+4+4" "-cr 18x18+13+13" \

45
testimages/LICENSE.txt Normal file
View File

@@ -0,0 +1,45 @@
test1.icc and test3.icc are from Little CMS, which is
Copyright (c) 2023 Marti Maria Saguer
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject
to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-------------------------------------------------------------------------------
sRGB2014.icc, which is embedded in monkey12.jpg, monkey16.png, and
vgl_5674_0098.png, is
Copyright International Color Consortium, 2015
This profile is made available by the International Color Consortium, and may
be copied, distributed, embedded, made, used, and sold without restriction.
Altered versions of this profile shall have the original identification and
copyright information removed and shall not be misrepresented as the original
profile.
-------------------------------------------------------------------------------
testorig* and testimg* were part of the Independent JPEG Group's software and
are provided under the terms of the IJG License. (Refer to README.ijg.)
-------------------------------------------------------------------------------
Other images are provided under the terms of the Modified (3-clause) BSD
License. (Refer to LICENSE.md.)

BIN
testimages/monkey12.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
testimages/monkey16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

View File

@@ -1,20 +0,0 @@
Little CMS
Copyright (c) 1998-2011 Marti Maria Saguer
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,20 +0,0 @@
Little CMS
Copyright (c) 1998-2011 Marti Maria Saguer
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

File diff suppressed because one or more lines are too long

BIN
testimages/testorig.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB