From: Jiyong Date: Tue, 10 Dec 2024 01:28:16 +0000 (+0900) Subject: Imported Upstream version 3.0.4 X-Git-Tag: accepted/tizen/base/20241215.120030~1^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fupstream;p=platform%2Fupstream%2Flibjpeg-turbo.git Imported Upstream version 3.0.4 Change-Id: I133a0b36f5ada2d692b6d1043c0b8206cdaed8e8 --- diff --git a/BUILDING.md b/BUILDING.md index 6b484a1..e180483 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -8,14 +8,16 @@ Build Requirements ### All Systems -- [CMake](http://www.cmake.org) v2.8.12 or later +- [CMake](https://cmake.org) v2.8.12 or later -- [NASM](http://www.nasm.us) or [Yasm](http://yasm.tortall.net) +- [NASM](https://nasm.us) or [Yasm](https://yasm.tortall.net) (if building x86 or x86-64 SIMD extensions) * If using NASM, 2.13 or later is required. * If using Yasm, 1.2.0 or later is required. + * NASM 2.15 or later is required if building libjpeg-turbo with Intel + Control-flow Enforcement Technology (CET) support. * If building on macOS, NASM or Yasm can be obtained from - [MacPorts](http://www.macports.org/) or [Homebrew](http://brew.sh/). + [MacPorts](https://macports.org) or [Homebrew](https://brew.sh). - NOTE: Currently, if it is desirable to hide the SIMD function symbols in Mac executables or shared libraries that statically link with libjpeg-turbo, then NASM 2.14 or later or Yasm must be used when @@ -37,7 +39,7 @@ Build Requirements required. Most modern Linux distributions, as well as Solaris 10 and later, include JDK or OpenJDK. For other systems, you can obtain the Oracle Java Development Kit from - . + . * If using JDK 11 or later, CMake 3.10.x or later must also be used. @@ -67,14 +69,14 @@ Build Requirements - MinGW - [MSYS2](http://msys2.github.io/) or [tdm-gcc](http://tdm-gcc.tdragon.net/) + [MSYS2](https://msys2.org) or [tdm-gcc](https://jmeubank.github.io/tdm-gcc) recommended if building on a Windows machine. Both distributions install a Start Menu link that can be used to launch a command prompt with the appropriate compiler paths automatically set. - If building the TurboJPEG Java wrapper, JDK 1.5 or later is required. This can be downloaded from - . + . * If using JDK 11 or later, CMake 3.10.x or later must also be used. @@ -437,7 +439,7 @@ Building libjpeg-turbo for Android ---------------------------------- Building libjpeg-turbo for Android platforms requires v13b or later of the -[Android NDK](https://developer.android.com/tools/sdk/ndk). +[Android NDK](https://developer.android.com/ndk). ### Armv7 (32-bit) @@ -605,15 +607,6 @@ brackets, then its final value will depend on the final value of that other variable. For instance, the default value of `CMAKE_INSTALL_MANDIR` is **\/man**. -NOTE: If setting one of these directory variables to a relative path using the -CMake command line, you must specify that the variable is of type `PATH`. -For example: - - cmake -G"{generator type}" -DCMAKE_INSTALL_LIBDIR:PATH=lib {source_directory} - -Otherwise, CMake will assume that the path is relative to the build directory -rather than the install directory. - Creating Distribution Packages ============================== @@ -686,7 +679,7 @@ as the configuration you built (such as *{build_directory}*\Debug\ or *{build_directory}*\Release\). Building a Windows installer requires the -[Nullsoft Install System](http://nsis.sourceforge.net/). makensis.exe should +[Nullsoft Install System](https://nsis.sourceforge.io). makensis.exe should be in your `PATH`. diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad0718..d18298d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,12 @@ -cmake_minimum_required(VERSION 2.8.12) -# When using CMake 3.4 and later, don't export symbols from executables unless -# the CMAKE_ENABLE_EXPORTS variable is set. -if(POLICY CMP0065) - cmake_policy(SET CMP0065 NEW) -endif() +cmake_minimum_required(VERSION 2.8.12...3.28) if(CMAKE_EXECUTABLE_SUFFIX) set(CMAKE_EXECUTABLE_SUFFIX_TMP ${CMAKE_EXECUTABLE_SUFFIX}) endif() project(libjpeg-turbo C) -set(VERSION 3.0.1) -set(COPYRIGHT_YEAR "1991-2023") +set(VERSION 3.0.4) +set(COPYRIGHT_YEAR "1991-2024") string(REPLACE "." ";" VERSION_TRIPLET ${VERSION}) list(GET VERSION_TRIPLET 0 VERSION_MAJOR) list(GET VERSION_TRIPLET 1 VERSION_MINOR) @@ -222,25 +217,38 @@ option(ENABLE_SHARED "Build shared libraries" TRUE) boolean_number(ENABLE_SHARED) option(ENABLE_STATIC "Build static libraries" TRUE) boolean_number(ENABLE_STATIC) -option(REQUIRE_SIMD "Generate a fatal error if SIMD extensions are not available for this platform (default is to fall back to a non-SIMD build)" FALSE) +option(REQUIRE_SIMD + "Generate a fatal error if SIMD extensions are not available for this platform (default is to fall back to a non-SIMD build)" + FALSE) boolean_number(REQUIRE_SIMD) -option(WITH_ARITH_DEC "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" TRUE) +option(WITH_ARITH_DEC + "Include arithmetic decoding support when emulating the libjpeg v6b API/ABI" + TRUE) boolean_number(WITH_ARITH_DEC) -option(WITH_ARITH_ENC "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" TRUE) +option(WITH_ARITH_ENC + "Include arithmetic encoding support when emulating the libjpeg v6b API/ABI" + TRUE) boolean_number(WITH_ARITH_ENC) if(CMAKE_C_COMPILER_ABI MATCHES "ELF X32") set(WITH_JAVA 0) else() - option(WITH_JAVA "Build Java wrapper for the TurboJPEG API library (implies ENABLE_SHARED=1)" FALSE) + option(WITH_JAVA + "Build Java wrapper for the TurboJPEG API library (implies ENABLE_SHARED=1)" + FALSE) boolean_number(WITH_JAVA) endif() -option(WITH_JPEG7 "Emulate libjpeg v7 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" FALSE) +option(WITH_JPEG7 + "Emulate libjpeg v7 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" + FALSE) boolean_number(WITH_JPEG7) -option(WITH_JPEG8 "Emulate libjpeg v8 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" FALSE) +option(WITH_JPEG8 + "Emulate libjpeg v8 API/ABI (this makes ${CMAKE_PROJECT_NAME} backward-incompatible with libjpeg v6b)" + FALSE) boolean_number(WITH_JPEG8) option(WITH_SIMD "Include SIMD extensions, if available for this platform" TRUE) boolean_number(WITH_SIMD) -option(WITH_TURBOJPEG "Include the TurboJPEG API library and associated test programs" TRUE) +option(WITH_TURBOJPEG + "Include the TurboJPEG API library and associated test programs" TRUE) boolean_number(WITH_TURBOJPEG) option(WITH_FUZZ "Build fuzz targets" FALSE) @@ -301,12 +309,12 @@ endif() # 1: + In-memory source/destination managers (libjpeg-turbo 1.3.x) # 2: + Partial image decompression functions (libjpeg-turbo 1.5.x) # 3: + ICC functions (libjpeg-turbo 2.0.x) -# 4: + 12-bit-per-component and lossless functions (libjpeg-turbo 2.2.x) +# 4: + 12-bit-per-sample and lossless functions (libjpeg-turbo 3.0.x) # # libjpeg v8 API/ABI emulation: # 1: + Partial image decompression functions (libjpeg-turbo 1.5.x) # 2: + ICC functions (libjpeg-turbo 2.0.x) -# 3: + 12-bit-per-component and lossless functions (libjpeg-turbo 2.2.x) +# 3: + 12-bit-per-sample and lossless functions (libjpeg-turbo 3.0.x) set(SO_AGE 3) if(NOT WITH_JPEG8) set(SO_AGE 4) @@ -379,23 +387,38 @@ set(TURBOJPEG_SO_VERSION 0.${TURBOJPEG_SO_AGE}.0) # COMPILER SETTINGS ############################################################################### +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) + if(MSVC) option(WITH_CRT_DLL "Link all ${CMAKE_PROJECT_NAME} libraries and executables with the C run-time DLL (msvcr*.dll) instead of the static C run-time library (libcmt*.lib.) The default is to use the C run-time DLL only with the libraries and executables that need it." FALSE) + boolean_number(WITH_CRT_DLL) if(NOT WITH_CRT_DLL) # Use the static C library for all build types - foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) - if(${var} MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}") + if(CMAKE_VERSION VERSION_EQUAL "3.15" OR + CMAKE_VERSION VERSION_GREATER "3.15") + if(CMAKE_BUILD_TYPE_UC STREQUAL "DEBUG") + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebug) + elseif(MSVC_IDE) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded) endif() - endforeach() + message(STATUS "Visual C++ run-time library: ${CMAKE_MSVC_RUNTIME_LIBRARY} (WITH_CRT_DLL = ${WITH_CRT_DLL})") + else() + foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${var} MATCHES "/MD") + string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}") + endif() + endforeach() + endif() endif() add_definitions(-D_CRT_NONSTDC_NO_WARNINGS) endif() -if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang") +if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") # Use the maximum optimization level for release builds foreach(var CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELWITHDEBINFO) if(${var} MATCHES "-O2") @@ -418,8 +441,6 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") endif() endif() -string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) - set(EFFECTIVE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}") message(STATUS "Compiler flags = ${EFFECTIVE_C_FLAGS}") @@ -449,13 +470,13 @@ if(UNIX) check_c_source_runs(" #include #include - int is_shifting_signed (long arg) { + static int is_shifting_signed (long arg) { long res = arg >> 4; if (res == -0x7F7E80CL) return 1; /* right shift is signed */ /* see if unsigned-shift hack will fix it. */ /* we can't just test exact value since it depends on width of long... */ - res |= (~0L) << (32-4); + res |= 0xFFFFFFFFL << (32-4); if (res == -0x7F7E80CL) return 0; /* right shift is unsigned */ printf(\"Right shift isn't acting as I expect it to.\\\\n\"); @@ -468,6 +489,15 @@ if(UNIX) endif() endif() +if(NOT MSVC OR CMAKE_C_COMPILER_ID MATCHES "Clang") + check_c_source_compiles("extern const int table[1]; const int __attribute__((visibility(\"hidden\"))) table[1] = { 0 }; int main(void) { return table[0]; }" + HIDDEN_WORKS) + if(HIDDEN_WORKS) + set(HIDDEN "__attribute__((visibility(\"hidden\")))") + message(STATUS "HIDDEN = ${HIDDEN}") + endif() +endif() + if(MSVC) set(INLINE_OPTIONS "__inline;inline") else() @@ -501,7 +531,8 @@ if(MSVC) else() set(THREAD_LOCAL "__thread") endif() -check_c_source_compiles("${THREAD_LOCAL} int i; int main(void) { i = 0; return i; }" HAVE_THREAD_LOCAL) +check_c_source_compiles("static ${THREAD_LOCAL} int i; int main(void) { i = 0; return i; }" + HAVE_THREAD_LOCAL) if(HAVE_THREAD_LOCAL) message(STATUS "THREAD_LOCAL = ${THREAD_LOCAL}") else() @@ -572,7 +603,7 @@ set(JPEG_SOURCES ${JPEG12_SOURCES} jcapimin.c jchuff.c jcicc.c jcinit.c jclhuff.c jcmarker.c jcmaster.c jcomapi.c jcparam.c jcphuff.c jctrans.c jdapimin.c jdatadst.c jdatasrc.c jdhuff.c jdicc.c jdinput.c jdlhuff.c jdmarker.c jdmaster.c jdphuff.c jdtrans.c jerror.c jfdctflt.c jmemmgr.c - jmemnobs.c) + jmemnobs.c jpeg_nbits.c) if(WITH_ARITH_ENC OR WITH_ARITH_DEC) set(JPEG_SOURCES ${JPEG_SOURCES} jaricom.c) @@ -701,6 +732,9 @@ if(WITH_TURBOJPEG) add_executable(tjexample tjexample.c) target_link_libraries(tjexample turbojpeg) + + add_custom_target(tjdoc COMMAND doxygen -s doxygen.config + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) endif() if(ENABLE_STATIC) @@ -859,10 +893,8 @@ if(ENABLE_STATIC) endif() set(TESTIMAGES ${CMAKE_CURRENT_SOURCE_DIR}/testimages) -set(MD5CMP ${CMAKE_CURRENT_BINARY_DIR}/md5/md5cmp) if(CMAKE_CROSSCOMPILING) file(RELATIVE_PATH TESTIMAGES ${CMAKE_CURRENT_BINARY_DIR} ${TESTIMAGES}) - file(RELATIVE_PATH MD5CMP ${CMAKE_CURRENT_BINARY_DIR} ${MD5CMP}) endif() # The output of the floating point DCT/IDCT algorithms differs depending on the @@ -895,7 +927,7 @@ if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386") set(DEFAULT_FLOATTEST8 no-fp-contract) endif() elseif(CPU_TYPE STREQUAL "powerpc" OR CPU_TYPE STREQUAL "arm64") - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_C_COMPILER_VERSION VERSION_EQUAL 14.0.0 OR CMAKE_C_COMPILER_VERSION VERSION_GREATER 14.0.0) set(DEFAULT_FLOATTEST8 fp-contract) @@ -937,7 +969,7 @@ endif() if(CPU_TYPE STREQUAL "x86_64") set(DEFAULT_FLOATTEST12 no-fp-contract) elseif(CPU_TYPE STREQUAL "powerpc" OR CPU_TYPE STREQUAL "arm64") - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") if(CMAKE_C_COMPILER_VERSION VERSION_EQUAL 14.0.0 OR CMAKE_C_COMPILER_VERSION VERSION_GREATER 14.0.0) set(DEFAULT_FLOATTEST12 fp-contract) @@ -975,42 +1007,38 @@ foreach(libtype ${TEST_LIBTYPES}) set(suffix -static) endif() if(WITH_TURBOJPEG) - add_test(tjunittest-${libtype} - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix}) - add_test(tjunittest-${libtype}-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -alloc) - add_test(tjunittest-${libtype}-yuv - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv) - add_test(tjunittest-${libtype}-yuv-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -alloc) - add_test(tjunittest-${libtype}-yuv-nopad - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -yuv -noyuvpad) - add_test(tjunittest-${libtype}-lossless - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -lossless) - add_test(tjunittest-${libtype}-lossless-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -lossless -alloc) - add_test(tjunittest-${libtype}-bmp - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -bmp) - add_test(tjunittest12-${libtype} - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 12) - add_test(tjunittest12-${libtype}-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 12 - -alloc) - add_test(tjunittest12-${libtype}-lossless - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 12 - -lossless) - add_test(tjunittest12-${libtype}-lossless-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 12 - -lossless -alloc) - add_test(tjunittest12-${libtype}-bmp - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 12 -bmp) - add_test(tjunittest16-${libtype}-lossless - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 16) - add_test(tjunittest16-${libtype}-lossless-alloc - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 16 - -alloc) - add_test(tjunittest16-${libtype}-bmp - ${CMAKE_CROSSCOMPILING_EMULATOR} tjunittest${suffix} -precision 16 -bmp) + add_test(NAME tjunittest-${libtype} + COMMAND tjunittest${suffix}) + add_test(NAME tjunittest-${libtype}-alloc + COMMAND tjunittest${suffix} -alloc) + add_test(NAME tjunittest-${libtype}-yuv + COMMAND tjunittest${suffix} -yuv) + add_test(NAME tjunittest-${libtype}-yuv-alloc + COMMAND tjunittest${suffix} -yuv -alloc) + add_test(NAME tjunittest-${libtype}-yuv-nopad + COMMAND tjunittest${suffix} -yuv -noyuvpad) + add_test(NAME tjunittest-${libtype}-lossless + COMMAND tjunittest${suffix} -lossless) + add_test(NAME tjunittest-${libtype}-lossless-alloc + COMMAND tjunittest${suffix} -lossless -alloc) + add_test(NAME tjunittest-${libtype}-bmp + COMMAND tjunittest${suffix} -bmp) + add_test(NAME tjunittest12-${libtype} + COMMAND tjunittest${suffix} -precision 12) + add_test(NAME tjunittest12-${libtype}-alloc + COMMAND tjunittest${suffix} -precision 12 -alloc) + add_test(NAME tjunittest12-${libtype}-lossless + COMMAND tjunittest${suffix} -precision 12 -lossless) + add_test(NAME tjunittest12-${libtype}-lossless-alloc + COMMAND tjunittest${suffix} -precision 12 -lossless -alloc) + add_test(NAME tjunittest12-${libtype}-bmp + COMMAND tjunittest${suffix} -precision 12 -bmp) + add_test(NAME tjunittest16-${libtype}-lossless + COMMAND tjunittest${suffix} -precision 16) + add_test(NAME tjunittest16-${libtype}-lossless-alloc + COMMAND tjunittest${suffix} -precision 16 -alloc) + add_test(NAME tjunittest16-${libtype}-bmp + COMMAND tjunittest${suffix} -precision 16 -bmp) foreach(sample_bits 8 12) @@ -1056,30 +1084,29 @@ foreach(libtype ${TEST_LIBTYPES}) set(MD5_PPM_444_TILE 87bd58005eec73f0f313c8e38d0d793c) endif() - # Test compressing from/decompressing to an arbitrary subregion of a larger - # image buffer - add_test(${tjbench}-${libtype}-tile-cp - ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm - ${testout}_tile.ppm) - add_test(${tjbench}-${libtype}-tile - ${CMAKE_CROSSCOMPILING_EMULATOR} tjbench${suffix} ${testout}_tile.ppm - 95 -precision ${sample_bits} -rgb -quiet -tile -benchtime 0.01 + # Test compressing from/decompressing to an arbitrary subregion of a + # larger image buffer + add_test(NAME ${tjbench}-${libtype}-tile-cp + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${TESTIMAGES}/testorig.ppm ${testout}_tile.ppm) + add_test(NAME ${tjbench}-${libtype}-tile + COMMAND tjbench${suffix} ${testout}_tile.ppm 95 + -precision ${sample_bits} -rgb -quiet -tile -benchtime 0.01 -warmup 0) set_tests_properties(${tjbench}-${libtype}-tile PROPERTIES DEPENDS ${tjbench}-${libtype}-tile-cp) foreach(tile 8 16 32 64 128) - add_test(${tjbench}-${libtype}-tile-gray-${tile}x${tile}-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_GRAY_TILE} + 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) foreach(subsamp 420 422) - add_test(${tjbench}-${libtype}-tile-${subsamp}-${tile}x${tile}-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} - ${MD5_PPM_${subsamp}_${tile}x${tile}_TILE} + 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) endforeach() - add_test(${tjbench}-${libtype}-tile-444-${tile}x${tile}-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_444_TILE} + 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) foreach(subsamp gray 420 422 444) set_tests_properties( @@ -1088,27 +1115,26 @@ foreach(libtype ${TEST_LIBTYPES}) endforeach() endforeach() - add_test(${tjbench}-${libtype}-tilem-cp - ${CMAKE_COMMAND} -E copy_if_different ${TESTIMAGES}/testorig.ppm - ${testout}_tilem.ppm) - add_test(${tjbench}-${libtype}-tilem - ${CMAKE_CROSSCOMPILING_EMULATOR} tjbench${suffix} ${testout}_tilem.ppm - 95 -precision ${sample_bits} -rgb -fastupsample -quiet -tile + add_test(NAME ${tjbench}-${libtype}-tilem-cp + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${TESTIMAGES}/testorig.ppm ${testout}_tilem.ppm) + add_test(NAME ${tjbench}-${libtype}-tilem + COMMAND tjbench${suffix} ${testout}_tilem.ppm 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(${tjbench}-${libtype}-tile-420m-8x8-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_420M_8x8_TILE} + add_test(NAME ${tjbench}-${libtype}-tile-420m-8x8-cmp + COMMAND md5cmp ${MD5_PPM_420M_8x8_TILE} ${testout}_tilem_420_Q95_8x8.ppm) - add_test(${tjbench}-${libtype}-tile-422m-8x8-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_422M_8x8_TILE} + add_test(NAME ${tjbench}-${libtype}-tile-422m-8x8-cmp + COMMAND md5cmp ${MD5_PPM_422M_8x8_TILE} ${testout}_tilem_422_Q95_8x8.ppm) foreach(tile 16 32 64 128) foreach(subsamp 420 422) - add_test(${tjbench}-${libtype}-tile-${subsamp}m-${tile}x${tile}-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} - ${MD5_PPM_${subsamp}M_TILE} + 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) endforeach() endforeach() @@ -1138,11 +1164,11 @@ foreach(libtype ${TEST_LIBTYPES}) endif() string(REGEX REPLACE "16" "" ACTUAL_PROG ${PROG}) string(REGEX REPLACE "12" "" ACTUAL_PROG ${ACTUAL_PROG}) - add_test(${PROG}-${libtype}-${NAME} - ${CMAKE_CROSSCOMPILING_EMULATOR} ${ACTUAL_PROG}${suffix} ${ACTUAL_ARGS} - -outfile ${OUTFILE} ${INFILE}) - add_test(${PROG}-${libtype}-${NAME}-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5SUM} ${OUTFILE}) + add_test(NAME ${PROG}-${libtype}-${NAME} + COMMAND ${ACTUAL_PROG}${suffix} ${ACTUAL_ARGS} -outfile ${OUTFILE} + ${INFILE}) + add_test(NAME ${PROG}-${libtype}-${NAME}-cmp + COMMAND md5cmp ${MD5SUM} ${OUTFILE}) set_tests_properties(${PROG}-${libtype}-${NAME}-cmp PROPERTIES DEPENDS ${PROG}-${libtype}-${NAME}) if(${ARGC} GREATER 6) @@ -1176,7 +1202,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(TESTORIG testorig12.jpg) set(MD5_JPEG_RGB_ISLOW 9d7369207c520d37f2c1cbfcb82b2964) - set(MD5_JPEG_RGB_ISLOW2 a00bd20d8ae49684640ef7177d2e0b64) + 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) @@ -1198,7 +1224,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(MD5_PPM_3x2_FLOAT_NO_FP_CONTRACT ${MD5_PPM_3x2_FLOAT_SSE}) set(MD5_JPEG_3x2_FLOAT_PROG_FP_CONTRACT ${MD5_JPEG_3x2_FLOAT_PROG_NO_FP_CONTRACT}) - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(MD5_PPM_3x2_FLOAT_FP_CONTRACT 2da9de6ae869e88b8372de815d366b03) else() set(MD5_PPM_3x2_FLOAT_FP_CONTRACT ${MD5_PPM_3x2_FLOAT_SSE}) @@ -1233,7 +1259,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(MD5_JPEG_CROP cdb35ff4b4519392690ea040c56ea99c) set(MD5_JPEG_EXAMPLE_COMPRESS 5e502da0c3c0f957a58c536f31e973dc) - set(MD5_PPM_EXAMPLE_DECOMPRESS 2ff0e8505ee6e0ffaeb24037d5650b57) + set(MD5_PPM_EXAMPLE_DECOMPRESS 70194fdcb73370ee7ba0db868d0c6fc8) else() set(cjpeg cjpeg) set(djpeg djpeg) @@ -1242,7 +1268,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(TESTORIG testorig.jpg) set(MD5_JPEG_RGB_ISLOW 1d44a406f61da743b5fd31c0a9abdca3) - set(MD5_JPEG_RGB_ISLOW2 31d121e57b6c2934c890a7fc7763bcd4) + set(MD5_JPEG_RGB_ISLOW2 b811e5ad807beb9384e51ef6a47f715d) set(MD5_PPM_RGB_ISLOW 00a257f5393fef8821f2b88ac7421291) set(MD5_BMP_RGB_ISLOW_565 f07d2e75073e4bb10f6c6f4d36e2e3be) set(MD5_BMP_RGB_ISLOW_565D 4cfa0928ef3e6bb626d7728c924cfda4) @@ -1270,7 +1296,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(MD5_PPM_3x2_FLOAT_NO_FP_CONTRACT f6bfab038438ed8f5522fbd33595dcdc) set(MD5_JPEG_3x2_FLOAT_PROG_FP_CONTRACT ${MD5_JPEG_3x2_FLOAT_PROG_NO_FP_CONTRACT}) - if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(MD5_PPM_3x2_FLOAT_FP_CONTRACT ${MD5_PPM_3x2_FLOAT_NO_FP_CONTRACT}) else() set(MD5_PPM_3x2_FLOAT_FP_CONTRACT 0e917a34193ef976b679a6b069b1be26) @@ -1317,7 +1343,7 @@ foreach(libtype ${TEST_LIBTYPES}) set(MD5_JPEG_CROP b4197f377e621c4e9b1d20471432610d) set(MD5_JPEG_EXAMPLE_COMPRESS 95d4d72e2ef127332654c2599afb47bf) - set(MD5_PPM_EXAMPLE_DECOMPRESS 6fdde7301575bfd711e295b969b6b3de) + set(MD5_PPM_EXAMPLE_DECOMPRESS dea1d7bbc37e39adf628342c86096641) endif() # CC: null SAMP: fullsize FDCT: islow ENT: huff @@ -1331,13 +1357,12 @@ foreach(libtype ${TEST_LIBTYPES}) ${testout}_rgb_islow.ppm ${testout}_rgb_islow.jpg ${MD5_PPM_RGB_ISLOW} ${cjpeg}-${libtype}-rgb-islow) - add_test(${djpeg}-${libtype}-rgb-islow-icc-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} - b06a39d730129122e85c1363ed1bbc9e ${testout}_rgb_islow.icc) + add_test(NAME ${djpeg}-${libtype}-rgb-islow-icc-cmp + COMMAND md5cmp b06a39d730129122e85c1363ed1bbc9e ${testout}_rgb_islow.icc) set_tests_properties(${djpeg}-${libtype}-rgb-islow-icc-cmp PROPERTIES DEPENDS ${djpeg}-${libtype}-rgb-islow) - add_bittest(${jpegtran} icc "-copy;all;-icc;${TESTIMAGES}/test2.icc" + add_bittest(${jpegtran} icc "-copy;all;-icc;${TESTIMAGES}/test3.icc" ${testout}_rgb_islow2.jpg ${testout}_rgb_islow.jpg ${MD5_JPEG_RGB_ISLOW2} ${cjpeg}-${libtype}-rgb-islow) @@ -1577,10 +1602,9 @@ foreach(libtype ${TEST_LIBTYPES}) # Context rows: Yes Intra-iMCU row: No iMCU row prefetch: No # ENT: prog huff - add_test(${cjpeg}-${libtype}-420-islow-prog - ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -prog - -precision ${sample_bits} -outfile ${testout}_420_islow_prog.jpg - ${TESTIMAGES}/testorig.ppm) + 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) add_bittest(${djpeg} 420-islow-prog-crop62x62_71_71 "-dct;int;-crop;62x62+71+71;-ppm" ${testout}_420_islow_prog_crop62x62,71,71.ppm @@ -1597,19 +1621,18 @@ foreach(libtype ${TEST_LIBTYPES}) endif() # Context rows: No Intra-iMCU row: Yes ENT: huff - add_test(${cjpeg}-${libtype}-444-islow - ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -sample 1x1 - -precision ${sample_bits} -outfile ${testout}_444_islow.jpg - ${TESTIMAGES}/testorig.ppm) + 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) # Context rows: No Intra-iMCU row: No ENT: prog huff - add_test(${cjpeg}-${libtype}-444-islow-prog - ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -prog - -precision ${sample_bits} -sample 1x1 - -outfile ${testout}_444_islow_prog.jpg ${TESTIMAGES}/testorig.ppm) + 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) add_bittest(${djpeg} 444-islow-prog-crop98x98_13_13 "-dct;int;-crop;98x98+13+13;-ppm" ${testout}_444_islow_prog_crop98x98,13,13.ppm @@ -1618,10 +1641,10 @@ foreach(libtype ${TEST_LIBTYPES}) # Context rows: No Intra-iMCU row: No ENT: arith if(WITH_ARITH_ENC AND sample_bits EQUAL 8) - add_test(${cjpeg}-${libtype}-444-islow-ari - ${CMAKE_CROSSCOMPILING_EMULATOR} cjpeg${suffix} -dct int -arithmetic - -sample 1x1 -precision ${sample_bits} - -outfile ${testout}_444_islow_ari.jpg ${TESTIMAGES}/testorig.ppm) + 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) if(WITH_ARITH_DEC) add_bittest(${djpeg} 444-islow-ari-crop37x37_0_0 "-dct;int;-crop;37x37+0+0;-ppm" @@ -1640,23 +1663,19 @@ foreach(libtype ${TEST_LIBTYPES}) set(EXAMPLE_12BIT_ARG "-precision;12") endif() - add_test(example-${sample_bits}bit-${libtype}-compress - ${CMAKE_CROSSCOMPILING_EMULATOR} example${suffix} compress -q 95 - ${EXAMPLE_12BIT_ARG} ${testout}-example.jpg) - add_test(example-${sample_bits}bit-${libtype}-compress-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_JPEG_EXAMPLE_COMPRESS} + add_test(NAME example-${sample_bits}bit-${libtype}-compress + COMMAND example${suffix} compress -q 95 ${EXAMPLE_12BIT_ARG} ${testout}-example.jpg) + add_test(NAME example-${sample_bits}bit-${libtype}-compress-cmp + COMMAND md5cmp ${MD5_JPEG_EXAMPLE_COMPRESS} ${testout}-example.jpg) set_tests_properties(example-${sample_bits}bit-${libtype}-compress-cmp PROPERTIES DEPENDS example-${sample_bits}bit-${libtype}-compress) - add_test(example-${sample_bits}bit-${libtype}-decompress - ${CMAKE_CROSSCOMPILING_EMULATOR} example${suffix} decompress - ${EXAMPLE_12BIT_ARG} ${testout}-example.jpg ${testout}-example.ppm) - set_tests_properties(example-${sample_bits}bit-${libtype}-decompress - PROPERTIES DEPENDS example-${sample_bits}bit-${libtype}-compress) - add_test(example-${sample_bits}bit-${libtype}-decompress-cmp - ${CMAKE_CROSSCOMPILING_EMULATOR} ${MD5CMP} ${MD5_PPM_EXAMPLE_DECOMPRESS} - ${testout}-example.ppm) + add_test(NAME example-${sample_bits}bit-${libtype}-decompress + COMMAND example${suffix} decompress ${EXAMPLE_12BIT_ARG} + ${TESTIMAGES}/${TESTORIG} ${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 PROPERTIES DEPENDS example-${sample_bits}bit-${libtype}-decompress) @@ -1706,21 +1725,21 @@ if(WITH_TURBOJPEG) if(ENABLE_SHARED) install(TARGETS turbojpeg EXPORT ${CMAKE_PROJECT_NAME}Targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin) install(TARGETS tjbench - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin) if(NOT CMAKE_VERSION VERSION_LESS "3.1" AND MSVC AND CMAKE_C_LINKER_SUPPORTS_PDB) install(FILES "$" - DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin OPTIONAL) endif() endif() if(ENABLE_STATIC) install(TARGETS turbojpeg-static EXPORT ${CMAKE_PROJECT_NAME}Targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib) if(NOT ENABLE_SHARED) if(GENERATOR_IS_MULTI_CONFIG) set(DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}") @@ -1728,17 +1747,17 @@ if(WITH_TURBOJPEG) set(DIR ${CMAKE_CURRENT_BINARY_DIR}) endif() install(PROGRAMS ${DIR}/tjbench-static${EXE} - DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME tjbench${EXE}) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin RENAME tjbench${EXE}) endif() endif() install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/turbojpeg.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT include) endif() if(ENABLE_STATIC) install(TARGETS jpeg-static EXPORT ${CMAKE_PROJECT_NAME}Targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib) if(NOT ENABLE_SHARED) if(GENERATOR_IS_MULTI_CONFIG) set(DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CMAKE_INSTALL_CONFIG_NAME}") @@ -1746,15 +1765,16 @@ if(ENABLE_STATIC) set(DIR ${CMAKE_CURRENT_BINARY_DIR}) endif() install(PROGRAMS ${DIR}/cjpeg-static${EXE} - DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME cjpeg${EXE}) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin RENAME cjpeg${EXE}) install(PROGRAMS ${DIR}/djpeg-static${EXE} - DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME djpeg${EXE}) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin RENAME djpeg${EXE}) install(PROGRAMS ${DIR}/jpegtran-static${EXE} - DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME jpegtran${EXE}) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin RENAME jpegtran${EXE}) endif() endif() -install(TARGETS rdjpgcom wrjpgcom RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +install(TARGETS rdjpgcom wrjpgcom + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.ijg ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/example.c @@ -1762,10 +1782,11 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.ijg ${CMAKE_CURRENT_SOURCE_DIR}/libjpeg.txt ${CMAKE_CURRENT_SOURCE_DIR}/structure.txt ${CMAKE_CURRENT_SOURCE_DIR}/usage.txt ${CMAKE_CURRENT_SOURCE_DIR}/wizard.txt - ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR}) + ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md DESTINATION ${CMAKE_INSTALL_DOCDIR} + COMPONENT doc) if(WITH_JAVA) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/java/TJExample.java - DESTINATION ${CMAKE_INSTALL_DOCDIR}) + DESTINATION ${CMAKE_INSTALL_DOCDIR} COMPONENT doc) endif() if(UNIX OR MINGW) @@ -1773,26 +1794,28 @@ if(UNIX OR MINGW) ${CMAKE_CURRENT_SOURCE_DIR}/djpeg.1 ${CMAKE_CURRENT_SOURCE_DIR}/jpegtran.1 ${CMAKE_CURRENT_SOURCE_DIR}/rdjpgcom.1 ${CMAKE_CURRENT_SOURCE_DIR}/wrjpgcom.1 - DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT man) endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libjpeg.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT lib) if(WITH_TURBOJPEG) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/libturbojpeg.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT lib) endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/${CMAKE_PROJECT_NAME}Config.cmake ${CMAKE_CURRENT_BINARY_DIR}/pkgscripts/${CMAKE_PROJECT_NAME}ConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME} + COMPONENT lib) install(EXPORT ${CMAKE_PROJECT_NAME}Targets NAMESPACE ${CMAKE_PROJECT_NAME}:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME}) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME} + COMPONENT lib) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/jconfig.h ${CMAKE_CURRENT_SOURCE_DIR}/jerror.h ${CMAKE_CURRENT_SOURCE_DIR}/jmorecfg.h ${CMAKE_CURRENT_SOURCE_DIR}/jpeglib.h - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT include) include(cmakescripts/BuildPackages.cmake) diff --git a/ChangeLog.md b/ChangeLog.md index a466785..8b1ebd8 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,3 +1,120 @@ +3.0.4 +===== + +### Significant changes relative to 3.0.3: + +1. Fixed an issue whereby the CPU usage of the default marker processor in the +decompressor grew exponentially with the number of markers. This caused an +unreasonable slow-down in `jpeg_read_header()` if an application called +`jpeg_save_markers()` to save markers of a particular type and then attempted +to decompress a JPEG image containing an excessive number of markers of that +type. + +2. Hardened the default marker processor in the decompressor to guard against +an issue (exposed by 3.0 beta2[6]) whereby attempting to decompress a +specially-crafted malformed JPEG image (specifically an image with a complete +12-bit-per-sample Start Of Frame segment followed by an incomplete +8-bit-per-sample Start Of Frame segment) using buffered-image mode and input +prefetching caused a segfault if the `fill_input_buffer()` method in the +calling application's custom source manager incorrectly returned `FALSE` in +response to a prematurely-terminated JPEG data stream. + +3. Fixed an issue in cjpeg whereby, when generating a 12-bit-per-sample or +16-bit-per-sample lossless JPEG image, specifying a point transform value +greater than 7 resulted in an error ("Invalid progressive/lossless parameters") +unless the `-precision` option was specified before the `-lossless` option. + +4. Fixed a regression introduced by 3.0.3[3] that made it impossible for +calling applications to generate 12-bit-per-sample arithmetic-coded lossy JPEG +images using the TurboJPEG API. + +5. Fixed an error ("Destination buffer is not large enough") that occurred when +attempting to generate a full-color lossless JPEG image using the TurboJPEG +Java API's `byte[] TJCompressor.compress()` method if the value of +`TJ.PARAM_SUBSAMP` was not `TJ.SAMP_444`. + +6. Fixed a segfault in djpeg that occurred if a negative width was specified +with the `-crop` option. Since the cropping region width was read into an +unsigned 32-bit integer, a negative width was interpreted as a very large +value. With certain negative width and positive left boundary values, the +bounds checks in djpeg and `jpeg_crop_scanline()` overflowed and did not detect +the out-of-bounds width, which caused a buffer overrun in the upsampling or +color conversion routine. Both bounds checks now use 64-bit integers to guard +against overflow, and djpeg now checks for negative numbers when it parses the +crop specification from the command line. + +7. Fixed an issue whereby the TurboJPEG lossless transformation function and +methods checked the specified cropping region against the source image +dimensions and level of chrominance subsampling rather than the destination +image dimensions and level of chrominance subsampling, which caused some +cropping regions to be unduly rejected when performing 90-degree rotation, +270-degree rotation, transposition, transverse transposition, or grayscale +conversion. + +8. Fixed an issue whereby the TurboJPEG lossless transformation function and +methods did not honor `TJXOPT_COPYNONE`/`TJTransform.OPT_COPYNONE` unless it +was specified for all lossless transforms. + + +3.0.3 +===== + +### Significant changes relative to 3.0.2: + +1. Fixed an issue in the build system, introduced in 3.0.2, that caused all +libjpeg-turbo components to depend on the Visual C++ run-time DLL when built +with Visual C++ and CMake 3.15 or later, regardless of value of the +`WITH_CRT_DLL` CMake variable. + +2. The x86-64 SIMD extensions now include support for Intel Control-flow +Enforcement Technology (CET), which is enabled automatically if CET is enabled +in the C compiler. + +3. Fixed a regression introduced by 3.0 beta2[6] that made it impossible for +calling applications to supply custom Huffman tables when generating +12-bit-per-component lossy JPEG images using the libjpeg API. + +4. Fixed a segfault that occurred when attempting to use the jpegtran `-drop` +option with a specially-crafted malformed input image or drop image +(specifically an image in which all of the scans contain fewer components than +the number of components specified in the Start Of Frame segment.) + + +3.0.2 +===== + +### Significant changes relative to 3.0.1: + +1. Fixed a signed integer overflow in the `tj3CompressFromYUV8()`, +`tj3DecodeYUV8()`, `tj3DecompressToYUV8()`, and `tj3EncodeYUV8()` functions, +detected by the Clang and GCC undefined behavior sanitizers, that could be +triggered by setting the `align` parameter to an unreasonably large value. +This issue did not pose a security threat, but removing the warning made it +easier to detect actual security issues, should they arise in the future. + +2. Introduced a new parameter (`TJPARAM_MAXMEMORY` in the TurboJPEG C API and +`TJ.PARAM_MAXMEMORY` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxmemory`) for specifying the maximum amount of memory (in +megabytes) that will be allocated for intermediate buffers, which are used with +progressive JPEG compression and decompression, Huffman table optimization, +lossless JPEG compression, and lossless transformation. The new parameter and +option serve the same purpose as the `max_memory_to_use` field in the +`jpeg_memory_mgr` struct in the libjpeg API, the `JPEGMEM` environment +variable, and the cjpeg/djpeg/jpegtran `-maxmemory` option. + +3. Introduced a new parameter (`TJPARAM_MAXPIXELS` in the TurboJPEG C API and +`TJ.PARAM_MAXPIXELS` in the TurboJPEG Java API) and a corresponding TJBench +option (`-maxpixels`) for specifying the maximum number of pixels that the +decompression, lossless transformation, and packed-pixel image loading +functions/methods will process. + +4. Fixed an error ("Unsupported color conversion request") that occurred when +attempting to decompress a 3-component lossless JPEG image without an Adobe +APP14 marker. The decompressor now assumes that a 3-component lossless JPEG +image without an Adobe APP14 marker uses the RGB colorspace if its component +IDs are 1, 2, and 3. + + 3.0.1 ===== @@ -9,7 +126,7 @@ within the functions. 2. Fixed two minor issues in the interblock smoothing algorithm that caused mathematical (but not necessarily perceptible) edge block errors when -decompressing progressive JPEG images exactly two MCU blocks in width or that +decompressing progressive JPEG images exactly two DCT blocks in width or that use vertical chrominance subsampling. 3. Fixed a regression introduced by 3.0 beta2[6] that, in rare cases, caused @@ -120,11 +237,10 @@ through pointer arguments. - `TJFLAG_LIMITSCANS`/`TJ.FLAG_LIMITSCANS` has been reimplemented as an API parameter (`TJPARAM_SCANLIMIT`/`TJ.PARAM_SCANLIMIT`) that allows the number of scans to be specified. - - Optimized baseline entropy coding (the computation of optimal Huffman -tables, as opposed to using the default Huffman tables) can now be specified, -using a new API parameter (`TJPARAM_OPTIMIZE`/`TJ.PARAM_OPTIMIZE`), a new -transform option (`TJXOPT_OPTIMIZE`/`TJTransform.OPT_OPTIMIZE`), and a new -TJBench option (`-optimize`.) + - Huffman table optimization can now be specified using a new API +parameter (`TJPARAM_OPTIMIZE`/`TJ.PARAM_OPTIMIZE`), a new transform option +(`TJXOPT_OPTIMIZE`/`TJTransform.OPT_OPTIMIZE`), and a new TJBench option +(`-optimize`.) - Arithmetic entropy coding can now be specified or queried, using a new API parameter (`TJPARAM_ARITHMETIC`/`TJ.PARAM_ARITHMETIC`), a new transform option (`TJXOPT_ARITHMETIC`/`TJTransform.OPT_ARITHMETIC`), and a new TJBench @@ -367,9 +483,9 @@ prevented libjpeg-turbo from working properly with other linkers and also represented a potential security risk. 2. Fixed an issue whereby the `tjTransform()` function incorrectly computed the -MCU block size for 4:4:4 JPEG images with non-unary sampling factors and thus -unduly rejected some cropping regions, even though those regions aligned with -8x8 MCU block boundaries. +iMCU size for 4:4:4 JPEG images with non-unary sampling factors and thus unduly +rejected some cropping regions, even though those regions aligned with 8x8 iMCU +boundaries. 3. Fixed a regression introduced by 2.1 beta1[13] that caused the build system to enable the Arm Neon SIMD extensions when targetting Armv6 and other legacy @@ -951,16 +1067,15 @@ encounters a warning from the underlying libjpeg API (the default behavior is to allow the operation to complete unless a fatal error is encountered.) 5. Introduced a new flag in the TurboJPEG C and Java APIs (`TJFLAG_PROGRESSIVE` -and `TJ.FLAG_PROGRESSIVE`, respectively) that causes the library to use -progressive entropy coding in JPEG images generated by compression and -transform operations. Additionally, a new transform option -(`TJXOPT_PROGRESSIVE` in the C API and `TJTransform.OPT_PROGRESSIVE` in the -Java API) has been introduced, allowing progressive entropy coding to be -enabled for selected transforms in a multi-transform operation. +and `TJ.FLAG_PROGRESSIVE`, respectively) that causes compression and transform +operations to generate progressive JPEG images. Additionally, a new transform +option (`TJXOPT_PROGRESSIVE` in the C API and `TJTransform.OPT_PROGRESSIVE` in +the Java API) has been introduced, allowing progressive JPEG images to be +generated by selected transforms in a multi-transform operation. 6. Introduced a new transform option in the TurboJPEG API (`TJXOPT_COPYNONE` in the C API and `TJTransform.OPT_COPYNONE` in the Java API) that allows the -copying of markers (including EXIF and ICC profile data) to be disabled for a +copying of markers (including Exif and ICC profile data) to be disabled for a particular transform. 7. Added two functions to the TurboJPEG C API (`tjLoadImage()` and @@ -1091,13 +1206,13 @@ bug that has existed since the introduction of libjpeg v7/v8 API/ABI emulation in libjpeg-turbo v1.1. 7. The lossless transform features in jpegtran and the TurboJPEG API will now -always attempt to adjust the EXIF image width and height tags if the image size +always attempt to adjust the Exif image width and height tags if the image size changed as a result of the transform. This behavior has always existed when using libjpeg v8 API/ABI emulation. It was supposed to be available with libjpeg v7 API/ABI emulation as well but did not work properly due to a bug. Furthermore, there was never any good reason not to enable it with libjpeg v6b API/ABI emulation, since the behavior is entirely internal. Note that -`-copy all` must be passed to jpegtran in order to transfer the EXIF tags from +`-copy all` must be passed to jpegtran in order to transfer the Exif tags from the source image to the destination image. 8. Fixed several memory leaks in the TurboJPEG API library that could occur @@ -1119,7 +1234,7 @@ for two reasons: it allows testers to more easily work around the 2 GB limit in libFuzzer, and it allows developers of security-sensitive applications to more easily defend against one of the progressive JPEG exploits (LJT-01-004) identified in -[this report](http://www.libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf). +[this report](https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf). 10. TJBench will now run each benchmark for 1 second prior to starting the timer, in order to improve the consistency of the results. Furthermore, the @@ -2146,7 +2261,7 @@ and unit tests now work on those architectures. 0.0.93 ====== -### Significant changes since 0.0.91: +### Significant changes relative to 0.0.91: 1. 2982659: Fixed x86-64 build on FreeBSD systems diff --git a/LICENSE.md b/LICENSE.md index bf8a7fd..2204864 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,30 +1,33 @@ libjpeg-turbo Licenses ====================== -libjpeg-turbo is covered by three compatible BSD-style open source licenses: +libjpeg-turbo is covered by two compatible BSD-style open source licenses: - The IJG (Independent JPEG Group) License, which is listed in [README.ijg](README.ijg) - This license applies to the libjpeg API library and associated programs - (any code inherited from libjpeg, and any modifications to that code.) + 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. - The Modified (3-clause) BSD License, which is listed below - This license covers the TurboJPEG API library and associated programs, as - well as the build system. - -- The [zlib License](https://opensource.org/licenses/Zlib) - - This license is a subset of the other two, and it covers the libjpeg-turbo - SIMD extensions. + 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. Complying with the libjpeg-turbo Licenses ========================================= This section provides a roll-up of the libjpeg-turbo licensing terms, to the -best of our understanding. +best of our understanding. This is not a license in and of itself. It is +intended solely for clarification. 1. If you are distributing a modified version of the libjpeg-turbo source, then: @@ -38,7 +41,7 @@ best of our understanding. - 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 + file you modified, so others can tell that you modified that file. (If there is not an existing copyright header in that file, then you can simply add a notice stating that you modified the file.) @@ -119,8 +122,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -Why Three Licenses? -=================== +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 diff --git a/README.ijg b/README.ijg index 8f37682..1be3595 100644 --- a/README.ijg +++ b/README.ijg @@ -89,9 +89,9 @@ The library is intended to be reused in other applications. In order to support file conversion and viewing software, we have included considerable functionality beyond the bare JPEG coding/decoding capability; for example, the color quantization modules are not strictly part of JPEG -decoding, but they are essential for output to colormapped file formats or -colormapped displays. These extra functions can be compiled out of the -library if not required for a particular application. +decoding, but they are essential for output to colormapped file formats. These +extra functions can be compiled out of the library if not required for a +particular application. We have also included "jpegtran", a utility for lossless transcoding between different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple diff --git a/README.md b/README.md index 923e61d..17c8412 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,8 @@ JPEG images: top of the TurboJPEG API. The TurboJPEG API is recommended for first-time users of libjpeg-turbo. Refer to [tjexample.c](tjexample.c) and [TJExample.java](java/TJExample.java) for examples of its usage and to - for API documentation. + for API + documentation. - **libjpeg API**
This is the de facto industry-standard API for compressing and decompressing @@ -199,7 +200,7 @@ supported and which aren't. NOTE: As of this writing, extensive research has been conducted into the usefulness of DCT scaling as a means of data reduction and SmartScale as a means of quality improvement. Readers are invited to peruse the research at - and draw their own conclusions, + and draw their own conclusions, but it is the general belief of our project that these features have not demonstrated sufficient usefulness to justify inclusion in libjpeg-turbo. diff --git a/cderror.h b/cderror.h index 2844346..cd3e806 100644 --- a/cderror.h +++ b/cderror.h @@ -5,7 +5,7 @@ * Copyright (C) 1994-1997, Thomas G. Lane. * Modified 2009-2017 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2021, D. R. Commander. + * Copyright (C) 2021, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -42,7 +42,6 @@ typedef enum { JMESSAGE(JMSG_FIRSTADDONCODE = 1000, NULL) /* Must be first entry! */ -#ifdef BMP_SUPPORTED JMESSAGE(JERR_BMP_BADCMAP, "Unsupported BMP colormap format") JMESSAGE(JERR_BMP_BADDEPTH, "Only 8-, 24-, and 32-bit BMP files are supported") JMESSAGE(JERR_BMP_BADHEADER, "Invalid BMP file: bad header length") @@ -56,9 +55,7 @@ JMESSAGE(JTRC_BMP, "%ux%u %d-bit BMP image") JMESSAGE(JTRC_BMP_MAPPED, "%ux%u 8-bit colormapped BMP image") JMESSAGE(JTRC_BMP_OS2, "%ux%u %d-bit OS2 BMP image") JMESSAGE(JTRC_BMP_OS2_MAPPED, "%ux%u 8-bit colormapped OS2 BMP image") -#endif /* BMP_SUPPORTED */ -#ifdef GIF_SUPPORTED JMESSAGE(JERR_GIF_BUG, "GIF output got confused") JMESSAGE(JERR_GIF_CODESIZE, "Bogus GIF codesize %d") JMESSAGE(JERR_GIF_COLORSPACE, "GIF output must be grayscale or RGB") @@ -74,29 +71,23 @@ JMESSAGE(JWRN_GIF_BADDATA, "Corrupt data in GIF file") 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") -#endif /* GIF_SUPPORTED */ -#ifdef PPM_SUPPORTED 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") JMESSAGE(JERR_PPM_OUTOFRANGE, "Numeric value out of range in PPM file") -JMESSAGE(JTRC_PGM, "%ux%u PGM image") -JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") -JMESSAGE(JTRC_PPM, "%ux%u PPM image") -JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image") -#endif /* PPM_SUPPORTED */ +JMESSAGE(JTRC_PGM, "%ux%u PGM image (maximum color value = %u)") +JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image (maximum color value = %u)") +JMESSAGE(JTRC_PPM, "%ux%u PPM image (maximum color value = %u)") +JMESSAGE(JTRC_PPM_TEXT, "%ux%u text PPM image (maximum color value = %u)") -#ifdef TARGA_SUPPORTED JMESSAGE(JERR_TGA_BADCMAP, "Unsupported Targa colormap format") JMESSAGE(JERR_TGA_BADPARMS, "Invalid or unsupported Targa file") JMESSAGE(JERR_TGA_COLORSPACE, "Targa output must be grayscale or RGB") JMESSAGE(JTRC_TGA, "%ux%u RGB Targa image") JMESSAGE(JTRC_TGA_GRAY, "%ux%u grayscale Targa image") JMESSAGE(JTRC_TGA_MAPPED, "%ux%u colormapped Targa image") -#else JMESSAGE(JERR_TGA_NOTCOMP, "Targa support was not compiled") -#endif /* TARGA_SUPPORTED */ JMESSAGE(JERR_BAD_CMAP_FILE, "Color map file is invalid or of unsupported format") diff --git a/cdjpeg.h b/cdjpeg.h index 471b9a3..f4da238 100644 --- a/cdjpeg.h +++ b/cdjpeg.h @@ -40,9 +40,7 @@ struct cjpeg_source_struct { J16SAMPARRAY buffer16; #endif JDIMENSION buffer_height; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION JDIMENSION max_pixels; -#endif }; diff --git a/cjpeg.1 b/cjpeg.1 index 0815ca0..28a633b 100644 --- a/cjpeg.1 +++ b/cjpeg.1 @@ -1,4 +1,4 @@ -.TH CJPEG 1 "29 June 2023" +.TH CJPEG 1 "30 August 2024" .SH NAME cjpeg \- compress an image file to a JPEG file .SH SYNOPSIS @@ -16,7 +16,8 @@ cjpeg \- compress an image file to a JPEG file 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, and Targa. +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 @@ -29,7 +30,7 @@ Upper and lower case are equivalent (thus .B \-BMP is the same as .BR \-bmp ). -British spellings are also accepted (e.g., +British spellings are also accepted (e.g. .BR \-greyscale ), though for brevity these are not mentioned below. .PP @@ -40,13 +41,12 @@ Scale quantization tables to adjust image quality. Quality is 0 (worst) to 100 (best); default is 75. (See below for more info.) .TP .B \-grayscale -Create monochrome JPEG file from color input. By saying +Create monochrome JPEG file from color input. By specifying .BR \-grayscale, you'll get a smaller JPEG file that takes less time to process. .TP .B \-rgb -Create RGB JPEG file. -Using this switch suppresses the conversion from RGB +Create RGB JPEG file. Using this switch suppresses the conversion from RGB colorspace input to the default YCbCr JPEG colorspace. .TP .B \-optimize @@ -60,18 +60,22 @@ decompression are unaffected by .BR \-optimize . .TP .B \-progressive -Create progressive JPEG file (see below). +Create progressive JPEG file (see below). Implies +.B \-optimize +unless +.B \-arithmetic +is also specified. .TP .B \-targa -Input file is Targa format. Targa files that contain an "identification" -field will not be automatically recognized by -.BR cjpeg ; -for such files you must specify +Input file is Targa format [legacy feature]. Targa files that contain an +"identification" field will not be automatically recognized by +.BR cjpeg . +For such files, you must specify .B \-targa to make .B cjpeg -treat the input as Targa format. -For most Targa files, you won't need this switch. +treat the input as Targa format. For most Targa files, you won't need this +switch. .PP The .B \-quality @@ -153,10 +157,28 @@ Switches for advanced users: Create JPEG file with N-bit data precision. N is 8, 12, or 16; default is 8. If N is 16, then .B -lossless -must also be specified. +must also be specified. Note that only the PBMPLUS input file format supports +data precisions other than 8. (For historical reasons, +.B cjpeg +allows GIF input files to be converted into 12-bit-per-sample JPEG files, but +this is not a useful conversion.) Note also that PBMPLUS input files are +silently scaled to the target data precision, even if it is lower than the +precision of the input file. Passing an argument of +.B \-verbose +to +.B cjpeg +will cause it to print information about the precision of the input file. .B Caution: -12-bit and 16-bit JPEG is not yet widely implemented, so many decoders will be -unable to view a 12-bit or 16-bit JPEG file at all. +12-bit and 16-bit data precision is not yet widely implemented, so many +decoders will be unable to handle a 12-bit-per-sample or 16-bit-per-sample JPEG +file at all. +.IP +.B \-precision\ 12 +implies +.B \-optimize +unless +.B \-arithmetic +is also specified. .TP .BI \-lossless " psv[,Pt]" Create a lossless JPEG file using the specified predictor selection value @@ -174,8 +196,11 @@ non-zero point transform value right-shifts the input samples by the specified number of bits, which is effectively a form of lossy color quantization.) .B Caution: lossless JPEG is not yet widely implemented, so many decoders will be unable to -view a lossless JPEG file at all. Note that the following features will be -unavailable when compressing or decompressing a lossless JPEG file: +handle a lossless JPEG file at all. In most cases, compressing and +decompressing a lossless JPEG file is considerably slower than compressing and +decompressing a lossy JPEG file, and lossless JPEG files are much larger than +lossy JPEG files. Also note that the following features will be unavailable +when compressing or decompressing a lossless JPEG file: .IP - Quality/quantization table selection .IP @@ -202,8 +227,8 @@ Any switches used to enable or configure those features will be ignored. .B \-arithmetic Use arithmetic coding. .B Caution: -arithmetic coded JPEG is not yet widely implemented, so many decoders will be -unable to view an arithmetic coded JPEG file at all. +arithmetic-coded JPEG is not yet widely implemented, so many decoders will be +unable to handle an arithmetic-coded JPEG file at all. .TP .B \-dct int Use accurate integer DCT method (default). @@ -245,8 +270,18 @@ machines. Embed ICC color management profile contained in the specified file. .TP .BI \-restart " N" -Emit a JPEG restart marker every N MCU rows, or every N MCU blocks (samples in -lossless mode) if "B" is attached to the number. +Emit a JPEG restart marker every N MCU rows, or every N MCUs if "B" is attached +to the number. +.IP +In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set of +interleaved "data units" (8x8 DCT blocks if the image is lossy or samples if +the image is lossless) necessary to represent at least one data unit per +component. (For example, an MCU in an interleaved lossy JPEG image that uses +4:2:2 subsampling consists of two luminance blocks followed by one block for +each chrominance component.) In single-component or non-interleaved JPEG +images, an MCU is the same as a data unit. An MCU row is a row of MCUs +spanning the entire width of the image. +.IP .B \-restart 0 (the default) means no restart markers. .TP @@ -346,10 +381,10 @@ This example compresses the PPM file foo.ppm with a quality factor of .I foo.jpg .SH HINTS Color GIF files are not the ideal input for JPEG; JPEG is really intended for -compressing full-color (24-bit) images. In particular, don't try to convert -cartoons, line drawings, and other images that have only a few distinct -colors. GIF works great on these, JPEG does not. If you want to convert a -GIF to JPEG, you should experiment with +compressing full-color (24-bit through 48-bit) images. In particular, don't +try to convert cartoons, line drawings, and other images that have only a few +distinct colors. GIF works great on these; JPEG does not. If you want to +convert a GIF to JPEG, you should experiment with .BR cjpeg 's .B \-quality and @@ -404,8 +439,3 @@ relevant to libjpeg-turbo, to wordsmith certain sections, and to describe features not present in libjpeg. .SH ISSUES Not all variants of BMP and Targa file formats are supported. -.PP -The -.B \-targa -switch is not a bug, it's a feature. (It would be a bug if the Targa format -designers had not been clueless.) diff --git a/cjpeg.c b/cjpeg.c index ed649d2..c23036d 100644 --- a/cjpeg.c +++ b/cjpeg.c @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2013-2014, 2017, 2019-2022, D. R. Commander. + * Copyright (C) 2010, 2013-2014, 2017, 2019-2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -156,9 +156,9 @@ 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 char *outfilename; /* for -outfile switch */ -boolean memdst; /* for -memdst switch */ -boolean report; /* for -report switch */ -boolean strict; /* for -strict switch */ +static boolean memdst; /* for -memdst switch */ +static boolean report; /* for -report switch */ +static boolean strict; /* for -strict switch */ #ifdef CJPEG_FUZZER @@ -290,7 +290,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, int argn; char *arg; #ifdef C_LOSSLESS_SUPPORTED - int psv, pt = 0; + int psv = 0, pt = 0; #endif boolean force_baseline; boolean simple_progressive; @@ -361,7 +361,8 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, if (!printed_version) { fprintf(stderr, "%s version %s (build %s)\n", PACKAGE_NAME, VERSION, BUILD); - fprintf(stderr, "%s\n\n", JCOPYRIGHT); + fprintf(stderr, JCOPYRIGHT1); + fprintf(stderr, JCOPYRIGHT2 "\n"); fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n", JVERSION); printed_version = TRUE; @@ -402,7 +403,8 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, string */ if (*ptr) sscanf(ptr, "%d", &pt); - jpeg_enable_lossless(cinfo, psv, pt); + + /* We must postpone execution until data_precision is known. */ #else fprintf(stderr, "%s: sorry, lossless output was not compiled\n", progname); @@ -454,7 +456,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, usage(); cinfo->data_precision = val; - } else if (keymatch(arg, "progressive", 3)) { + } else if (keymatch(arg, "progressive", 1)) { /* Select simple progressive mode. */ #ifdef C_PROGRESSIVE_SUPPORTED simple_progressive = TRUE; @@ -524,7 +526,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, * default sampling factors. */ - } else if (keymatch(arg, "scans", 4)) { + } else if (keymatch(arg, "scans", 2)) { /* Set scan script. */ #ifdef C_MULTISCAN_FILES_SUPPORTED if (++argn >= argc) /* advance to next argument */ @@ -588,6 +590,11 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, jpeg_simple_progression(cinfo); #endif +#ifdef C_LOSSLESS_SUPPORTED + if (psv != 0) /* process -lossless */ + jpeg_enable_lossless(cinfo, psv, pt); +#endif + #ifdef C_MULTISCAN_FILES_SUPPORTED if (scansarg != NULL) /* process -scans if it was present */ if (!read_scan_script(cinfo, scansarg)) diff --git a/cmakescripts/GNUInstallDirs.cmake b/cmakescripts/GNUInstallDirs.cmake index 6408fca..d3e5b47 100644 --- a/cmakescripts/GNUInstallDirs.cmake +++ b/cmakescripts/GNUInstallDirs.cmake @@ -118,9 +118,10 @@ # absolute paths where necessary, using the same logic. #============================================================================= +# Copyright 2018 Tobias C. Berner # Copyright 2018 Matthias Räncker -# Copyright 2016, 2019 D. R. Commander -# Copyright 2016 Dmitry Marakasov +# Copyright 2016, 2019, 2024 D. R. Commander +# Copyright 2016, 2021 Dmitry Marakasov # Copyright 2016 Roger Leigh # Copyright 2015 Alex Turbov # Copyright 2014 Rolf Eike Beer @@ -181,6 +182,10 @@ macro(GNUInstallDirs_set_install_dir var docstring) set(_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var} "FORCE") endif() + if(DEFINED CMAKE_INSTALL_${var} AND NOT CMAKE_INSTALL_${var} MATCHES "^/") + set_property(CACHE CMAKE_INSTALL_${var} PROPERTY TYPE PATH) + endif() + set(CMAKE_INSTALL_${var} "${CMAKE_INSTALL_DEFAULT_${var}}" CACHE PATH "${docstring} (Default: ${CMAKE_INSTALL_DEFAULT_${var}})" ${_GNUInstallDirs_CMAKE_INSTALL_FORCE_${var}}) @@ -300,7 +305,7 @@ GNUInstallDirs_set_install_dir(DATADIR "The directory under which read-only architecture-independent data files should be installed") if(NOT DEFINED CMAKE_INSTALL_DEFAULT_INFODIR) - if(CMAKE_SYSTEM_NAME MATCHES "^(.*BSD|DragonFly)$") + if(CMAKE_SYSTEM_NAME MATCHES "^(([^kF].*)?BSD|DragonFly)$") set(CMAKE_INSTALL_DEFAULT_INFODIR "info") else() set(CMAKE_INSTALL_DEFAULT_INFODIR "/info") @@ -310,7 +315,7 @@ GNUInstallDirs_set_install_dir(INFODIR "The directory into which info documentation files should be installed") if(NOT DEFINED CMAKE_INSTALL_DEFAULT_MANDIR) - if(CMAKE_SYSTEM_NAME MATCHES "^(.*BSD|DragonFly)$") + if(CMAKE_SYSTEM_NAME MATCHES "^(([^k].*)?BSD|DragonFly)$" AND NOT CMAKE_SYSTEM_NAME MATCHES "^(FreeBSD)$") set(CMAKE_INSTALL_DEFAULT_MANDIR "man") else() set(CMAKE_INSTALL_DEFAULT_MANDIR "/man") diff --git a/cmakescripts/PackageInfo.cmake b/cmakescripts/PackageInfo.cmake index 36f6133..86e5ca0 100644 --- a/cmakescripts/PackageInfo.cmake +++ b/cmakescripts/PackageInfo.cmake @@ -5,8 +5,8 @@ set(PKGNAME ${CMAKE_PROJECT_NAME} CACHE STRING "Distribution package name (default: ${CMAKE_PROJECT_NAME})") set(PKGVENDOR "The ${CMAKE_PROJECT_NAME} Project" CACHE STRING "Vendor name to be included in distribution package descriptions (default: The ${CMAKE_PROJECT_NAME} Project)") -set(PKGURL "http://www.${CMAKE_PROJECT_NAME}.org" CACHE STRING - "URL of project web site to be included in distribution package descriptions (default: http://www.${CMAKE_PROJECT_NAME}.org)") +set(PKGURL "https://${CMAKE_PROJECT_NAME}.org" CACHE STRING + "URL of project web site to be included in distribution package descriptions (default: https://${CMAKE_PROJECT_NAME}.org)") set(PKGEMAIL "information@${CMAKE_PROJECT_NAME}.org" CACHE STRING "E-mail of project maintainer to be included in distribution package descriptions (default: information@${CMAKE_PROJECT_NAME}.org") set(PKGID "com.${CMAKE_PROJECT_NAME}.${PKGNAME}" CACHE STRING diff --git a/cmakescripts/testclean.cmake b/cmakescripts/testclean.cmake index 6b5a146..5f95109 100644 --- a/cmakescripts/testclean.cmake +++ b/cmakescripts/testclean.cmake @@ -38,6 +38,7 @@ file(GLOB FILES *_LOSSL*S_*.bmp *_LOSSL*S_*.ppm *_LOSSL*S_*.jpg + croptest.log tjbenchtest*.log tjexampletest*.log) diff --git a/djpeg.1 b/djpeg.1 index 31431b9..617eace 100644 --- a/djpeg.1 +++ b/djpeg.1 @@ -1,4 +1,4 @@ -.TH DJPEG 1 "4 November 2020" +.TH DJPEG 1 "17 June 2024" .SH NAME djpeg \- decompress a JPEG file to an image file .SH SYNOPSIS @@ -28,47 +28,46 @@ Upper and lower case are equivalent (thus .B \-BMP is the same as .BR \-bmp ). -British spellings are also accepted (e.g., +British spellings are also accepted (e.g. .BR \-greyscale ), though for brevity these are not mentioned below. .PP The basic switches are: .TP .BI \-colors " N" -Reduce image to at most N colors. This reduces the number of colors used in -the output image, so that it can be displayed on a colormapped display or -stored in a colormapped file format. For example, if you have an 8-bit -display, you'd need to reduce to 256 or fewer colors. +Reduce image to at most N colors [legacy feature]. This reduces the number of +colors used in the output image so that it can be stored in a colormapped file +format. This feature cannot be used when decompressing lossless JPEG images. .TP .BI \-quantize " N" Same as .BR \-colors . .B \-colors -is the recommended name, +is the recommended name. .B \-quantize -is provided only for backwards compatibility. +is provided only for backward compatibility. .TP .B \-fast -Select recommended processing options for fast, low quality output. (The -default options are chosen for highest quality output.) Currently, this is -equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR. +Select recommended processing options for low-quality output [legacy feature]. +(The default options are chosen for highest-quality output.) Currently, this +is equivalent to \fB\-dct fast \-nosmooth \-onepass \-dither ordered\fR. On +modern CPUs, these settings have little or no performance benefit and are +retained solely for backward compatibility. .TP .B \-grayscale -Force grayscale output even if JPEG file is color. Useful for viewing on -monochrome displays; also, -.B djpeg -runs noticeably faster in this mode. +Force grayscale output even if JPEG file is full-color. This feature cannot be +used when decompressing full-color lossless JPEG images. .TP .B \-rgb -Force RGB output even if JPEG file is grayscale. +Force RGB output even if JPEG file is grayscale. This feature cannot be used +when decompressing grayscale lossless JPEG images. .TP .BI \-scale " M/N" Scale the output image by a factor M/N. Currently the scale factor must be M/8, where M is an integer between 1 and 16 inclusive, or any reduced fraction thereof (such as 1/2, 3/4, etc.) Scaling is handy if the image is larger than -your screen; also, -.B djpeg -runs much faster when scaling down the output. +your screen. This feature cannot be used when decompressing lossless JPEG +images. .TP .B \-bmp Select BMP output format (Windows flavor). 8-bit colormapped format is @@ -77,32 +76,36 @@ emitted if or .B \-grayscale is specified, or if the JPEG file is grayscale; otherwise, 24-bit full-color -format is emitted. +format is emitted. This format can only be used when decompressing +8-bit-per-sample JPEG images. .TP .B \-gif -Select GIF output format (LZW-compressed). Since GIF does not support more -than 256 colors, +Select GIF output format (LZW-compressed) [legacy feature]. Since GIF does not +support more than 256 colors, .B \-colors 256 is assumed (unless you specify a smaller number of colors). If you specify .BR \-fast, -the default number of colors is 216. +the default number of colors is 216. This format can only be used when +decompressing 8-bit-per-sample or 12-bit-per-sample lossy JPEG images. .TP .B \-gif0 -Select GIF output format (uncompressed). Since GIF does not support more than -256 colors, +Select GIF output format (uncompressed) [legacy feature]. Since GIF does not +support more than 256 colors, .B \-colors 256 is assumed (unless you specify a smaller number of colors). If you specify .BR \-fast, -the default number of colors is 216. +the default number of colors is 216. This format can only be used when +decompressing 8-bit-per-sample or 12-bit-per-sample lossy JPEG images. .TP .B \-os2 -Select BMP output format (OS/2 1.x flavor). 8-bit colormapped format is -emitted if +Select BMP output format (OS/2 1.x flavor) [legacy feature]. 8-bit colormapped +format is emitted if .B \-colors or .B \-grayscale is specified, or if the JPEG file is grayscale; otherwise, 24-bit full-color -format is emitted. +format is emitted. This format can only be used when decompressing +8-bit-per-sample JPEG images. .TP .B \-pnm Select PBMPLUS (PPM/PGM) output format (this is the default format). @@ -111,12 +114,13 @@ PGM is emitted if the JPEG file is grayscale or if is specified; otherwise PPM is emitted. .TP .B \-targa -Select Targa output format. Grayscale format is emitted if the JPEG file is -grayscale or if +Select Targa output format [legacy feature]. Grayscale format is emitted if +the JPEG file is grayscale or if .B \-grayscale is specified; otherwise, colormapped format is emitted if .B \-colors -is specified; otherwise, 24-bit full-color format is emitted. +is specified; otherwise, 24-bit full-color format is emitted. This format can +only be used when decompressing 8-bit-per-sample JPEG images. .PP Switches for advanced users: .TP @@ -157,18 +161,18 @@ behavior, whereas the integer methods should give the same results on all machines. .TP .B \-dither fs -Use Floyd-Steinberg dithering in color quantization. +Use Floyd-Steinberg dithering when quantizing colors [legacy feature]. .TP .B \-dither ordered -Use ordered dithering in color quantization. +Use ordered dithering when quantizing colors [legacy feature]. .TP .B \-dither none -Do not use dithering in color quantization. -By default, Floyd-Steinberg dithering is applied when quantizing colors; this -is slow but usually produces the best results. Ordered dither is a compromise -between speed and quality; no dithering is fast but usually looks awful. Note -that these switches have no effect unless color quantization is being done. -Ordered dither is only available in +Do not use dithering when quantizing colors [legacy feature]. By default, +Floyd-Steinberg dithering is applied when quantizing colors. This is slower +but usually produces the best results. Ordered dithering is a compromise +between speed and quality. No dithering is faster but usually looks awful. +Note that these switches have no effect unless color quantization is being +done. Ordered dithering is only available in .B \-onepass mode. .TP @@ -176,9 +180,9 @@ mode. Extract ICC color management profile to the specified file. .TP .BI \-map " file" -Quantize to the colors used in the specified image file. This is useful for -producing multiple files with identical color maps, or for forcing a -predefined set of colors to be used. The +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 +forcing a predefined set of colors to be used. The .I file must be a GIF or PPM file. This option overrides .B \-colors @@ -189,14 +193,14 @@ and Use a faster, lower-quality upsampling routine. .TP .B \-onepass -Use one-pass instead of two-pass color quantization. The one-pass method is -faster and needs less memory, but it produces a lower-quality image. +Use one-pass instead of two-pass color quantization [legacy feature]. The +one-pass method needs less memory, but it produces a lower-quality image. .B \-onepass -is ignored unless you also say +is ignored unless you also specify .B \-colors .IR N . -Also, the one-pass method is always used for grayscale output (the two-pass -method is no improvement then). +Also, the one-pass method is always used for grayscale output. (The two-pass +method has no improvement in that case.) .TP .BI \-maxmemory " N" Set limit for amount of memory to use in processing large images. Value is @@ -260,36 +264,13 @@ Same as Print version information and exit. .SH EXAMPLES .LP -This example decompresses the JPEG file foo.jpg, quantizes it to -256 colors, and saves the output in 8-bit BMP format in foo.bmp: +This example decompresses the JPEG file foo.jpg and saves the output in 8-bit +BMP format in foo.bmp: .IP -.B djpeg \-colors 256 \-bmp +.B djpeg \-bmp .I foo.jpg .B > .I foo.bmp -.SH HINTS -To get a quick preview of an image, use the -.B \-grayscale -and/or -.B \-scale -switches. -.B \-grayscale \-scale 1/8 -is the fastest case. -.PP -Several options are available that trade off image quality to gain speed. -.B \-fast -turns on the recommended settings. -.PP -.B \-dct fast -and/or -.B \-nosmooth -gain speed at a small sacrifice in quality. -When producing a color-quantized image, -.B \-onepass \-dither ordered -is fast but much lower quality than the default behavior. -.B \-dither none -may give acceptable results in two-pass mode, but is seldom tolerable in -one-pass mode. .SH ENVIRONMENT .TP .B JPEGMEM diff --git a/djpeg.c b/djpeg.c index 4ea5c4b..132fc4b 100644 --- a/djpeg.c +++ b/djpeg.c @@ -5,7 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * Modified 2013-2019 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010-2011, 2013-2017, 2019-2020, 2022-2023, D. R. Commander. + * Copyright (C) 2010-2011, 2013-2017, 2019-2020, 2022-2024, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -84,14 +84,14 @@ static IMAGE_FORMATS requested_fmt; static const char *progname; /* program name for error messages */ static char *icc_filename; /* for -icc switch */ -JDIMENSION max_scans; /* for -maxscans switch */ +static JDIMENSION max_scans; /* for -maxscans switch */ static char *outfilename; /* for -outfile switch */ -boolean memsrc; /* for -memsrc switch */ -boolean report; /* for -report switch */ -boolean skip, crop; -JDIMENSION skip_start, skip_end; -JDIMENSION crop_x, crop_y, crop_width, crop_height; -boolean strict; /* for -strict switch */ +static boolean memsrc; /* for -memsrc switch */ +static boolean report; /* for -report switch */ +static boolean skip, crop; +static JDIMENSION skip_start, skip_end; +static JDIMENSION crop_x, crop_y, crop_width, crop_height; +static boolean strict; /* for -strict switch */ #define INPUT_BUF_SIZE 4096 @@ -107,8 +107,8 @@ usage(void) #endif fprintf(stderr, "Switches (names may be abbreviated):\n"); - fprintf(stderr, " -colors N Reduce image to no more than N colors\n"); - fprintf(stderr, " -fast Fast, low-quality processing\n"); + fprintf(stderr, " -colors N Reduce image to no more than N colors [legacy feature]\n"); + fprintf(stderr, " -fast Low-quality processing [legacy feature]\n"); fprintf(stderr, " -grayscale Force grayscale output\n"); fprintf(stderr, " -rgb Force RGB output\n"); fprintf(stderr, " -rgb565 Force RGB565 output\n"); @@ -120,13 +120,13 @@ usage(void) (DEFAULT_FMT == FMT_BMP ? " (default)" : "")); #endif #ifdef GIF_SUPPORTED - fprintf(stderr, " -gif Select GIF output format (LZW-compressed)%s\n", + fprintf(stderr, " -gif Select GIF output format (LZW-compressed)%s [legacy feature]\n", (DEFAULT_FMT == FMT_GIF ? " (default)" : "")); - fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s\n", + fprintf(stderr, " -gif0 Select GIF output format (uncompressed)%s [legacy feature]\n", (DEFAULT_FMT == FMT_GIF0 ? " (default)" : "")); #endif #ifdef BMP_SUPPORTED - fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s\n", + fprintf(stderr, " -os2 Select BMP output format (OS/2 style)%s [legacy feature]\n", (DEFAULT_FMT == FMT_OS2 ? " (default)" : "")); #endif #ifdef PPM_SUPPORTED @@ -134,7 +134,7 @@ usage(void) (DEFAULT_FMT == FMT_PPM ? " (default)" : "")); #endif #ifdef TARGA_SUPPORTED - fprintf(stderr, " -targa Select Targa output format%s\n", + fprintf(stderr, " -targa Select Targa output format%s [legacy feature]\n", (DEFAULT_FMT == FMT_TARGA ? " (default)" : "")); #endif fprintf(stderr, "Switches for advanced users:\n"); @@ -150,16 +150,18 @@ usage(void) fprintf(stderr, " -dct float Use floating-point DCT method [legacy feature]%s\n", (JDCT_DEFAULT == JDCT_FLOAT ? " (default)" : "")); #endif - fprintf(stderr, " -dither fs Use F-S dithering (default)\n"); - fprintf(stderr, " -dither none Don't use dithering in quantization\n"); - fprintf(stderr, " -dither ordered Use ordered dither (medium speed, quality)\n"); + fprintf(stderr, " -dither fs Use Floyd-Steinberg dithering when quantizing colors (default)\n"); + fprintf(stderr, " [legacy feature]\n"); + fprintf(stderr, " -dither none Don't use dithering when quantizing colors [legacy feature]\n"); + 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"); #ifdef QUANT_2PASS_SUPPORTED - fprintf(stderr, " -map FILE Map to colors used in named image file\n"); + fprintf(stderr, " -map FILE Quantize to colors used in named image file [legacy feature]\n"); #endif - fprintf(stderr, " -nosmooth Don't use high-quality upsampling\n"); + fprintf(stderr, " -nosmooth Use faster, lower-quality upsampling\n"); #ifdef QUANT_1PASS_SUPPORTED - fprintf(stderr, " -onepass Use 1-pass quantization (fast, low quality)\n"); + fprintf(stderr, " -onepass Use 1-pass color quantization (low quality) [legacy feature]\n"); #endif fprintf(stderr, " -maxmemory N Maximum memory to use (in kbytes)\n"); fprintf(stderr, " -maxscans N Maximum number of scans to allow in input file\n"); @@ -267,7 +269,8 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv, if (!printed_version) { fprintf(stderr, "%s version %s (build %s)\n", PACKAGE_NAME, VERSION, BUILD); - fprintf(stderr, "%s\n\n", JCOPYRIGHT); + fprintf(stderr, JCOPYRIGHT1); + fprintf(stderr, JCOPYRIGHT2 "\n"); fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n", JVERSION); printed_version = TRUE; @@ -389,7 +392,7 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv, } else if (keymatch(arg, "report", 2)) { report = TRUE; - } else if (keymatch(arg, "scale", 2)) { + } else if (keymatch(arg, "scale", 1)) { /* Scale the output image by a fraction M/N. */ if (++argn >= argc) /* advance to next argument */ usage(); @@ -398,22 +401,31 @@ parse_switches(j_decompress_ptr cinfo, int argc, char **argv, usage(); } else if (keymatch(arg, "skip", 2)) { + int temp_start = -1, temp_end = -1; if (++argn >= argc) usage(); - if (sscanf(argv[argn], "%u,%u", &skip_start, &skip_end) != 2 || - skip_start > skip_end) + if (sscanf(argv[argn], "%d,%d", &temp_start, &temp_end) != 2 || + temp_start < 0 || temp_end < 0 || temp_start > temp_end) usage(); skip = TRUE; + skip_start = temp_start; + skip_end = temp_end; } else if (keymatch(arg, "crop", 2)) { + int temp_width = -1, temp_height = -1, temp_x = -1, temp_y = -1; char c; if (++argn >= argc) usage(); - if (sscanf(argv[argn], "%u%c%u+%u+%u", &crop_width, &c, &crop_height, - &crop_x, &crop_y) != 5 || - (c != 'X' && c != 'x') || crop_width < 1 || crop_height < 1) + if (sscanf(argv[argn], "%d%c%d+%d+%d", &temp_width, &c, &temp_height, + &temp_x, &temp_y) != 5 || + (c != 'X' && c != 'x') || temp_width < 1 || temp_height < 1 || + temp_x < 0 || temp_y < 0) usage(); crop = TRUE; + crop_width = temp_width; + crop_height = temp_height; + crop_x = temp_x; + crop_y = temp_y; } else if (keymatch(arg, "strict", 2)) { strict = TRUE; @@ -773,8 +785,8 @@ main(int argc, char **argv) /* Check for valid crop dimensions. We cannot check these values until * after jpeg_start_decompress() is called. */ - if (crop_x + crop_width > cinfo.output_width || - crop_y + crop_height > cinfo.output_height) { + if ((unsigned long long)crop_x + crop_width > cinfo.output_width || + (unsigned long long)crop_y + crop_height > cinfo.output_height) { fprintf(stderr, "%s: crop dimensions exceed image dimensions %u x %u\n", progname, cinfo.output_width, cinfo.output_height); exit(EXIT_FAILURE); diff --git a/doc/html/annotated.html b/doc/html/annotated.html index d7e2987..1e5b562 100644 --- a/doc/html/annotated.html +++ b/doc/html/annotated.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: Data Structures @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ + @@ -57,27 +57,33 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
-
Data Structures
+
Data Structures
Here are the data structures with brief descriptions:
- +
 CtjregionCropping region
 CtjscalingfactorScaling factor
 CtjscalingfactorScaling factor
 CtjtransformLossless transform
diff --git a/doc/html/bc_sd.png b/doc/html/bc_sd.png new file mode 100644 index 0000000..31ca888 Binary files /dev/null and b/doc/html/bc_sd.png differ diff --git a/doc/html/bdwn.png b/doc/html/bdwn.png deleted file mode 100644 index 940a0b9..0000000 Binary files a/doc/html/bdwn.png and /dev/null differ diff --git a/doc/html/classes.html b/doc/html/classes.html index 78730e6..ddfc183 100644 --- a/doc/html/classes.html +++ b/doc/html/classes.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: Data Structure Index @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ + @@ -57,33 +57,32 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
-
Data Structure Index
+
Data Structure Index
- - - - - - - - - - -
  t  
-
tjscalingfactor   tjtransform   
tjregion   
- + +
diff --git a/doc/html/doc.png b/doc/html/doc.png deleted file mode 100644 index 17edabf..0000000 Binary files a/doc/html/doc.png and /dev/null differ diff --git a/doc/html/doc.svg b/doc/html/doc.svg new file mode 100644 index 0000000..0b928a5 --- /dev/null +++ b/doc/html/doc.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doc/html/docd.svg b/doc/html/docd.svg new file mode 100644 index 0000000..ac18b27 --- /dev/null +++ b/doc/html/docd.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doc/html/doxygen-extra.css b/doc/html/doxygen-extra.css index f1bd4c2..be54168 100644 --- a/doc/html/doxygen-extra.css +++ b/doc/html/doxygen-extra.css @@ -1,3 +1,7 @@ code { color: #4665A2; } + +th.markdownTableHeadNone { + color: black; +} diff --git a/doc/html/doxygen.css b/doc/html/doxygen.css index f640966..eeadba5 100644 --- a/doc/html/doxygen.css +++ b/doc/html/doxygen.css @@ -1,29 +1,378 @@ -/* The standard CSS for doxygen 1.8.20 */ - -body, table, div, p, dl { - font: 400 14px/22px Roboto,sans-serif; +/* The standard CSS for doxygen 1.9.8*/ + +html { +/* page base colors */ +--page-background-color: white; +--page-foreground-color: black; +--page-link-color: #3D578C; +--page-visited-link-color: #4665A2; + +/* index */ +--index-odd-item-bg-color: #F8F9FC; +--index-even-item-bg-color: white; +--index-header-color: black; +--index-separator-color: #A0A0A0; + +/* header */ +--header-background-color: #F9FAFC; +--header-separator-color: #C4CFE5; +--header-gradient-image: url('nav_h.png'); +--group-header-separator-color: #879ECB; +--group-header-color: #354C7B; +--inherit-header-color: gray; + +--footer-foreground-color: #2A3D61; +--footer-logo-width: 104px; +--citation-label-color: #334975; +--glow-color: cyan; + +--title-background-color: white; +--title-separator-color: #5373B4; +--directory-separator-color: #9CAFD4; +--separator-color: #4A6AAA; + +--blockquote-background-color: #F7F8FB; +--blockquote-border-color: #9CAFD4; + +--scrollbar-thumb-color: #9CAFD4; +--scrollbar-background-color: #F9FAFC; + +--icon-background-color: #728DC1; +--icon-foreground-color: white; +--icon-doc-image: url('doc.svg'); +--icon-folder-open-image: url('folderopen.svg'); +--icon-folder-closed-image: url('folderclosed.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #F9FAFC; +--memdecl-separator-color: #DEE4F0; +--memdecl-foreground-color: #555; +--memdecl-template-color: #4665A2; + +/* detailed member list */ +--memdef-border-color: #A8B8D9; +--memdef-title-background-color: #E2E8F2; +--memdef-title-gradient-image: url('nav_f.png'); +--memdef-proto-background-color: #DFE5F1; +--memdef-proto-text-color: #253555; +--memdef-proto-text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--memdef-doc-background-color: white; +--memdef-param-name-color: #602020; +--memdef-template-color: #4665A2; + +/* tables */ +--table-cell-border-color: #2D4068; +--table-header-background-color: #374F7F; +--table-header-foreground-color: #FFFFFF; + +/* labels */ +--label-background-color: #728DC1; +--label-left-top-border-color: #5373B4; +--label-right-bottom-border-color: #C4CFE5; +--label-foreground-color: white; + +/** navigation bar/tree/menu */ +--nav-background-color: #F9FAFC; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_b.png'); +--nav-gradient-hover-image: url('tab_h.png'); +--nav-gradient-active-image: url('tab_a.png'); +--nav-gradient-active-image-parent: url("../tab_a.png"); +--nav-separator-image: url('tab_s.png'); +--nav-breadcrumb-image: url('bc_s.png'); +--nav-breadcrumb-border-color: #C2CDE4; +--nav-splitbar-image: url('splitbar.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #283A5D; +--nav-text-hover-color: white; +--nav-text-active-color: white; +--nav-text-normal-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #364D7C; +--nav-menu-background-color: white; +--nav-menu-foreground-color: #555555; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.5); +--nav-arrow-color: #9CAFD4; +--nav-arrow-selected-color: #9CAFD4; + +/* table of contents */ +--toc-background-color: #F4F6FA; +--toc-border-color: #D8DFEE; +--toc-header-color: #4665A2; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: white; +--search-foreground-color: #909090; +--search-magnification-image: url('mag.svg'); +--search-magnification-select-image: url('mag_sel.svg'); +--search-active-color: black; +--search-filter-background-color: #F9FAFC; +--search-filter-foreground-color: black; +--search-filter-border-color: #90A5CE; +--search-filter-highlight-text-color: white; +--search-filter-highlight-bg-color: #3D578C; +--search-results-foreground-color: #425E97; +--search-results-background-color: #EEF1F7; +--search-results-border-color: black; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #555; + +/** code fragments */ +--code-keyword-color: #008000; +--code-type-keyword-color: #604020; +--code-flow-keyword-color: #E08000; +--code-comment-color: #800000; +--code-preprocessor-color: #806020; +--code-string-literal-color: #002080; +--code-char-literal-color: #008080; +--code-xml-cdata-color: black; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #000000; +--code-vhdl-keyword-color: #700070; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #4665A2; +--code-external-link-color: #4665A2; +--fragment-foreground-color: black; +--fragment-background-color: #FBFCFD; +--fragment-border-color: #C4CFE5; +--fragment-lineno-border-color: #00FF00; +--fragment-lineno-background-color: #E8E8E8; +--fragment-lineno-foreground-color: black; +--fragment-lineno-link-fg-color: #4665A2; +--fragment-lineno-link-bg-color: #D8D8D8; +--fragment-lineno-link-hover-fg-color: #4665A2; +--fragment-lineno-link-hover-bg-color: #C8C8C8; +--tooltip-foreground-color: black; +--tooltip-background-color: white; +--tooltip-border-color: gray; +--tooltip-doc-color: grey; +--tooltip-declaration-color: #006318; +--tooltip-link-color: #4665A2; +--tooltip-shadow: 1px 1px 7px gray; +--fold-line-color: #808080; +--fold-minus-image: url('minus.svg'); +--fold-plus-image: url('plus.svg'); +--fold-minus-image-relpath: url('../../minus.svg'); +--fold-plus-image-relpath: url('../../plus.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +} + +@media (prefers-color-scheme: dark) { + html:not(.dark-mode) { + color-scheme: dark; + +/* page base colors */ +--page-background-color: black; +--page-foreground-color: #C9D1D9; +--page-link-color: #90A5CE; +--page-visited-link-color: #A3B4D7; + +/* index */ +--index-odd-item-bg-color: #0B101A; +--index-even-item-bg-color: black; +--index-header-color: #C4CFE5; +--index-separator-color: #334975; + +/* header */ +--header-background-color: #070B11; +--header-separator-color: #141C2E; +--header-gradient-image: url('nav_hd.png'); +--group-header-separator-color: #283A5D; +--group-header-color: #90A5CE; +--inherit-header-color: #A0A0A0; + +--footer-foreground-color: #5B7AB7; +--footer-logo-width: 60px; +--citation-label-color: #90A5CE; +--glow-color: cyan; + +--title-background-color: #090D16; +--title-separator-color: #354C79; +--directory-separator-color: #283A5D; +--separator-color: #283A5D; + +--blockquote-background-color: #101826; +--blockquote-border-color: #283A5D; + +--scrollbar-thumb-color: #283A5D; +--scrollbar-background-color: #070B11; + +--icon-background-color: #334975; +--icon-foreground-color: #C4CFE5; +--icon-doc-image: url('docd.svg'); +--icon-folder-open-image: url('folderopend.svg'); +--icon-folder-closed-image: url('folderclosedd.svg'); + +/* brief member declaration list */ +--memdecl-background-color: #0B101A; +--memdecl-separator-color: #2C3F65; +--memdecl-foreground-color: #BBB; +--memdecl-template-color: #7C95C6; + +/* detailed member list */ +--memdef-border-color: #233250; +--memdef-title-background-color: #1B2840; +--memdef-title-gradient-image: url('nav_fd.png'); +--memdef-proto-background-color: #19243A; +--memdef-proto-text-color: #9DB0D4; +--memdef-proto-text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.9); +--memdef-doc-background-color: black; +--memdef-param-name-color: #D28757; +--memdef-template-color: #7C95C6; + +/* tables */ +--table-cell-border-color: #283A5D; +--table-header-background-color: #283A5D; +--table-header-foreground-color: #C4CFE5; + +/* labels */ +--label-background-color: #354C7B; +--label-left-top-border-color: #4665A2; +--label-right-bottom-border-color: #283A5D; +--label-foreground-color: #CCCCCC; + +/** navigation bar/tree/menu */ +--nav-background-color: #101826; +--nav-foreground-color: #364D7C; +--nav-gradient-image: url('tab_bd.png'); +--nav-gradient-hover-image: url('tab_hd.png'); +--nav-gradient-active-image: url('tab_ad.png'); +--nav-gradient-active-image-parent: url("../tab_ad.png"); +--nav-separator-image: url('tab_sd.png'); +--nav-breadcrumb-image: url('bc_sd.png'); +--nav-breadcrumb-border-color: #2A3D61; +--nav-splitbar-image: url('splitbard.png'); +--nav-font-size-level1: 13px; +--nav-font-size-level2: 10px; +--nav-font-size-level3: 9px; +--nav-text-normal-color: #B6C4DF; +--nav-text-hover-color: #DCE2EF; +--nav-text-active-color: #DCE2EF; +--nav-text-normal-shadow: 0px 1px 1px black; +--nav-text-hover-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-text-active-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +--nav-menu-button-color: #B6C4DF; +--nav-menu-background-color: #05070C; +--nav-menu-foreground-color: #BBBBBB; +--nav-menu-toggle-color: rgba(255, 255, 255, 0.2); +--nav-arrow-color: #334975; +--nav-arrow-selected-color: #90A5CE; + +/* table of contents */ +--toc-background-color: #151E30; +--toc-border-color: #202E4A; +--toc-header-color: #A3B4D7; +--toc-down-arrow-image: url("data:image/svg+xml;utf8,&%238595;"); + +/** search field */ +--search-background-color: black; +--search-foreground-color: #C5C5C5; +--search-magnification-image: url('mag_d.svg'); +--search-magnification-select-image: url('mag_seld.svg'); +--search-active-color: #C5C5C5; +--search-filter-background-color: #101826; +--search-filter-foreground-color: #90A5CE; +--search-filter-border-color: #7C95C6; +--search-filter-highlight-text-color: #BCC9E2; +--search-filter-highlight-bg-color: #283A5D; +--search-results-background-color: #101826; +--search-results-foreground-color: #90A5CE; +--search-results-border-color: #7C95C6; +--search-box-shadow: inset 0.5px 0.5px 3px 0px #2F436C; + +/** code fragments */ +--code-keyword-color: #CC99CD; +--code-type-keyword-color: #AB99CD; +--code-flow-keyword-color: #E08000; +--code-comment-color: #717790; +--code-preprocessor-color: #65CABE; +--code-string-literal-color: #7EC699; +--code-char-literal-color: #00E0F0; +--code-xml-cdata-color: #C9D1D9; +--code-vhdl-digit-color: #FF00FF; +--code-vhdl-char-color: #C0C0C0; +--code-vhdl-keyword-color: #CF53C9; +--code-vhdl-logic-color: #FF0000; +--code-link-color: #79C0FF; +--code-external-link-color: #79C0FF; +--fragment-foreground-color: #C9D1D9; +--fragment-background-color: black; +--fragment-border-color: #30363D; +--fragment-lineno-border-color: #30363D; +--fragment-lineno-background-color: black; +--fragment-lineno-foreground-color: #6E7681; +--fragment-lineno-link-fg-color: #6E7681; +--fragment-lineno-link-bg-color: #303030; +--fragment-lineno-link-hover-fg-color: #8E96A1; +--fragment-lineno-link-hover-bg-color: #505050; +--tooltip-foreground-color: #C9D1D9; +--tooltip-background-color: #202020; +--tooltip-border-color: #C9D1D9; +--tooltip-doc-color: #D9E1E9; +--tooltip-declaration-color: #20C348; +--tooltip-link-color: #79C0FF; +--tooltip-shadow: none; +--fold-line-color: #808080; +--fold-minus-image: url('minusd.svg'); +--fold-plus-image: url('plusd.svg'); +--fold-minus-image-relpath: url('../../minusd.svg'); +--fold-plus-image-relpath: url('../../plusd.svg'); + +/** font-family */ +--font-family-normal: Roboto,sans-serif; +--font-family-monospace: 'JetBrains Mono',Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace,fixed; +--font-family-nav: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; +--font-family-title: Tahoma,Arial,sans-serif; +--font-family-toc: Verdana,'DejaVu Sans',Geneva,sans-serif; +--font-family-search: Arial,Verdana,sans-serif; +--font-family-icon: Arial,Helvetica; +--font-family-tooltip: Roboto,sans-serif; + +}} +body { + background-color: var(--page-background-color); + color: var(--page-foreground-color); } -p.reference, p.definition { - font: 400 14px/22px Roboto,sans-serif; +body, table, div, p, dl { + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 22px; } /* @group Heading Levels */ -h1.groupheader { - font-size: 150%; -} - .title { - font: 400 14px/28px Roboto,sans-serif; + font-weight: 400; + font-size: 14px; + font-family: var(--font-family-normal); + line-height: 28px; font-size: 150%; font-weight: bold; margin: 10px 2px; } +h1.groupheader { + font-size: 150%; +} + h2.groupheader { - border-bottom: 1px solid #879ECB; - color: #354C7B; + border-bottom: 1px solid var(--group-header-separator-color); + color: var(--group-header-color); font-size: 150%; font-weight: normal; margin-top: 1.75em; @@ -46,22 +395,13 @@ h1, h2, h3, h4, h5, h6 { } h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow { - text-shadow: 0 0 15px cyan; + text-shadow: 0 0 15px var(--glow-color); } dt { font-weight: bold; } -ul.multicol { - -moz-column-gap: 1em; - -webkit-column-gap: 1em; - column-gap: 1em; - -moz-column-count: 3; - -webkit-column-count: 3; - column-count: 3; -} - p.startli, p.startdd { margin-top: 2px; } @@ -103,59 +443,120 @@ caption { } span.legend { - font-size: 70%; - text-align: center; + font-size: 70%; + text-align: center; } h3.version { - font-size: 90%; - text-align: center; + font-size: 90%; + text-align: center; } -div.qindex, div.navtab{ - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; +div.navtab { + padding-right: 15px; + text-align: right; + line-height: 110%; } -div.qindex, div.navpath { +div.navtab table { + border-spacing: 0; +} + +td.navtab { + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL { + background-image: var(--nav-gradient-active-image); + background-repeat:repeat-x; + padding-right: 6px; + padding-left: 6px; +} + +td.navtabHL a, td.navtabHL a:visited { + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); +} + +a.navtab { + font-weight: bold; +} + +div.qindex{ + text-align: center; width: 100%; line-height: 140%; + font-size: 130%; + color: var(--index-separator-color); } -div.navtab { - margin-right: 15px; +#main-menu a:focus { + outline: auto; + z-index: 10; + position: relative; } -/* @group Link Styling */ +dt.alphachar{ + font-size: 180%; + font-weight: bold; +} -a { - color: #3D578C; - font-weight: normal; +.alphachar a{ + color: var(--index-header-color); +} + +.alphachar a:hover, .alphachar a:visited{ text-decoration: none; } -.contents a:visited { - color: #4665A2; +.classindex dl { + padding: 25px; + column-count:1 } -a:hover { - text-decoration: underline; +.classindex dd { + display:inline-block; + margin-left: 50px; + width: 90%; + line-height: 1.15em; } -a.qindex { - font-weight: bold; +.classindex dl.even { + background-color: var(--index-even-item-bg-color); } -a.qindexHL { - font-weight: bold; - background-color: #9CAFD4; - color: #FFFFFF; - border: 1px double #869DCA; +.classindex dl.odd { + background-color: var(--index-odd-item-bg-color); +} + +@media(min-width: 1120px) { + .classindex dl { + column-count:2 + } +} + +@media(min-width: 1320px) { + .classindex dl { + column-count:3 + } } -.contents a.qindexHL:visited { - color: #FFFFFF; + +/* @group Link Styling */ + +a { + color: var(--page-link-color); + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: var(--page-visited-link-color); +} + +a:hover { + text-decoration: underline; } a.el { @@ -166,12 +567,39 @@ a.elRef { } a.code, a.code:visited, a.line, a.line:visited { - color: #4665A2; + color: var(--code-link-color); } a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited { - color: #4665A2; -} + color: var(--code-external-link-color); +} + +a.code.hl_class { /* style for links to class names in code snippets */ } +a.code.hl_struct { /* style for links to struct names in code snippets */ } +a.code.hl_union { /* style for links to union names in code snippets */ } +a.code.hl_interface { /* style for links to interface names in code snippets */ } +a.code.hl_protocol { /* style for links to protocol names in code snippets */ } +a.code.hl_category { /* style for links to category names in code snippets */ } +a.code.hl_exception { /* style for links to exception names in code snippets */ } +a.code.hl_service { /* style for links to service names in code snippets */ } +a.code.hl_singleton { /* style for links to singleton names in code snippets */ } +a.code.hl_concept { /* style for links to concept names in code snippets */ } +a.code.hl_namespace { /* style for links to namespace names in code snippets */ } +a.code.hl_package { /* style for links to package names in code snippets */ } +a.code.hl_define { /* style for links to macro names in code snippets */ } +a.code.hl_function { /* style for links to function names in code snippets */ } +a.code.hl_variable { /* style for links to variable names in code snippets */ } +a.code.hl_typedef { /* style for links to typedef names in code snippets */ } +a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ } +a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ } +a.code.hl_signal { /* style for links to Qt signal names in code snippets */ } +a.code.hl_slot { /* style for links to Qt slot names in code snippets */ } +a.code.hl_friend { /* style for links to friend names in code snippets */ } +a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ } +a.code.hl_property { /* style for links to property names in code snippets */ } +a.code.hl_event { /* style for links to event names in code snippets */ } +a.code.hl_sequence { /* style for links to sequence names in code snippets */ } +a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ } /* @end */ @@ -180,7 +608,17 @@ dl.el { } ul { - overflow: hidden; /*Fixed: list item bullets overlap floating elements*/ + overflow: visible; +} + +ul.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; + column-count: 3; + list-style-type: none; } #side-nav ul { @@ -199,30 +637,32 @@ ul { } pre.fragment { - border: 1px solid #C4CFE5; - background-color: #FBFCFD; + border: 1px solid var(--fragment-border-color); + background-color: var(--fragment-background-color); + color: var(--fragment-foreground-color); padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; font-size: 9pt; line-height: 125%; - font-family: monospace, fixed; + font-family: var(--font-family-monospace); font-size: 105%; } div.fragment { - padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ - margin: 4px 8px 4px 2px; - background-color: #FBFCFD; - border: 1px solid #C4CFE5; + padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/ + margin: 4px 8px 4px 2px; + color: var(--fragment-foreground-color); + background-color: var(--fragment-background-color); + border: 1px solid var(--fragment-border-color); } div.line { - font-family: monospace, fixed; + font-family: var(--font-family-monospace); font-size: 13px; min-height: 13px; - line-height: 1.0; + line-height: 1.2; text-wrap: unrestricted; white-space: -moz-pre-wrap; /* Moz */ white-space: -pre-wrap; /* Opera 4-6 */ @@ -251,24 +691,40 @@ div.line:after { } div.line.glow { - background-color: cyan; - box-shadow: 0 0 10px cyan; + background-color: var(--glow-color); + box-shadow: 0 0 10px var(--glow-color); } +span.fold { + margin-left: 5px; + margin-right: 1px; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; + display: inline-block; + width: 12px; + height: 12px; + background-repeat:no-repeat; + background-position:center; +} span.lineno { padding-right: 4px; + margin-right: 9px; text-align: right; - border-right: 2px solid #0F0; - background-color: #E8E8E8; + border-right: 2px solid var(--fragment-lineno-border-color); + color: var(--fragment-lineno-foreground-color); + background-color: var(--fragment-lineno-background-color); white-space: pre; } -span.lineno a { - background-color: #D8D8D8; +span.lineno a, span.lineno a:visited { + color: var(--fragment-lineno-link-fg-color); + background-color: var(--fragment-lineno-link-bg-color); } span.lineno a:hover { - background-color: #C8C8C8; + color: var(--fragment-lineno-link-hover-fg-color); + background-color: var(--fragment-lineno-link-hover-bg-color); } .lineno { @@ -280,24 +736,6 @@ span.lineno a:hover { user-select: none; } -div.ah, span.ah { - background-color: black; - font-weight: bold; - color: #FFFFFF; - margin-bottom: 3px; - margin-top: 3px; - padding: 0.2em; - border: solid thin #333; - border-radius: 0.5em; - -webkit-border-radius: .5em; - -moz-border-radius: .5em; - box-shadow: 2px 2px 3px #999; - -webkit-box-shadow: 2px 2px 3px #999; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); - background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%); -} - div.classindex ul { list-style: none; padding-left: 0; @@ -319,8 +757,7 @@ div.groupText { } body { - background-color: white; - color: black; + color: var(--page-foreground-color); margin: 0; } @@ -330,29 +767,15 @@ div.contents { margin-right: 8px; } -td.indexkey { - background-color: #EBEFF6; - font-weight: bold; - border: 1px solid #C4CFE5; - margin: 2px 0px 2px 0; - padding: 2px 10px; - white-space: nowrap; - vertical-align: top; -} - -td.indexvalue { - background-color: #EBEFF6; - border: 1px solid #C4CFE5; - padding: 2px 10px; - margin: 2px 0px; +p.formulaDsp { + text-align: center; } -tr.memlist { - background-color: #EEF1F7; +img.dark-mode-visible { + display: none; } - -p.formulaDsp { - text-align: center; +img.light-mode-visible { + display: none; } img.formulaDsp { @@ -382,89 +805,74 @@ address.footer { img.footer { border: 0px; vertical-align: middle; + width: var(--footer-logo-width); +} + +.compoundTemplParams { + color: var(--memdecl-template-color); + font-size: 80%; + line-height: 120%; } /* @group Code Colorization */ span.keyword { - color: #008000 + color: var(--code-keyword-color); } span.keywordtype { - color: #604020 + color: var(--code-type-keyword-color); } span.keywordflow { - color: #e08000 + color: var(--code-flow-keyword-color); } span.comment { - color: #800000 + color: var(--code-comment-color); } span.preprocessor { - color: #806020 + color: var(--code-preprocessor-color); } span.stringliteral { - color: #002080 + color: var(--code-string-literal-color); } span.charliteral { - color: #008080 + color: var(--code-char-literal-color); +} + +span.xmlcdata { + color: var(--code-xml-cdata-color); } span.vhdldigit { - color: #ff00ff + color: var(--code-vhdl-digit-color); } span.vhdlchar { - color: #000000 + color: var(--code-vhdl-char-color); } span.vhdlkeyword { - color: #700070 + color: var(--code-vhdl-keyword-color); } span.vhdllogic { - color: #ff0000 + color: var(--code-vhdl-logic-color); } blockquote { - background-color: #F7F8FB; - border-left: 2px solid #9CAFD4; + background-color: var(--blockquote-background-color); + border-left: 2px solid var(--blockquote-border-color); margin: 0 24px 0 4px; padding: 0 12px 0 16px; } -blockquote.DocNodeRTL { - border-left: 0; - border-right: 2px solid #9CAFD4; - margin: 0 4px 0 24px; - padding: 0 16px 0 12px; -} - /* @end */ -/* -.search { - color: #003399; - font-weight: bold; -} - -form.search { - margin-bottom: 0px; - margin-top: 0px; -} - -input.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} -*/ - td.tiny { font-size: 75%; } @@ -472,18 +880,19 @@ td.tiny { .dirtab { padding: 4px; border-collapse: collapse; - border: 1px solid #A3B4D7; + border: 1px solid var(--table-cell-border-color); } th.dirtab { - background: #EBEFF6; + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); font-weight: bold; } hr { height: 0px; border: none; - border-top: 1px solid #4A6AAA; + border-top: 1px solid var(--separator-color); } hr.footer { @@ -511,14 +920,14 @@ table.memberdecls { } .memberdecls td.glow, .fieldtable tr.glow { - background-color: cyan; - box-shadow: 0 0 15px cyan; + background-color: var(--glow-color); + box-shadow: 0 0 15px var(--glow-color); } .mdescLeft, .mdescRight, .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight, .memTemplParams { - background-color: #F9FAFC; + background-color: var(--memdecl-background-color); border: none; margin: 4px; padding: 1px 0 0 8px; @@ -526,11 +935,11 @@ table.memberdecls { .mdescLeft, .mdescRight { padding: 0px 8px 4px 8px; - color: #555; + color: var(--memdecl-foreground-color); } .memSeparator { - border-bottom: 1px solid #DEE4F0; + border-bottom: 1px solid var(--memdecl-separator-color); line-height: 1px; margin: 0px; padding: 0px; @@ -545,7 +954,7 @@ table.memberdecls { } .memTemplParams { - color: #4665A2; + color: var(--memdecl-template-color); white-space: nowrap; font-size: 80%; } @@ -558,15 +967,15 @@ table.memberdecls { .memtitle { padding: 8px; - border-top: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); border-top-right-radius: 4px; border-top-left-radius: 4px; margin-bottom: -1px; - background-image: url('nav_f.png'); + background-image: var(--memdef-title-gradient-image); background-repeat: repeat-x; - background-color: #E2E8F2; + background-color: var(--memdef-title-background-color); line-height: 1.25; font-weight: 300; float:left; @@ -581,20 +990,11 @@ table.memberdecls { .memtemplate { font-size: 80%; - color: #4665A2; + color: var(--memdef-template-color); font-weight: normal; margin-left: 9px; } -.memnav { - background-color: #EBEFF6; - border: 1px solid #A3B4D7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} - .mempage { width: 100%; } @@ -613,7 +1013,7 @@ table.memberdecls { } .memitem.glow { - box-shadow: 0 0 15px cyan; + box-shadow: 0 0 15px var(--glow-color); } .memname { @@ -626,41 +1026,32 @@ table.memberdecls { } .memproto, dl.reflist dt { - border-top: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; + border-top: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); padding: 6px 0px 6px 0px; - color: #253555; + color: var(--memdef-proto-text-color); font-weight: bold; - text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - background-color: #DFE5F1; - /* opera specific markup */ + text-shadow: var(--memdef-proto-text-shadow); + background-color: var(--memdef-proto-background-color); box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); border-top-right-radius: 4px; - /* firefox specific markup */ - -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; - -moz-border-radius-topright: 4px; - /* webkit specific markup */ - -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); - -webkit-border-top-right-radius: 4px; - } .overload { - font-family: "courier new",courier,monospace; + font-family: var(--font-family-monospace); font-size: 65%; } .memdoc, dl.reflist dd { - border-bottom: 1px solid #A8B8D9; - border-left: 1px solid #A8B8D9; - border-right: 1px solid #A8B8D9; + border-bottom: 1px solid var(--memdef-border-color); + border-left: 1px solid var(--memdef-border-color); + border-right: 1px solid var(--memdef-border-color); padding: 6px 10px 2px 10px; - background-color: #FBFCFD; border-top-width: 0; background-image:url('nav_g.png'); background-repeat:repeat-x; - background-color: #FFFFFF; + background-color: var(--memdef-doc-background-color); /* opera specific markup */ border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; @@ -693,7 +1084,7 @@ dl.reflist dd { } .paramname { - color: #602020; + color: var(--memdef-param-name-color); white-space: nowrap; } .paramname em { @@ -706,20 +1097,20 @@ dl.reflist dd { .params, .retval, .exception, .tparams { margin-left: 0px; padding-left: 0px; -} +} .params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname { font-weight: bold; vertical-align: top; } - + .params .paramtype, .tparams .paramtype { font-style: italic; vertical-align: top; -} - +} + .params .paramdir, .tparams .paramdir { - font-family: "courier new",courier,monospace; + font-family: var(--font-family-monospace); vertical-align: top; } @@ -743,13 +1134,13 @@ span.mlabels { } span.mlabel { - background-color: #728DC1; - border-top:1px solid #5373B4; - border-left:1px solid #5373B4; - border-right:1px solid #C4CFE5; - border-bottom:1px solid #C4CFE5; + background-color: var(--label-background-color); + border-top:1px solid var(--label-left-top-border-color); + border-left:1px solid var(--label-left-top-border-color); + border-right:1px solid var(--label-right-bottom-border-color); + border-bottom:1px solid var(--label-right-bottom-border-color); text-shadow: none; - color: white; + color: var(--label-foreground-color); margin-right: 4px; padding: 2px 3px; border-radius: 3px; @@ -766,8 +1157,8 @@ span.mlabel { div.directory { margin: 10px 0px; - border-top: 1px solid #9CAFD4; - border-bottom: 1px solid #9CAFD4; + border-top: 1px solid var(--directory-separator-color); + border-bottom: 1px solid var(--directory-separator-color); width: 100%; } @@ -803,9 +1194,14 @@ div.directory { border-left: 1px solid rgba(0,0,0,0.05); } +.directory tr.odd { + padding-left: 6px; + background-color: var(--index-odd-item-bg-color); +} + .directory tr.even { padding-left: 6px; - background-color: #F7F8FB; + background-color: var(--index-even-item-bg-color); } .directory img { @@ -823,11 +1219,11 @@ div.directory { cursor: pointer; padding-left: 2px; padding-right: 2px; - color: #3D578C; + color: var(--page-link-color); } .arrow { - color: #9CAFD4; + color: var(--nav-arrow-color); -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; @@ -841,14 +1237,15 @@ div.directory { } .icon { - font-family: Arial, Helvetica; + font-family: var(--font-family-icon); + line-height: normal; font-weight: bold; font-size: 12px; height: 14px; width: 16px; display: inline-block; - background-color: #728DC1; - color: white; + background-color: var(--icon-background-color); + color: var(--icon-foreground-color); text-align: center; border-radius: 4px; margin-left: 2px; @@ -865,8 +1262,7 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('folderopen.png'); - background-position: 0px -4px; + background-image:var(--icon-folder-open-image); background-repeat: repeat-y; vertical-align:top; display: inline-block; @@ -876,8 +1272,7 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('folderclosed.png'); - background-position: 0px -4px; + background-image:var(--icon-folder-closed-image); background-repeat: repeat-y; vertical-align:top; display: inline-block; @@ -887,17 +1282,13 @@ div.directory { width: 24px; height: 18px; margin-bottom: 4px; - background-image:url('doc.png'); + background-image:var(--icon-doc-image); background-position: 0px -4px; background-repeat: repeat-y; vertical-align:top; display: inline-block; } -table.directory { - font: 400 14px Roboto,sans-serif; -} - /* @end */ div.dynheader { @@ -912,7 +1303,7 @@ div.dynheader { address { font-style: normal; - color: #2A3D61; + color: var(--footer-foreground-color); } table.doxtable caption { @@ -926,28 +1317,23 @@ table.doxtable { } table.doxtable td, table.doxtable th { - border: 1px solid #2D4068; + border: 1px solid var(--table-cell-border-color); padding: 3px 7px 2px; } table.doxtable th { - background-color: #374F7F; - color: #FFFFFF; + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); font-size: 110%; padding-bottom: 4px; padding-top: 5px; } table.fieldtable { - /*width: 100%;*/ margin-bottom: 10px; - border: 1px solid #A8B8D9; + border: 1px solid var(--memdef-border-color); border-spacing: 0px; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; border-radius: 4px; - -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; - -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); } @@ -957,8 +1343,8 @@ table.fieldtable { .fieldtable td.fieldtype, .fieldtable td.fieldname { white-space: nowrap; - border-right: 1px solid #A8B8D9; - border-bottom: 1px solid #A8B8D9; + border-right: 1px solid var(--memdef-border-color); + border-bottom: 1px solid var(--memdef-border-color); vertical-align: top; } @@ -967,14 +1353,13 @@ table.fieldtable { } .fieldtable td.fielddoc { - border-bottom: 1px solid #A8B8D9; - /*width: 100%;*/ + border-bottom: 1px solid var(--memdef-border-color); } .fieldtable td.fielddoc p:first-child { margin-top: 0px; -} - +} + .fieldtable td.fielddoc p:last-child { margin-bottom: 2px; } @@ -984,22 +1369,18 @@ table.fieldtable { } .fieldtable th { - background-image:url('nav_f.png'); + background-image: var(--memdef-title-gradient-image); background-repeat:repeat-x; - background-color: #E2E8F2; + background-color: var(--memdef-title-background-color); font-size: 90%; - color: #253555; + color: var(--memdef-proto-text-color); padding-bottom: 4px; padding-top: 5px; text-align:left; font-weight: 400; - -moz-border-radius-topleft: 4px; - -moz-border-radius-topright: 4px; - -webkit-border-top-left-radius: 4px; - -webkit-border-top-right-radius: 4px; border-top-left-radius: 4px; border-top-right-radius: 4px; - border-bottom: 1px solid #A8B8D9; + border-bottom: 1px solid var(--memdef-border-color); } @@ -1007,7 +1388,7 @@ table.fieldtable { top: 0px; left: 10px; height: 36px; - background-image: url('tab_b.png'); + background-image: var(--nav-gradient-image); z-index: 101; overflow: hidden; font-size: 13px; @@ -1016,13 +1397,13 @@ table.fieldtable { .navpath ul { font-size: 11px; - background-image:url('tab_b.png'); + background-image: var(--nav-gradient-image); background-repeat:repeat-x; background-position: 0 -5px; height:30px; line-height:30px; - color:#8AA0CC; - border:solid 1px #C2CDE4; + color:var(--nav-text-normal-color); + border:solid 1px var(--nav-breadcrumb-border-color); overflow:hidden; margin:0px; padding:0px; @@ -1034,10 +1415,10 @@ table.fieldtable { float:left; padding-left:10px; padding-right:15px; - background-image:url('bc_s.png'); + background-image:var(--nav-breadcrumb-image); background-repeat:no-repeat; background-position:right; - color:#364D7C; + color: var(--nav-foreground-color); } .navpath li.navelem a @@ -1046,15 +1427,16 @@ table.fieldtable { display:block; text-decoration: none; outline: none; - color: #283A5D; - font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif; - text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); - text-decoration: none; + color: var(--nav-text-normal-color); + font-family: var(--font-family-nav); + text-shadow: var(--nav-text-normal-shadow); + text-decoration: none; } .navpath li.navelem a:hover { - color:#6884BD; + color: var(--nav-text-hover-color); + text-shadow: var(--nav-text-hover-shadow); } .navpath li.footer @@ -1066,7 +1448,7 @@ table.fieldtable { background-image:none; background-repeat:no-repeat; background-position:right; - color:#364D7C; + color: var(--footer-foreground-color); font-size: 8pt; } @@ -1078,7 +1460,7 @@ div.summary padding-right: 5px; width: 50%; text-align: right; -} +} div.summary a { @@ -1093,7 +1475,7 @@ table.classindex margin-right: 3%; width: 94%; border: 0; - border-spacing: 0; + border-spacing: 0; padding: 0; } @@ -1111,11 +1493,11 @@ div.ingroups a div.header { - background-image:url('nav_h.png'); + background-image: var(--header-gradient-image); background-repeat:repeat-x; - background-color: #F9FAFC; + background-color: var(--header-background-color); margin: 0px; - border-bottom: 1px solid #C4CFE5; + border-bottom: 1px solid var(--header-separator-color); } div.headertitle @@ -1138,11 +1520,6 @@ dl.section { padding-left: 0px; } -dl.section.DocNodeRTL { - margin-right: 0px; - padding-right: 0px; -} - dl.note { margin-left: -7px; padding-left: 3px; @@ -1150,16 +1527,6 @@ dl.note { border-color: #D0C000; } -dl.note.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #D0C000; -} - dl.warning, dl.attention { margin-left: -7px; padding-left: 3px; @@ -1167,16 +1534,6 @@ dl.warning, dl.attention { border-color: #FF0000; } -dl.warning.DocNodeRTL, dl.attention.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #FF0000; -} - dl.pre, dl.post, dl.invariant { margin-left: -7px; padding-left: 3px; @@ -1184,16 +1541,6 @@ dl.pre, dl.post, dl.invariant { border-color: #00D000; } -dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00D000; -} - dl.deprecated { margin-left: -7px; padding-left: 3px; @@ -1201,16 +1548,6 @@ dl.deprecated { border-color: #505050; } -dl.deprecated.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #505050; -} - dl.todo { margin-left: -7px; padding-left: 3px; @@ -1218,16 +1555,6 @@ dl.todo { border-color: #00C0E0; } -dl.todo.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #00C0E0; -} - dl.test { margin-left: -7px; padding-left: 3px; @@ -1235,16 +1562,6 @@ dl.test { border-color: #3030E0; } -dl.test.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #3030E0; -} - dl.bug { margin-left: -7px; padding-left: 3px; @@ -1252,21 +1569,16 @@ dl.bug { border-color: #C08050; } -dl.bug.DocNodeRTL { - margin-left: 0; - padding-left: 0; - border-left: 0; - margin-right: -7px; - padding-right: 3px; - border-right: 4px solid; - border-color: #C08050; -} - dl.section dd { margin-bottom: 6px; } +#projectrow +{ + height: 56px; +} + #projectlogo { text-align: center; @@ -1282,25 +1594,29 @@ dl.section dd { #projectalign { vertical-align: middle; + padding-left: 0.5em; } #projectname { - font: 300% Tahoma, Arial,sans-serif; + font-size: 200%; + font-family: var(--font-family-title); margin: 0px; padding: 2px 0px; } - + #projectbrief { - font: 120% Tahoma, Arial,sans-serif; + font-size: 90%; + font-family: var(--font-family-title); margin: 0px; padding: 0px; } #projectnumber { - font: 50% Tahoma, Arial,sans-serif; + font-size: 50%; + font-family: 50% var(--font-family-title); margin: 0px; padding: 0px; } @@ -1310,7 +1626,8 @@ dl.section dd { padding: 0px; margin: 0px; width: 100%; - border-bottom: 1px solid #5373B4; + border-bottom: 1px solid var(--title-separator-color); + background-color: var(--title-background-color); } .image @@ -1343,17 +1660,12 @@ dl.section dd { font-weight: bold; } -div.zoom -{ - border: 1px solid #90A5CE; -} - dl.citelist { margin-bottom:50px; } dl.citelist dt { - color:#334975; + color:var(--citation-label-color); float:left; font-weight:bold; margin-right:10px; @@ -1369,8 +1681,8 @@ dl.citelist dd { div.toc { padding: 14px 25px; - background-color: #F4F6FA; - border: 1px solid #D8DFEE; + background-color: var(--toc-background-color); + border: 1px solid var(--toc-border-color); border-radius: 7px 7px 7px 7px; float: right; height: auto; @@ -1378,28 +1690,17 @@ div.toc { width: 200px; } -.PageDocRTL-title div.toc { - float: left !important; - text-align: right; -} - div.toc li { - background: url("bdwn.png") no-repeat scroll 0 5px transparent; - font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + background: var(--toc-down-arrow-image) no-repeat scroll 0 5px transparent; + font: 10px/1.2 var(--font-family-toc); margin-top: 5px; padding-left: 10px; padding-top: 2px; } -.PageDocRTL-title div.toc li { - background-position-x: right !important; - padding-left: 0 !important; - padding-right: 10px; -} - div.toc h3 { - font: bold 12px/1.2 Arial,FreeSans,sans-serif; - color: #4665A2; + font: bold 12px/1.2 var(--font-family-toc); + color: var(--toc-header-color); border-bottom: 0 none; margin: 0; } @@ -1408,7 +1709,7 @@ div.toc ul { list-style: none outside none; border: medium none; padding: 0px; -} +} div.toc li.level1 { margin-left: 0px; @@ -1419,36 +1720,26 @@ div.toc li.level2 { } div.toc li.level3 { - margin-left: 30px; + margin-left: 15px; } div.toc li.level4 { - margin-left: 45px; -} - -.PageDocRTL-title div.toc li.level1 { - margin-left: 0 !important; - margin-right: 0; -} - -.PageDocRTL-title div.toc li.level2 { - margin-left: 0 !important; - margin-right: 15px; + margin-left: 15px; } -.PageDocRTL-title div.toc li.level3 { - margin-left: 0 !important; - margin-right: 30px; +span.emoji { + /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html + * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort; + */ } -.PageDocRTL-title div.toc li.level4 { - margin-left: 0 !important; - margin-right: 45px; +span.obfuscator { + display: none; } .inherit_header { font-weight: bold; - color: gray; + color: var(--inherit-header-color); cursor: pointer; -webkit-touch-callout: none; -webkit-user-select: none; @@ -1480,11 +1771,12 @@ tr.heading h2 { #powerTip { cursor: default; - white-space: nowrap; - background-color: white; - border: 1px solid gray; + /*white-space: nowrap;*/ + color: var(--tooltip-foreground-color); + background-color: var(--tooltip-background-color); + border: 1px solid var(--tooltip-border-color); border-radius: 4px 4px 4px 4px; - box-shadow: 1px 1px 7px gray; + box-shadow: var(--tooltip-shadow); display: none; font-size: smaller; max-width: 80%; @@ -1495,7 +1787,7 @@ tr.heading h2 { } #powerTip div.ttdoc { - color: grey; + color: var(--tooltip-doc-color); font-style: italic; } @@ -1503,18 +1795,24 @@ tr.heading h2 { font-weight: bold; } +#powerTip a { + color: var(--tooltip-link-color); +} + #powerTip div.ttname { font-weight: bold; } #powerTip div.ttdeci { - color: #006318; + color: var(--tooltip-declaration-color); } #powerTip div { margin: 0px; padding: 0px; - font: 12px/16px Roboto,sans-serif; + font-size: 12px; + font-family: var(--font-family-tooltip); + line-height: 16px; } #powerTip:before, #powerTip:after { @@ -1559,12 +1857,12 @@ tr.heading h2 { } #powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after { - border-top-color: #FFFFFF; + border-top-color: var(--tooltip-background-color); border-width: 10px; margin: 0px -10px; } -#powerTip.n:before { - border-top-color: #808080; +#powerTip.n:before, #powerTip.ne:before, #powerTip.nw:before { + border-top-color: var(--tooltip-border-color); border-width: 11px; margin: 0px -11px; } @@ -1587,13 +1885,13 @@ tr.heading h2 { } #powerTip.s:after, #powerTip.se:after, #powerTip.sw:after { - border-bottom-color: #FFFFFF; + border-bottom-color: var(--tooltip-background-color); border-width: 10px; margin: 0px -10px; } #powerTip.s:before, #powerTip.se:before, #powerTip.sw:before { - border-bottom-color: #808080; + border-bottom-color: var(--tooltip-border-color); border-width: 11px; margin: 0px -11px; } @@ -1614,13 +1912,13 @@ tr.heading h2 { left: 100%; } #powerTip.e:after { - border-left-color: #FFFFFF; + border-left-color: var(--tooltip-border-color); border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.e:before { - border-left-color: #808080; + border-left-color: var(--tooltip-border-color); border-width: 11px; top: 50%; margin-top: -11px; @@ -1630,13 +1928,13 @@ tr.heading h2 { right: 100%; } #powerTip.w:after { - border-right-color: #FFFFFF; + border-right-color: var(--tooltip-border-color); border-width: 10px; top: 50%; margin-top: -10px; } #powerTip.w:before { - border-right-color: #808080; + border-right-color: var(--tooltip-border-color); border-width: 11px; top: 50%; margin-top: -11px; @@ -1670,7 +1968,7 @@ table.markdownTable { } table.markdownTable td, table.markdownTable th { - border: 1px solid #2D4068; + border: 1px solid var(--table-cell-border-color); padding: 3px 7px 2px; } @@ -1678,8 +1976,8 @@ table.markdownTable tr { } th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone { - background-color: #374F7F; - color: #FFFFFF; + background-color: var(--table-header-background-color); + color: var(--table-header-foreground-color); font-size: 110%; padding-bottom: 4px; padding-top: 5px; @@ -1697,36 +1995,33 @@ th.markdownTableHeadCenter, td.markdownTableBodyCenter { text-align: center } -.DocNodeRTL { - text-align: right; - direction: rtl; +tt, code, kbd, samp +{ + display: inline-block; } +/* @end */ -.DocNodeLTR { - text-align: left; - direction: ltr; +u { + text-decoration: underline; } -table.DocNodeRTL { - width: auto; - margin-right: 0; - margin-left: auto; +details>summary { + list-style-type: none; } -table.DocNodeLTR { - width: auto; - margin-right: auto; - margin-left: 0; +details > summary::-webkit-details-marker { + display: none; } -tt, code, kbd, samp -{ - display: inline-block; - direction:ltr; +details>summary::before { + content: "\25ba"; + padding-right:4px; + font-size: 80%; } -/* @end */ -u { - text-decoration: underline; +details[open]>summary::before { + content: "\25bc"; + padding-right:4px; + font-size: 80%; } diff --git a/doc/html/doxygen.svg b/doc/html/doxygen.svg index d42dad5..79a7635 100644 --- a/doc/html/doxygen.svg +++ b/doc/html/doxygen.svg @@ -1,4 +1,6 @@ + @@ -17,7 +19,7 @@ - + diff --git a/doc/html/dynsections.js b/doc/html/dynsections.js index 3174bd7..b73c828 100644 --- a/doc/html/dynsections.js +++ b/doc/html/dynsections.js @@ -47,6 +47,8 @@ function updateStripes() { $('table.directory tr'). removeClass('even').filter(':visible:even').addClass('even'); + $('table.directory tr'). + removeClass('odd').filter(':visible:odd').addClass('odd'); } function toggleLevel(level) @@ -118,4 +120,73 @@ function toggleInherit(id) $(img).attr('src',src.substring(0,src.length-10)+'open.png'); } } + +var opened=true; +// in case HTML_COLORSTYLE is LIGHT or DARK the vars will be replaced, so we write them out explicitly and use double quotes +var plusImg = [ "var(--fold-plus-image)", "var(--fold-plus-image-relpath)" ]; +var minusImg = [ "var(--fold-minus-image)", "var(--fold-minus-image-relpath)" ]; + +// toggle all folding blocks +function codefold_toggle_all(relPath) { + if (opened) { + $('#fold_all').css('background-image',plusImg[relPath]); + $('div[id^=foldopen]').hide(); + $('div[id^=foldclosed]').show(); + } else { + $('#fold_all').css('background-image',minusImg[relPath]); + $('div[id^=foldopen]').show(); + $('div[id^=foldclosed]').hide(); + } + opened=!opened; +} + +// toggle single folding block +function codefold_toggle(id) { + $('#foldopen'+id).toggle(); + $('#foldclosed'+id).toggle(); +} +function init_codefold(relPath) { + $('span[class=lineno]').css( + {'padding-right':'4px', + 'margin-right':'2px', + 'display':'inline-block', + 'width':'54px', + 'background':'linear-gradient(var(--fold-line-color),var(--fold-line-color)) no-repeat 46px/2px 100%' + }); + // add global toggle to first line + $('span[class=lineno]:first').append(''); + // add vertical lines to other rows + $('span[class=lineno]').not(':eq(0)').append(''); + // add toggle controls to lines with fold divs + $('div[class=foldopen]').each(function() { + // extract specific id to use + var id = $(this).attr('id').replace('foldopen',''); + // extract start and end foldable fragment attributes + var start = $(this).attr('data-start'); + var end = $(this).attr('data-end'); + // replace normal fold span with controls for the first line of a foldable fragment + $(this).find('span[class=fold]:first').replaceWith(''); + // append div for folded (closed) representation + $(this).after(''); + // extract the first line from the "open" section to represent closed content + var line = $(this).children().first().clone(); + // remove any glow that might still be active on the original line + $(line).removeClass('glow'); + if (start) { + // if line already ends with a start marker (e.g. trailing {), remove it + $(line).html($(line).html().replace(new RegExp('\\s*'+start+'\\s*$','g'),'')); + } + // replace minus with plus symbol + $(line).find('span[class=fold]').css('background-image',plusImg[relPath]); + // append ellipsis + $(line).append(' '+start+''+end); + // insert constructed line into closed div + $('#foldclosed'+id).html(line); + }); +} + /* @license-end */ diff --git a/doc/html/folderclosed.png b/doc/html/folderclosed.png deleted file mode 100644 index bb8ab35..0000000 Binary files a/doc/html/folderclosed.png and /dev/null differ diff --git a/doc/html/folderclosed.svg b/doc/html/folderclosed.svg new file mode 100644 index 0000000..b04bed2 --- /dev/null +++ b/doc/html/folderclosed.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/doc/html/folderclosedd.svg b/doc/html/folderclosedd.svg new file mode 100644 index 0000000..52f0166 --- /dev/null +++ b/doc/html/folderclosedd.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/doc/html/folderopen.png b/doc/html/folderopen.png deleted file mode 100644 index d6c7f67..0000000 Binary files a/doc/html/folderopen.png and /dev/null differ diff --git a/doc/html/folderopen.svg b/doc/html/folderopen.svg new file mode 100644 index 0000000..f6896dd --- /dev/null +++ b/doc/html/folderopen.svg @@ -0,0 +1,17 @@ + + + + + + + + + + diff --git a/doc/html/folderopend.svg b/doc/html/folderopend.svg new file mode 100644 index 0000000..2d1f06e --- /dev/null +++ b/doc/html/folderopend.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/doc/html/functions.html b/doc/html/functions.html index 22c164b..67dc2fe 100644 --- a/doc/html/functions.html +++ b/doc/html/functions.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: Data Fields @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ + @@ -57,51 +57,36 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
diff --git a/doc/html/functions_vars.html b/doc/html/functions_vars.html index 0e3897e..964e303 100644 --- a/doc/html/functions_vars.html +++ b/doc/html/functions_vars.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: Data Fields - Variables @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ + @@ -57,51 +57,36 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
diff --git a/doc/html/group___turbo_j_p_e_g.html b/doc/html/group___turbo_j_p_e_g.html index 04285c2..42c3009 100644 --- a/doc/html/group___turbo_j_p_e_g.html +++ b/doc/html/group___turbo_j_p_e_g.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: TurboJPEG @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ + @@ -57,9 +57,16 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
@@ -70,15 +77,14 @@ $(function() { Enumerations | Functions | Variables
-
-
TurboJPEG
+
TurboJPEG

TurboJPEG API. More...

- @@ -90,321 +96,321 @@ Data Structures

+

Data Structures

struct  tjscalingfactor
 Scaling factor. More...
 Lossless transform. More...
 
- - - + + - - + + - - + + - - + + - - - - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Macros

#define TJ_NUMINIT
 The number of initialization options. More...
#define TJ_NUMINIT
 The number of initialization options.
 
#define TJ_NUMSAMP
 The number of chrominance subsampling options. More...
#define TJ_NUMSAMP
 The number of chrominance subsampling options.
 
#define TJ_NUMPF
 The number of pixel formats. More...
#define TJ_NUMPF
 The number of pixel formats.
 
#define TJ_NUMCS
 The number of JPEG colorspaces. More...
#define TJ_NUMCS
 The number of JPEG colorspaces.
 
#define TJ_NUMPARAM
 The number of parameters. More...
 
#define TJ_NUMERR
 The number of error codes. More...
#define TJ_NUMERR
 The number of error codes.
 
#define TJ_NUMXOP
 The number of transform operations. More...
#define TJ_NUMXOP
 The number of transform operations.
 
#define TJXOPT_PERFECT
 This option will cause tj3Transform() to return an error if the transform is not perfect. More...
#define TJXOPT_PERFECT
 This option causes tj3Transform() to return an error if the transform is not perfect.
 
#define TJXOPT_TRIM
 This option will cause tj3Transform() to discard any partial MCU blocks that cannot be transformed. More...
#define TJXOPT_TRIM
 Discard any partial iMCUs that cannot be transformed.
 
#define TJXOPT_CROP
 This option will enable lossless cropping. More...
#define TJXOPT_CROP
 Enable lossless cropping.
 
#define TJXOPT_GRAY
 This option will discard the color data in the source image and produce a grayscale destination image. More...
#define TJXOPT_GRAY
 Discard the color data in the source image, and generate a grayscale destination image.
 
#define TJXOPT_NOOUTPUT
 This option will prevent tj3Transform() from outputting a JPEG image for this particular transform. More...
#define TJXOPT_NOOUTPUT
 Do not generate a destination image.
 
#define TJXOPT_PROGRESSIVE
 This option will enable progressive entropy coding in the JPEG image generated by this particular transform. More...
#define TJXOPT_PROGRESSIVE
 Generate a progressive destination image instead of a single-scan destination image.
 
#define TJXOPT_COPYNONE
 This option will prevent tj3Transform() from copying any extra markers (including EXIF and ICC profile data) from the source image to the destination image. More...
#define TJXOPT_COPYNONE
 Do not copy any extra markers (including Exif and ICC profile data) from the source image to the destination image.
 
#define TJXOPT_ARITHMETIC
 This option will enable arithmetic entropy coding in the JPEG image generated by this particular transform. More...
#define TJXOPT_ARITHMETIC
 Enable arithmetic entropy coding in the destination image.
 
#define TJXOPT_OPTIMIZE
 This option will enable optimized baseline entropy coding in the JPEG image generated by this particular transform. More...
#define TJXOPT_OPTIMIZE
 Enable Huffman table optimization for the destination image.
 
#define TJSCALED(dimension, scalingFactor)
 Compute the scaled value of dimension using the given scaling factor. More...
#define TJSCALED(dimension, scalingFactor)
 Compute the scaled value of dimension using the given scaling factor.
 
- - - + + - - + +

+

Typedefs

typedef struct tjtransform tjtransform
 Lossless transform. More...
typedef struct tjtransform tjtransform
 Lossless transform.
 
typedef void * tjhandle
 TurboJPEG instance handle. More...
typedef void * tjhandle
 TurboJPEG instance handle.
 
- - - - - - - -

+

Enumerations

enum  TJINIT { TJINIT_COMPRESS, -TJINIT_DECOMPRESS, -TJINIT_TRANSFORM +
enum  TJINIT { TJINIT_COMPRESS +, TJINIT_DECOMPRESS +, TJINIT_TRANSFORM }
 Initialization options. More...
 
enum  TJSAMP {
-  TJSAMP_444, -TJSAMP_422, -TJSAMP_420, -TJSAMP_GRAY, -
-  TJSAMP_440, -TJSAMP_411, -TJSAMP_441, -TJSAMP_UNKNOWN +
enum  TJSAMP {
+  TJSAMP_444 +, TJSAMP_422 +, TJSAMP_420 +, TJSAMP_GRAY +,
+  TJSAMP_440 +, TJSAMP_411 +, TJSAMP_441 +, TJSAMP_UNKNOWN
}
 Chrominance subsampling options. More...
 
enum  TJPF {
-  TJPF_RGB, -TJPF_BGR, -TJPF_RGBX, -TJPF_BGRX, -
-  TJPF_XBGR, -TJPF_XRGB, -TJPF_GRAY, -TJPF_RGBA, -
-  TJPF_BGRA, -TJPF_ABGR, -TJPF_ARGB, -TJPF_CMYK, -
+
enum  TJPF {
+  TJPF_RGB +, TJPF_BGR +, TJPF_RGBX +, TJPF_BGRX +,
+  TJPF_XBGR +, TJPF_XRGB +, TJPF_GRAY +, TJPF_RGBA +,
+  TJPF_BGRA +, TJPF_ABGR +, TJPF_ARGB +, TJPF_CMYK +,
  TJPF_UNKNOWN
}
 Pixel formats. More...
 
enum  TJCS {
-  TJCS_RGB, -TJCS_YCbCr, -TJCS_GRAY, -TJCS_CMYK, -
+
enum  TJCS {
+  TJCS_RGB +, TJCS_YCbCr +, TJCS_GRAY +, TJCS_CMYK +,
  TJCS_YCCK
}
 JPEG colorspaces. More...
 
enum  TJPARAM {
-  TJPARAM_STOPONWARNING, -TJPARAM_BOTTOMUP, -TJPARAM_NOREALLOC, -TJPARAM_QUALITY, -
-  TJPARAM_SUBSAMP, -TJPARAM_JPEGWIDTH, -TJPARAM_JPEGHEIGHT, -TJPARAM_PRECISION, -
-  TJPARAM_COLORSPACE, -TJPARAM_FASTUPSAMPLE, -TJPARAM_FASTDCT, -TJPARAM_OPTIMIZE, -
-  TJPARAM_PROGRESSIVE, -TJPARAM_SCANLIMIT, -TJPARAM_ARITHMETIC, -TJPARAM_LOSSLESS, -
-  TJPARAM_LOSSLESSPSV, -TJPARAM_LOSSLESSPT, -TJPARAM_RESTARTBLOCKS, -TJPARAM_RESTARTROWS, -
-  TJPARAM_XDENSITY, -TJPARAM_YDENSITY, -TJPARAM_DENSITYUNITS +
enum  TJPARAM {
+  TJPARAM_STOPONWARNING +, TJPARAM_BOTTOMUP +, TJPARAM_NOREALLOC +, TJPARAM_QUALITY +,
+  TJPARAM_SUBSAMP +, TJPARAM_JPEGWIDTH +, TJPARAM_JPEGHEIGHT +, TJPARAM_PRECISION +,
+  TJPARAM_COLORSPACE +, TJPARAM_FASTUPSAMPLE +, TJPARAM_FASTDCT +, TJPARAM_OPTIMIZE +,
+  TJPARAM_PROGRESSIVE +, TJPARAM_SCANLIMIT +, TJPARAM_ARITHMETIC +, TJPARAM_LOSSLESS +,
+  TJPARAM_LOSSLESSPSV +, TJPARAM_LOSSLESSPT +, TJPARAM_RESTARTBLOCKS +, TJPARAM_RESTARTROWS +,
+  TJPARAM_XDENSITY +, TJPARAM_YDENSITY +, TJPARAM_DENSITYUNITS +, TJPARAM_MAXMEMORY +,
+  TJPARAM_MAXPIXELS
}
 Parameters. More...
 
enum  TJERR { TJERR_WARNING, -TJERR_FATAL +
enum  TJERR { TJERR_WARNING +, TJERR_FATAL }
 Error codes. More...
 
enum  TJXOP {
-  TJXOP_NONE, -TJXOP_HFLIP, -TJXOP_VFLIP, -TJXOP_TRANSPOSE, -
-  TJXOP_TRANSVERSE, -TJXOP_ROT90, -TJXOP_ROT180, -TJXOP_ROT270 +
enum  TJXOP {
+  TJXOP_NONE +, TJXOP_HFLIP +, TJXOP_VFLIP +, TJXOP_TRANSPOSE +,
+  TJXOP_TRANSVERSE +, TJXOP_ROT90 +, TJXOP_ROT180 +, TJXOP_ROT270
}
 Transform operations for tj3Transform() More...
 
- - - + + - - + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - - - + + + + + + + + - - + + - - + + - - + + - - + + - - - - - + + + + + + + + + + + + + + + + + - - + + + + + - - - - - + + + + + - - + + - - + + - - + + - - + + - - - - - + + - - - - - + + + + + - - + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + - - + + - - + + - - - - - - - - -

+

Functions

DLLEXPORT tjhandle tj3Init (int initType)
 Create a new TurboJPEG instance. More...
DLLEXPORT tjhandle tj3Init (int initType)
 Create a new TurboJPEG instance.
 
DLLEXPORT int tj3Set (tjhandle handle, int param, int value)
 Set the value of a parameter. More...
DLLEXPORT void tj3Destroy (tjhandle handle)
 Destroy a TurboJPEG instance.
 
DLLEXPORT char * tj3GetErrorStr (tjhandle handle)
 Returns a descriptive error message explaining why the last command failed.
 
DLLEXPORT int tj3GetErrorCode (tjhandle handle)
 Returns a code indicating the severity of the last error.
 
DLLEXPORT int tj3Set (tjhandle handle, int param, int value)
 Set the value of a parameter.
 
DLLEXPORT int tj3Get (tjhandle handle, int param)
 Get the value of a parameter. More...
DLLEXPORT int tj3Get (tjhandle handle, int param)
 Get the value of a parameter.
 
DLLEXPORT int tj3Compress8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into an 8-bit-per-sample JPEG image. More...
 
DLLEXPORT int tj3Compress12 (tjhandle handle, const short *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a 12-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into a 12-bit-per-sample JPEG image. More...
 
DLLEXPORT int tj3Compress16 (tjhandle handle, const unsigned short *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a 16-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into a 16-bit-per-sample lossless JPEG image. More...
 
DLLEXPORT int tj3CompressFromYUV8 (tjhandle handle, const unsigned char *srcBuf, int width, int align, int height, unsigned char **jpegBuf, size_t *jpegSize)
 Compress an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample JPEG image. More...
 
DLLEXPORT int tj3CompressFromYUVPlanes8 (tjhandle handle, const unsigned char *const *srcPlanes, int width, const int *strides, int height, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into an 8-bit-per-sample JPEG image. More...
 
DLLEXPORT size_t tj3JPEGBufSize (int width, int height, int jpegSubsamp)
 The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters. More...
DLLEXPORT void * tj3Alloc (size_t bytes)
 Allocate a byte buffer for use with TurboJPEG.
 
DLLEXPORT void tj3Free (void *buffer)
 Free a byte buffer previously allocated by TurboJPEG.
 
DLLEXPORT size_t tj3JPEGBufSize (int width, int height, int jpegSubsamp)
 The maximum size of the buffer (in bytes) required to hold a JPEG image with the given parameters.
 
DLLEXPORT size_t tj3YUVBufSize (int width, int align, int height, int subsamp)
 The size of the buffer (in bytes) required to hold a unified planar YUV image with the given parameters. More...
DLLEXPORT size_t tj3YUVBufSize (int width, int align, int height, int subsamp)
 The size of the buffer (in bytes) required to hold a unified planar YUV image with the given parameters.
 
DLLEXPORT size_t tj3YUVPlaneSize (int componentID, int width, int stride, int height, int subsamp)
 The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters. More...
DLLEXPORT size_t tj3YUVPlaneSize (int componentID, int width, int stride, int height, int subsamp)
 The size of the buffer (in bytes) required to hold a YUV image plane with the given parameters.
 
DLLEXPORT int tj3YUVPlaneWidth (int componentID, int width, int subsamp)
 The plane width of a YUV image plane with the given parameters. More...
DLLEXPORT int tj3YUVPlaneWidth (int componentID, int width, int subsamp)
 The plane width of a YUV image plane with the given parameters.
 
DLLEXPORT int tj3YUVPlaneHeight (int componentID, int height, int subsamp)
 The plane height of a YUV image plane with the given parameters. More...
DLLEXPORT int tj3YUVPlaneHeight (int componentID, int height, int subsamp)
 The plane height of a YUV image plane with the given parameters.
 
DLLEXPORT int tj3EncodeYUV8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int align)
 Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into an 8-bit-per-sample unified planar YUV image. More...
 
DLLEXPORT int tj3EncodeYUVPlanes8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **dstPlanes, int *strides)
 Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into separate 8-bit-per-sample Y, U (Cb), and V (Cr) image planes. More...
DLLEXPORT int tj3Compress8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into an 8-bit-per-sample JPEG image.
 
DLLEXPORT int tj3Compress12 (tjhandle handle, const short *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a 12-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into a 12-bit-per-sample JPEG image.
 
DLLEXPORT int tj3Compress16 (tjhandle handle, const unsigned short *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a 16-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into a 16-bit-per-sample lossless JPEG image.
 
DLLEXPORT int tj3CompressFromYUVPlanes8 (tjhandle handle, const unsigned char *const *srcPlanes, int width, const int *strides, int height, unsigned char **jpegBuf, size_t *jpegSize)
 Compress a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into an 8-bit-per-sample JPEG image.
 
DLLEXPORT int tj3CompressFromYUV8 (tjhandle handle, const unsigned char *srcBuf, int width, int align, int height, unsigned char **jpegBuf, size_t *jpegSize)
 Compress an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample JPEG image.
 
DLLEXPORT int tj3EncodeYUVPlanes8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char **dstPlanes, int *strides)
 Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into separate 8-bit-per-sample Y, U (Cb), and V (Cr) image planes.
 
DLLEXPORT int tj3DecompressHeader (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize)
 Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables. More...
DLLEXPORT int tj3EncodeYUV8 (tjhandle handle, const unsigned char *srcBuf, int width, int pitch, int height, int pixelFormat, unsigned char *dstBuf, int align)
 Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into an 8-bit-per-sample unified planar YUV image.
 
DLLEXPORT int tj3DecompressHeader (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize)
 Retrieve information about a JPEG image without decompressing it, or prime the decompressor with quantization and Huffman tables.
 
DLLEXPORT tjscalingfactortj3GetScalingFactors (int *numScalingFactors)
 Returns a list of fractional scaling factors that the JPEG decompressor supports. More...
 
DLLEXPORT int tj3SetScalingFactor (tjhandle handle, tjscalingfactor scalingFactor)
 Set the scaling factor for subsequent lossy decompression operations. More...
DLLEXPORT tjscalingfactortj3GetScalingFactors (int *numScalingFactors)
 Returns a list of fractional scaling factors that the JPEG decompressor supports.
 
DLLEXPORT int tj3SetScalingFactor (tjhandle handle, tjscalingfactor scalingFactor)
 Set the scaling factor for subsequent lossy decompression operations.
 
DLLEXPORT int tj3SetCroppingRegion (tjhandle handle, tjregion croppingRegion)
 Set the cropping region for partially decompressing a lossy JPEG image into a packed-pixel image. More...
DLLEXPORT int tj3SetCroppingRegion (tjhandle handle, tjregion croppingRegion)
 Set the cropping region for partially decompressing a lossy JPEG image into a packed-pixel image.
 
DLLEXPORT int tj3Decompress8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char *dstBuf, int pitch, int pixelFormat)
 Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK image. More...
DLLEXPORT int tj3Decompress8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char *dstBuf, int pitch, int pixelFormat)
 Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK image.
 
DLLEXPORT int tj3Decompress12 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, short *dstBuf, int pitch, int pixelFormat)
 Decompress a 12-bit-per-sample JPEG image into a 12-bit-per-sample packed-pixel RGB, grayscale, or CMYK image. More...
DLLEXPORT int tj3Decompress12 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, short *dstBuf, int pitch, int pixelFormat)
 Decompress a 12-bit-per-sample JPEG image into a 12-bit-per-sample packed-pixel RGB, grayscale, or CMYK image.
 
DLLEXPORT int tj3Decompress16 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned short *dstBuf, int pitch, int pixelFormat)
 Decompress a 16-bit-per-sample lossless JPEG image into a 16-bit-per-sample packed-pixel RGB, grayscale, or CMYK image. More...
DLLEXPORT int tj3Decompress16 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned short *dstBuf, int pitch, int pixelFormat)
 Decompress a 16-bit-per-sample lossless JPEG image into a 16-bit-per-sample packed-pixel RGB, grayscale, or CMYK image.
 
DLLEXPORT int tj3DecompressToYUV8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char *dstBuf, int align)
 Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample unified planar YUV image. More...
 
DLLEXPORT int tj3DecompressToYUVPlanes8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char **dstPlanes, int *strides)
 Decompress an 8-bit-per-sample JPEG image into separate 8-bit-per-sample Y, U (Cb), and V (Cr) image planes. More...
DLLEXPORT int tj3DecompressToYUVPlanes8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char **dstPlanes, int *strides)
 Decompress an 8-bit-per-sample JPEG image into separate 8-bit-per-sample Y, U (Cb), and V (Cr) image planes.
 
DLLEXPORT int tj3DecodeYUV8 (tjhandle handle, const unsigned char *srcBuf, int align, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat)
 Decode an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample packed-pixel RGB or grayscale image. More...
 
DLLEXPORT int tj3DecodeYUVPlanes8 (tjhandle handle, const unsigned char *const *srcPlanes, const int *strides, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat)
 Decode a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into an 8-bit-per-sample packed-pixel RGB or grayscale image. More...
DLLEXPORT int tj3DecompressToYUV8 (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, unsigned char *dstBuf, int align)
 Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample unified planar YUV image.
 
DLLEXPORT int tj3DecodeYUVPlanes8 (tjhandle handle, const unsigned char *const *srcPlanes, const int *strides, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat)
 Decode a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into an 8-bit-per-sample packed-pixel RGB or grayscale image.
 
DLLEXPORT int tj3Transform (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, int n, unsigned char **dstBufs, size_t *dstSizes, const tjtransform *transforms)
 Losslessly transform a JPEG image into another JPEG image. More...
DLLEXPORT int tj3DecodeYUV8 (tjhandle handle, const unsigned char *srcBuf, int align, unsigned char *dstBuf, int width, int pitch, int height, int pixelFormat)
 Decode an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample packed-pixel RGB or grayscale image.
 
DLLEXPORT int tj3Transform (tjhandle handle, const unsigned char *jpegBuf, size_t jpegSize, int n, unsigned char **dstBufs, size_t *dstSizes, const tjtransform *transforms)
 Losslessly transform a JPEG image into another JPEG image.
 
DLLEXPORT void tj3Destroy (tjhandle handle)
 Destroy a TurboJPEG instance. More...
 
DLLEXPORT void * tj3Alloc (size_t bytes)
 Allocate a byte buffer for use with TurboJPEG. More...
 
DLLEXPORT unsigned char * tj3LoadImage8 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load an 8-bit-per-sample packed-pixel image from disk into memory. More...
 
DLLEXPORT short * tj3LoadImage12 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load a 12-bit-per-sample packed-pixel image from disk into memory. More...
 
DLLEXPORT unsigned short * tj3LoadImage16 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load a 16-bit-per-sample packed-pixel image from disk into memory. More...
 
DLLEXPORT int tj3SaveImage8 (tjhandle handle, const char *filename, const unsigned char *buffer, int width, int pitch, int height, int pixelFormat)
 Save an 8-bit-per-sample packed-pixel image from memory to disk. More...
DLLEXPORT unsigned char * tj3LoadImage8 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load an 8-bit-per-sample packed-pixel image from disk into memory.
 
DLLEXPORT short * tj3LoadImage12 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load a 12-bit-per-sample packed-pixel image from disk into memory.
 
DLLEXPORT unsigned short * tj3LoadImage16 (tjhandle handle, const char *filename, int *width, int align, int *height, int *pixelFormat)
 Load a 16-bit-per-sample packed-pixel image from disk into memory.
 
DLLEXPORT int tj3SaveImage8 (tjhandle handle, const char *filename, const unsigned char *buffer, int width, int pitch, int height, int pixelFormat)
 Save an 8-bit-per-sample packed-pixel image from memory to disk.
 
DLLEXPORT int tj3SaveImage12 (tjhandle handle, const char *filename, const short *buffer, int width, int pitch, int height, int pixelFormat)
 Save a 12-bit-per-sample packed-pixel image from memory to disk. More...
DLLEXPORT int tj3SaveImage12 (tjhandle handle, const char *filename, const short *buffer, int width, int pitch, int height, int pixelFormat)
 Save a 12-bit-per-sample packed-pixel image from memory to disk.
 
DLLEXPORT int tj3SaveImage16 (tjhandle handle, const char *filename, const unsigned short *buffer, int width, int pitch, int height, int pixelFormat)
 Save a 16-bit-per-sample packed-pixel image from memory to disk. More...
DLLEXPORT int tj3SaveImage16 (tjhandle handle, const char *filename, const unsigned short *buffer, int width, int pitch, int height, int pixelFormat)
 Save a 16-bit-per-sample packed-pixel image from memory to disk.
 
DLLEXPORT void tj3Free (void *buffer)
 Free a byte buffer previously allocated by TurboJPEG. More...
 
DLLEXPORT char * tj3GetErrorStr (tjhandle handle)
 Returns a descriptive error message explaining why the last command failed. More...
 
DLLEXPORT int tj3GetErrorCode (tjhandle handle)
 Returns a code indicating the severity of the last error. More...
 
- - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - - + +

+

Variables

static const int tjMCUWidth [TJ_NUMSAMP]
 MCU block width (in pixels) for a given level of chrominance subsampling. More...
static const int tjMCUWidth [TJ_NUMSAMP]
 iMCU width (in pixels) for a given level of chrominance subsampling
 
static const int tjMCUHeight [TJ_NUMSAMP]
 MCU block height (in pixels) for a given level of chrominance subsampling. More...
static const int tjMCUHeight [TJ_NUMSAMP]
 iMCU height (in pixels) for a given level of chrominance subsampling
 
static const int tjRedOffset [TJ_NUMPF]
 Red offset (in samples) for a given pixel format. More...
static const int tjRedOffset [TJ_NUMPF]
 Red offset (in samples) for a given pixel format.
 
static const int tjGreenOffset [TJ_NUMPF]
 Green offset (in samples) for a given pixel format. More...
static const int tjGreenOffset [TJ_NUMPF]
 Green offset (in samples) for a given pixel format.
 
static const int tjBlueOffset [TJ_NUMPF]
 Blue offset (in samples) for a given pixel format. More...
static const int tjBlueOffset [TJ_NUMPF]
 Blue offset (in samples) for a given pixel format.
 
static const int tjAlphaOffset [TJ_NUMPF]
 Alpha offset (in samples) for a given pixel format. More...
static const int tjAlphaOffset [TJ_NUMPF]
 Alpha offset (in samples) for a given pixel format.
 
static const int tjPixelSize [TJ_NUMPF]
 Pixel size (in samples) for a given pixel format. More...
static const int tjPixelSize [TJ_NUMPF]
 Pixel size (in samples) for a given pixel format.
 
static const tjregion TJUNCROPPED
 A tjregion structure that specifies no cropping. More...
static const tjregion TJUNCROPPED
 A tjregion structure that specifies no cropping.
 
static const tjscalingfactor TJUNSCALED
 A tjscalingfactor structure that specifies a scaling factor of 1/1 (no scaling) More...
static const tjscalingfactor TJUNSCALED
 A tjscalingfactor structure that specifies a scaling factor of 1/1 (no scaling)
 

Detailed Description

@@ -417,8 +423,8 @@ YUV Image Format Notes

Each plane is simply a 2D array of bytes, each byte representing the value of one of the components (Y, Cb, or Cr) at a particular location in the image. The width and height of each plane are determined by the image width, height, and level of chrominance subsampling. The luminance plane width is the image width padded to the nearest multiple of the horizontal subsampling factor (1 in the case of 4:4:4, grayscale, 4:4:0, or 4:4:1; 2 in the case of 4:2:2 or 4:2:0; 4 in the case of 4:1:1.) Similarly, the luminance plane height is the image height padded to the nearest multiple of the vertical subsampling factor (1 in the case of 4:4:4, 4:2:2, grayscale, or 4:1:1; 2 in the case of 4:2:0 or 4:4:0; 4 in the case of 4:4:1.) This is irrespective of any additional padding that may be specified as an argument to the various YUV functions. The chrominance plane width is equal to the luminance plane width divided by the horizontal subsampling factor, and the chrominance plane height is equal to the luminance plane height divided by the vertical subsampling factor.

For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is used, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 18 x 35 bytes. If you specify a row alignment of 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 20 x 35 bytes.

Macro Definition Documentation

- -

◆ TJ_NUMCS

+ +

◆ TJ_NUMCS

@@ -433,8 +439,8 @@ YUV Image Format Notes
- -

◆ TJ_NUMERR

+ +

◆ TJ_NUMERR

@@ -449,8 +455,8 @@ YUV Image Format Notes
- -

◆ TJ_NUMINIT

+ +

◆ TJ_NUMINIT

@@ -465,24 +471,8 @@ YUV Image Format Notes
- -

◆ TJ_NUMPARAM

- -
-
- - - - -
#define TJ_NUMPARAM
-
- -

The number of parameters.

- -
-
- -

◆ TJ_NUMPF

+ +

◆ TJ_NUMPF

@@ -497,8 +487,8 @@ YUV Image Format Notes
- -

◆ TJ_NUMSAMP

+ +

◆ TJ_NUMSAMP

@@ -513,8 +503,8 @@ YUV Image Format Notes
- -

◆ TJ_NUMXOP

+ +

◆ TJ_NUMXOP

@@ -529,8 +519,8 @@ YUV Image Format Notes
- -

◆ TJSCALED

+ +

◆ TJSCALED

@@ -556,12 +546,13 @@ YUV Image Format Notes

Compute the scaled value of dimension using the given scaling factor.

-

This macro performs the integer equivalent of ceil(dimension * scalingFactor).

+

This macro performs the integer equivalent of ceil(dimension * +scalingFactor).

- -

◆ TJXOPT_ARITHMETIC

+ +

◆ TJXOPT_ARITHMETIC

@@ -572,13 +563,13 @@ YUV Image Format Notes
-

This option will enable arithmetic entropy coding in the JPEG image generated by this particular transform.

-

Arithmetic entropy coding will generally improve compression relative to Huffman entropy coding (the default), but it will reduce decompression performance considerably. Can be combined with TJXOPT_PROGRESSIVE.

+

Enable arithmetic entropy coding in the destination image.

+

Arithmetic entropy coding generally improves compression relative to Huffman entropy coding (the default), but it reduces decompression performance considerably. Can be combined with TJXOPT_PROGRESSIVE.

- -

◆ TJXOPT_COPYNONE

+ +

◆ TJXOPT_COPYNONE

@@ -589,12 +580,12 @@ YUV Image Format Notes
-

This option will prevent tj3Transform() from copying any extra markers (including EXIF and ICC profile data) from the source image to the destination image.

+

Do not copy any extra markers (including Exif and ICC profile data) from the source image to the destination image.

- -

◆ TJXOPT_CROP

+ +

◆ TJXOPT_CROP

@@ -605,13 +596,13 @@ YUV Image Format Notes
-

This option will enable lossless cropping.

+

Enable lossless cropping.

See tj3Transform() for more information.

- -

◆ TJXOPT_GRAY

+ +

◆ TJXOPT_GRAY

@@ -622,12 +613,12 @@ YUV Image Format Notes
-

This option will discard the color data in the source image and produce a grayscale destination image.

+

Discard the color data in the source image, and generate a grayscale destination image.

- -

◆ TJXOPT_NOOUTPUT

+ +

◆ TJXOPT_NOOUTPUT

@@ -638,13 +629,13 @@ YUV Image Format Notes
-

This option will prevent tj3Transform() from outputting a JPEG image for this particular transform.

+

Do not generate a destination image.

(This can be used in conjunction with a custom filter to capture the transformed DCT coefficients without transcoding them.)

- -

◆ TJXOPT_OPTIMIZE

+ +

◆ TJXOPT_OPTIMIZE

@@ -655,13 +646,13 @@ YUV Image Format Notes
-

This option will enable optimized baseline entropy coding in the JPEG image generated by this particular transform.

-

Optimized baseline entropy coding will improve compression slightly (generally 5% or less.)

+

Enable Huffman table optimization for the destination image.

+

Huffman table optimization improves compression slightly (generally 5% or less.)

- -

◆ TJXOPT_PERFECT

+ +

◆ TJXOPT_PERFECT

@@ -672,13 +663,13 @@ YUV Image Format Notes
-

This option will cause tj3Transform() to return an error if the transform is not perfect.

-

Lossless transforms operate on MCU blocks, whose size depends on the level of chrominance subsampling used (see tjMCUWidth and tjMCUHeight.) If the image's width or height is not evenly divisible by the MCU block size, then there will be partial MCU blocks on the right and/or bottom edges. It is not possible to move these partial MCU blocks to the top or left of the image, so any transform that would require that is "imperfect." If this option is not specified, then any partial MCU blocks that cannot be transformed will be left in place, which will create odd-looking strips on the right or bottom edge of the image.

+

This option causes tj3Transform() to return an error if the transform is not perfect.

+

Lossless transforms operate on iMCUs, the size of which depends on the level of chrominance subsampling used (see tjMCUWidth and tjMCUHeight.) If the image's width or height is not evenly divisible by the iMCU size, then there will be partial iMCUs on the right and/or bottom edges. It is not possible to move these partial iMCUs to the top or left of the image, so any transform that would require that is "imperfect." If this option is not specified, then any partial iMCUs that cannot be transformed will be left in place, which will create odd-looking strips on the right or bottom edge of the image.

- -

◆ TJXOPT_PROGRESSIVE

+ +

◆ TJXOPT_PROGRESSIVE

@@ -689,13 +680,13 @@ YUV Image Format Notes
-

This option will enable progressive entropy coding in the JPEG image generated by this particular transform.

-

Progressive entropy coding will generally improve compression relative to baseline entropy coding (the default), but it will reduce decompression performance considerably. Can be combined with TJXOPT_ARITHMETIC. Implies TJXOPT_OPTIMIZE unless TJXOPT_ARITHMETIC is also specified.

+

Generate a progressive destination image instead of a single-scan destination image.

+

Progressive JPEG images generally have better compression ratios than single-scan JPEG images (much better if the image has large areas of solid color), but progressive JPEG decompression is considerably slower than single-scan JPEG decompression. Can be combined with TJXOPT_ARITHMETIC. Implies TJXOPT_OPTIMIZE unless TJXOPT_ARITHMETIC is also specified.

- -

◆ TJXOPT_TRIM

+ +

◆ TJXOPT_TRIM

@@ -706,13 +697,13 @@ YUV Image Format Notes
-

This option will cause tj3Transform() to discard any partial MCU blocks that cannot be transformed.

+

Discard any partial iMCUs that cannot be transformed.

Typedef Documentation

- -

◆ tjhandle

+ +

◆ tjhandle

@@ -727,8 +718,8 @@ YUV Image Format Notes
- -

◆ tjtransform

+ +

◆ tjtransform

@@ -744,8 +735,8 @@ YUV Image Format Notes

Enumeration Type Documentation

- -

◆ TJCS

+ +

◆ TJCS

@@ -758,27 +749,27 @@ YUV Image Format Notes

JPEG colorspaces.

- - - - -
Enumerator
TJCS_RGB 

RGB colorspace.

-

When compressing the JPEG image, the R, G, and B components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. RGB JPEG images can be compressed from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats, but they cannot be compressed from or decompressed to planar YUV images.

+
Enumerator
TJCS_RGB 

RGB colorspace.

+

When generating the JPEG image, the R, G, and B components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. RGB JPEG images can be generated from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats, but they cannot be generated from or decompressed to planar YUV images.

TJCS_YCbCr 

YCbCr colorspace.

-

YCbCr is not an absolute colorspace but rather a mathematical transformation of RGB designed solely for storage and transmission. YCbCr images must be converted to RGB before they can actually be displayed. In the YCbCr colorspace, the Y (luminance) component represents the black & white portion of the original image, and the Cb and Cr (chrominance) components represent the color portion of the original image. Originally, the analog equivalent of this transformation allowed the same signal to drive both black & white and color televisions, but JPEG images use YCbCr primarily because it allows the color data to be optionally subsampled for the purposes of reducing network or disk usage. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images can be compressed from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats. YCbCr JPEG images can also be compressed from and decompressed to planar YUV images.

+
TJCS_YCbCr 

YCbCr colorspace.

+

YCbCr is not an absolute colorspace but rather a mathematical transformation of RGB designed solely for storage and transmission. YCbCr images must be converted to RGB before they can be displayed. In the YCbCr colorspace, the Y (luminance) component represents the black & white portion of the original image, and the Cb and Cr (chrominance) components represent the color portion of the original image. Historically, the analog equivalent of this transformation allowed the same signal to be displayed to both black & white and color televisions, but JPEG images use YCbCr primarily because it allows the color data to be optionally subsampled in order to reduce network and disk usage. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images can be generated from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats. YCbCr JPEG images can also be generated from and decompressed to planar YUV images.

TJCS_GRAY 

Grayscale colorspace.

-

The JPEG image retains only the luminance data (Y component), and any color data from the source image is discarded. Grayscale JPEG images can be compressed from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats, or they can be compressed from and decompressed to planar YUV images.

+
TJCS_GRAY 

Grayscale colorspace.

+

The JPEG image retains only the luminance data (Y component), and any color data from the source image is discarded. Grayscale JPEG images can be generated from and decompressed to packed-pixel images with any of the extended RGB or grayscale pixel formats, or they can be generated from and decompressed to planar YUV images.

TJCS_CMYK 

CMYK colorspace.

-

When compressing the JPEG image, the C, M, Y, and K components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. CMYK JPEG images can only be compressed from and decompressed to packed-pixel images with the CMYK pixel format.

+
TJCS_CMYK 

CMYK colorspace.

+

When generating the JPEG image, the C, M, Y, and K components in the source image are reordered into image planes, but no colorspace conversion or subsampling is performed. CMYK JPEG images can only be generated from and decompressed to packed-pixel images with the CMYK pixel format.

TJCS_YCCK 

YCCK colorspace.

-

YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a mathematical transformation of CMYK designed solely for storage and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be reversibly transformed into YCCK, and as with YCbCr, the chrominance components in the YCCK pixels can be subsampled without incurring major perceptual loss. YCCK JPEG images can only be compressed from and decompressed to packed-pixel images with the CMYK pixel format.

+
TJCS_YCCK 

YCCK colorspace.

+

YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a mathematical transformation of CMYK designed solely for storage and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be reversibly transformed into YCCK, and as with YCbCr, the chrominance components in the YCCK pixels can be subsampled without incurring major perceptual loss. YCCK JPEG images can only be generated from and decompressed to packed-pixel images with the CMYK pixel format.

- -

◆ TJERR

+ +

◆ TJERR

@@ -791,16 +782,16 @@ YUV Image Format Notes

Error codes.

- -
Enumerator
TJERR_WARNING 

The error was non-fatal and recoverable, but the destination image may still be corrupt.

+
Enumerator
TJERR_WARNING 

The error was non-fatal and recoverable, but the destination image may still be corrupt.

TJERR_FATAL 

The error was fatal and non-recoverable.

+
TJERR_FATAL 

The error was fatal and non-recoverable.

- -

◆ TJINIT

+ +

◆ TJINIT

@@ -813,18 +804,18 @@ YUV Image Format Notes

Initialization options.

- - -
Enumerator
TJINIT_COMPRESS 

Initialize the TurboJPEG instance for compression.

+
Enumerator
TJINIT_COMPRESS 

Initialize the TurboJPEG instance for compression.

TJINIT_DECOMPRESS 

Initialize the TurboJPEG instance for decompression.

+
TJINIT_DECOMPRESS 

Initialize the TurboJPEG instance for decompression.

TJINIT_TRANSFORM 

Initialize the TurboJPEG instance for lossless transformation (both compression and decompression.)

+
TJINIT_TRANSFORM 

Initialize the TurboJPEG instance for lossless transformation (both compression and decompression.)

- -

◆ TJPARAM

+ +

◆ TJPARAM

@@ -837,59 +828,59 @@ YUV Image Format Notes

Parameters.

- - - - - - - - - - - - - - - - - - - - - - - + +
Enumerator
TJPARAM_STOPONWARNING 

Error handling behavior.

+
Enumerator
TJPARAM_STOPONWARNING 

Error handling behavior.

Value

  • 0 [default] Allow the current compression/decompression/transform operation to complete unless a fatal error is encountered.
  • 1 Immediately discontinue the current compression/decompression/transform operation if a warning (non-fatal error) occurs.
TJPARAM_BOTTOMUP 

Row order in packed-pixel source/destination images.

+
TJPARAM_BOTTOMUP 

Row order in packed-pixel source/destination images.

Value

  • 0 [default] top-down (X11) order
  • 1 bottom-up (Windows, OpenGL) order
TJPARAM_NOREALLOC 

JPEG destination buffer (re)allocation [compression, lossless transformation].

+
TJPARAM_NOREALLOC 

JPEG destination buffer (re)allocation [compression, lossless transformation].

Value

  • 0 [default] Attempt to allocate or reallocate the JPEG destination buffer as needed.
  • 1 Generate an error if the JPEG destination buffer is invalid or too small.
TJPARAM_QUALITY 

Perceptual quality of lossy JPEG images [compression only].

+
TJPARAM_QUALITY 

Perceptual quality of lossy JPEG images [compression only].

Value

  • 1-100 (1 = worst quality but best compression, 100 = best quality but worst compression) [no default; must be explicitly specified]
TJPARAM_SUBSAMP 

Chrominance subsampling level.

+
TJPARAM_SUBSAMP 

Chrominance subsampling level.

The JPEG or YUV image uses (decompression, decoding) or will use (lossy compression, encoding) the specified level of chrominance subsampling.

Value

TJPARAM_JPEGWIDTH 

JPEG width (in pixels) [decompression only, read-only].

+
TJPARAM_JPEGWIDTH 

JPEG width (in pixels) [decompression only, read-only].

TJPARAM_JPEGHEIGHT 

JPEG height (in pixels) [decompression only, read-only].

+
TJPARAM_JPEGHEIGHT 

JPEG height (in pixels) [decompression only, read-only].

TJPARAM_PRECISION 

JPEG data precision (bits per sample) [decompression only, read-only].

+
TJPARAM_PRECISION 

JPEG data precision (bits per sample) [decompression only, read-only].

The JPEG image uses the specified number of bits per sample.

Value

  • 8, 12, or 16
-

12-bit data precision implies TJPARAM_OPTIMIZE unless TJPARAM_ARITHMETIC is set.

+

12-bit data precision implies TJPARAM_OPTIMIZE unless TJPARAM_ARITHMETIC is set.

TJPARAM_COLORSPACE 

JPEG colorspace.

+
TJPARAM_COLORSPACE 

JPEG colorspace.

The JPEG image uses (decompression) or will use (lossy compression) the specified colorspace.

Value

  • One of the JPEG colorspaces [default for lossy compression: automatically selected based on the subsampling level and pixel format]
TJPARAM_FASTUPSAMPLE 

Chrominance upsampling algorithm [lossy decompression only].

+
TJPARAM_FASTUPSAMPLE 

Chrominance upsampling algorithm [lossy decompression only].

Value

    -
  • 0 [default] Use smooth upsampling when decompressing a JPEG image that was compressed using chrominance subsampling. This creates a smooth transition between neighboring chrominance components in order to reduce upsampling artifacts in the decompressed image.
  • +
  • 0 [default] Use smooth upsampling when decompressing a JPEG image that was generated using chrominance subsampling. This creates a smooth transition between neighboring chrominance components in order to reduce upsampling artifacts in the decompressed image.
  • 1 Use the fastest chrominance upsampling algorithm available, which may combine upsampling with color conversion.
TJPARAM_FASTDCT 

DCT/IDCT algorithm [lossy compression and decompression].

+
TJPARAM_FASTDCT 

DCT/IDCT algorithm [lossy compression and decompression].

Value

  • 0 [default] Use the most accurate DCT/IDCT algorithm available.
  • 1 Use the fastest DCT/IDCT algorithm available.
  • @@ -898,48 +889,49 @@ YUV Image Format Notes
  • The "fast" and "accurate" DCT/IDCT algorithms perform similarly on modern x86/x86-64 CPUs that support AVX2 instructions.
  • The "fast" algorithm is generally only about 5-15% faster than the "accurate" algorithm on other types of CPUs.
  • The difference in accuracy between the "fast" and "accurate" algorithms is the most pronounced at JPEG quality levels above 90 and tends to be more pronounced with decompression than with compression.
  • -
  • The "fast" algorithm degrades and is not fully accelerated for JPEG quality levels above 97, so it will be slower than the "accurate" algorithm.
  • +
  • For JPEG quality levels above 97, the "fast" algorithm degrades and is not fully accelerated, so it is slower than the "accurate" algorithm.
TJPARAM_OPTIMIZE 

Optimized baseline entropy coding [lossy compression only].

+
TJPARAM_OPTIMIZE 

Huffman table optimization [lossy compression, lossless transformation].

Value

  • 0 [default] The JPEG image will use the default Huffman tables.
  • -
  • 1 Optimal Huffman tables will be computed for the JPEG image. For lossless transformation, this can also be specified using TJXOPT_OPTIMIZE.
  • +
  • 1 Optimal Huffman tables will be computed for the JPEG image. For lossless transformation, this can also be specified using TJXOPT_OPTIMIZE.
-

Optimized baseline entropy coding will improve compression slightly (generally 5% or less), but it will reduce compression performance considerably.

+

Huffman table optimization improves compression slightly (generally 5% or less), but it reduces compression performance considerably.

TJPARAM_PROGRESSIVE 

Progressive entropy coding.

+
TJPARAM_PROGRESSIVE 

Progressive JPEG.

+

In a progressive JPEG image, the DCT coefficients are split across multiple "scans" of increasing quality. Thus, a low-quality scan containing the lowest-frequency DCT coefficients can be transmitted first and refined with subsequent higher-quality scans containing higher-frequency DCT coefficients. When using Huffman entropy coding, the progressive JPEG format also provides an "end-of-bands (EOB) run" feature that allows large groups of zeroes, potentially spanning multiple MCUs, to be represented using only a few bytes.

Value

    -
  • 0 [default for compression, lossless transformation] The lossy JPEG image uses (decompression) or will use (compression, lossless transformation) baseline entropy coding.
  • -
  • 1 The lossy JPEG image uses (decompression) or will use (compression, lossless transformation) progressive entropy coding. For lossless transformation, this can also be specified using TJXOPT_PROGRESSIVE.
  • +
  • 0 [default for compression, lossless transformation] The lossy JPEG image is (decompression) or will be (compression, lossless transformation) single-scan.
  • +
  • 1 The lossy JPEG image is (decompression) or will be (compression, lossless transformation) progressive. For lossless transformation, this can also be specified using TJXOPT_PROGRESSIVE.
-

Progressive entropy coding will generally improve compression relative to baseline entropy coding, but it will reduce compression and decompression performance considerably. Can be combined with TJPARAM_ARITHMETIC. Implies TJPARAM_OPTIMIZE unless TJPARAM_ARITHMETIC is also set.

+

Progressive JPEG images generally have better compression ratios than single-scan JPEG images (much better if the image has large areas of solid color), but progressive JPEG compression and decompression is considerably slower than single-scan JPEG compression and decompression. Can be combined with TJPARAM_ARITHMETIC. Implies TJPARAM_OPTIMIZE unless TJPARAM_ARITHMETIC is also set.

TJPARAM_SCANLIMIT 

Progressive JPEG scan limit for lossy JPEG images [decompression, lossless transformation].

-

Setting this parameter will cause the decompression and transform functions to return an error if the number of scans in a progressive JPEG image exceeds the specified limit. The primary purpose of this is to allow security-critical applications to guard against an exploit of the progressive JPEG format described in this report.

+
TJPARAM_SCANLIMIT 

Progressive JPEG scan limit for lossy JPEG images [decompression, lossless transformation].

+

Setting this parameter causes the decompression and transform functions to return an error if the number of scans in a progressive JPEG image exceeds the specified limit. The primary purpose of this is to allow security-critical applications to guard against an exploit of the progressive JPEG format described in this report.

Value

  • maximum number of progressive JPEG scans that the decompression and transform functions will process [default: 0 (no limit)]
-
See also
TJPARAM_PROGRESSIVE
+
See also
TJPARAM_PROGRESSIVE
TJPARAM_ARITHMETIC 

Arithmetic entropy coding.

+
TJPARAM_ARITHMETIC 

Arithmetic entropy coding.

Value

  • 0 [default for compression, lossless transformation] The lossy JPEG image uses (decompression) or will use (compression, lossless transformation) Huffman entropy coding.
  • -
  • 1 The lossy JPEG image uses (decompression) or will use (compression, lossless transformation) arithmetic entropy coding. For lossless transformation, this can also be specified using TJXOPT_ARITHMETIC.
  • +
  • 1 The lossy JPEG image uses (decompression) or will use (compression, lossless transformation) arithmetic entropy coding. For lossless transformation, this can also be specified using TJXOPT_ARITHMETIC.
-

Arithmetic entropy coding will generally improve compression relative to Huffman entropy coding, but it will reduce compression and decompression performance considerably. Can be combined with TJPARAM_PROGRESSIVE.

+

Arithmetic entropy coding generally improves compression relative to Huffman entropy coding, but it reduces compression and decompression performance considerably. Can be combined with TJPARAM_PROGRESSIVE.

TJPARAM_LOSSLESS 

Lossless JPEG.

+
TJPARAM_LOSSLESS 

Lossless JPEG.

Value

  • 0 [default for compression] The JPEG image is (decompression) or will be (compression) lossy/DCT-based.
  • 1 The JPEG image is (decompression) or will be (compression) lossless/predictive.
-

In most cases, compressing and decompressing lossless JPEG images is considerably slower than compressing and decompressing lossy JPEG images. Also note that the following features are not available with lossless JPEG images:

    +

    In most cases, lossless JPEG compression and decompression is considerably slower than lossy JPEG compression and decompression, and lossless JPEG images are much larger than lossy JPEG images. Thus, lossless JPEG images are typically used only for applications that require mathematically lossless compression. Also note that the following features are not available with lossless JPEG images:

    • Colorspace conversion (lossless JPEG images always use TJCS_RGB, TJCS_GRAY, or TJCS_CMYK, depending on the pixel format of the source image)
    • -
    • Chrominance subsampling (lossless JPEG images always use TJSAMP_444)
    • +
    • Chrominance subsampling (lossless JPEG images always use TJSAMP_444)
    • JPEG quality selection
    • DCT/IDCT algorithm selection
    • -
    • Progressive entropy coding
    • +
    • Progressive JPEG
    • Arithmetic entropy coding
    • Compression from/decompression to planar YUV images
    • Decompression scaling
    • @@ -947,62 +939,94 @@ YUV Image Format Notes
    See also
    TJPARAM_LOSSLESSPSV, TJPARAM_LOSSLESSPT
TJPARAM_LOSSLESSPSV 

Lossless JPEG predictor selection value (PSV)

+
TJPARAM_LOSSLESSPSV 

Lossless JPEG predictor selection value (PSV)

Value

  • 1-7 [default for compression: 1]
+

Lossless JPEG compression shares no algorithms with lossy JPEG compression. Instead, it uses differential pulse-code modulation (DPCM), an algorithm whereby each sample is encoded as the difference between the sample's value and a "predictor", which is based on the values of neighboring samples. If Ra is the sample immediately to the left of the current sample, Rb is the sample immediately above the current sample, and Rc is the sample diagonally to the left and above the current sample, then the relationship between the predictor selection value and the predictor is as follows:

+ + + + + + + + + + + + + + + + + +
PSV Predictor
1 Ra
2 Rb
3 Rc
4 Ra + Rb – Rc
5 Ra + (Rb – Rc) / 2
6 Rb + (Ra – Rc) / 2
7 (Ra + Rb) / 2
+

Predictors 1-3 are 1-dimensional predictors, whereas Predictors 4-7 are 2-dimensional predictors. The best predictor for a particular image depends on the image.

See also
TJPARAM_LOSSLESS
TJPARAM_LOSSLESSPT 

Lossless JPEG point transform (Pt)

+
TJPARAM_LOSSLESSPT 

Lossless JPEG point transform (Pt)

Value

  • 0 through precision - 1, where precision is the JPEG data precision in bits [default for compression: 0]

A point transform value of 0 is necessary in order to generate a fully lossless JPEG image. (A non-zero point transform value right-shifts the input samples by the specified number of bits, which is effectively a form of lossy color quantization.)

See also
TJPARAM_LOSSLESS, TJPARAM_PRECISION
TJPARAM_RESTARTBLOCKS 

JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) [compression only].

+
TJPARAM_RESTARTBLOCKS 

JPEG restart marker interval in MCUs [lossy compression only].

The nature of entropy coding is such that a corrupt JPEG image cannot be decompressed beyond the point of corruption unless it contains restart markers. A restart marker stops and restarts the entropy coding algorithm so that, if a JPEG image is corrupted, decompression can resume at the next marker. Thus, adding more restart markers improves the fault tolerance of the JPEG image, but adding too many restart markers can adversely affect the compression ratio and performance.

+

In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set of interleaved "data units" (8x8 DCT blocks if the image is lossy or samples if the image is lossless) necessary to represent at least one data unit per component. (For example, an MCU in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of two luminance blocks followed by one block for each chrominance component.) In single-component or non-interleaved JPEG images, an MCU is the same as a data unit.

Value

    -
  • the number of MCU blocks or samples between each restart marker [default: 0 (no restart markers)]
  • +
  • the number of MCUs between each restart marker [default: 0 (no restart markers)]
-

Setting this parameter to a non-zero value sets TJPARAM_RESTARTROWS to 0.

+

Setting this parameter to a non-zero value sets TJPARAM_RESTARTROWS to 0.

TJPARAM_RESTARTROWS 

JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) [compression only].

-

See TJPARAM_RESTARTBLOCKS for a description of restart markers.

+
TJPARAM_RESTARTROWS 

JPEG restart marker interval in MCU rows [compression only].

+

See TJPARAM_RESTARTBLOCKS for a description of restart markers and MCUs. An MCU row is a row of MCUs spanning the entire width of the image.

Value

    -
  • the number of MCU rows or sample rows between each restart marker [default: 0 (no restart markers)]
  • +
  • the number of MCU rows between each restart marker [default: 0 (no restart markers)]
-

Setting this parameter to a non-zero value sets TJPARAM_RESTARTBLOCKS to 0.

+

Setting this parameter to a non-zero value sets TJPARAM_RESTARTBLOCKS to 0.

TJPARAM_XDENSITY 

JPEG horizontal pixel density.

+
TJPARAM_XDENSITY 

JPEG horizontal pixel density.

Value

  • The JPEG image has (decompression) or will have (compression) the specified horizontal pixel density [default for compression: 1].
-

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value of #TJPARAM_DENSITYUNIT is 2.

-
See also
TJPARAM_DENSITYUNIT
+

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value of TJPARAM_DENSITYUNITS is 2.

+
See also
TJPARAM_DENSITYUNITS
TJPARAM_YDENSITY 

JPEG vertical pixel density.

+
TJPARAM_YDENSITY 

JPEG vertical pixel density.

Value

  • The JPEG image has (decompression) or will have (compression) the specified vertical pixel density [default for compression: 1].
-

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value of #TJPARAM_DENSITYUNIT is 2.

-
See also
TJPARAM_DENSITYUNIT
+

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value of TJPARAM_DENSITYUNITS is 2.

+
See also
TJPARAM_DENSITYUNITS
TJPARAM_DENSITYUNITS 

JPEG pixel density units.

+
TJPARAM_DENSITYUNITS 

JPEG pixel density units.

Value

  • 0 [default for compression] The pixel density of the JPEG image is expressed (decompression) or will be expressed (compression) in unknown units.
  • 1 The pixel density of the JPEG image is expressed (decompression) or will be expressed (compression) in units of pixels/inch.
  • 2 The pixel density of the JPEG image is expressed (decompression) or will be expressed (compression) in units of pixels/cm.
-

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value is 2.

+

This value is stored in or read from the JPEG header. It does not affect the contents of the JPEG image. Note that this parameter is set by tj3LoadImage8() when loading a Windows BMP file that contains pixel density information, and the value of this parameter is stored to a Windows BMP file by tj3SaveImage8() if the value is 2.

See also
TJPARAM_XDENSITY, TJPARAM_YDENSITY
TJPARAM_MAXMEMORY 

Memory limit for intermediate buffers.

+

Value

    +
  • the maximum amount of memory (in megabytes) that will be allocated for intermediate buffers, which are used with progressive JPEG compression and decompression, Huffman table optimization, lossless JPEG compression, and lossless transformation [default: 0 (no limit)]
  • +
+
TJPARAM_MAXPIXELS 

Image size limit [decompression, lossless transformation, packed-pixel image loading].

+

Setting this parameter causes the decompression, transform, and image loading functions to return an error if the number of pixels in the source image exceeds the specified limit. This allows security-critical applications to guard against excessive memory consumption.

+

Value

    +
  • maximum number of pixels that the decompression, transform, and image loading functions will process [default: 0 (no limit)]
  • +
+
- -

◆ TJPF

+ +

◆ TJPF

@@ -1015,51 +1039,51 @@ YUV Image Format Notes

Pixel formats.

- - - - - - - - - - - - -
Enumerator
TJPF_RGB 

RGB pixel format.

+
Enumerator
TJPF_RGB 

RGB pixel format.

The red, green, and blue components in the image are stored in 3-sample pixels in the order R, G, B from lowest to highest memory address within each pixel.

TJPF_BGR 

BGR pixel format.

+
TJPF_BGR 

BGR pixel format.

The red, green, and blue components in the image are stored in 3-sample pixels in the order B, G, R from lowest to highest memory address within each pixel.

TJPF_RGBX 

RGBX pixel format.

-

The red, green, and blue components in the image are stored in 4-sample pixels in the order R, G, B from lowest to highest memory address within each pixel. The X component is ignored when compressing and undefined when decompressing.

+
TJPF_RGBX 

RGBX pixel format.

+

The red, green, and blue components in the image are stored in 4-sample pixels in the order R, G, B from lowest to highest memory address within each pixel. The X component is ignored when compressing/encoding and undefined when decompressing/decoding.

TJPF_BGRX 

BGRX pixel format.

-

The red, green, and blue components in the image are stored in 4-sample pixels in the order B, G, R from lowest to highest memory address within each pixel. The X component is ignored when compressing and undefined when decompressing.

+
TJPF_BGRX 

BGRX pixel format.

+

The red, green, and blue components in the image are stored in 4-sample pixels in the order B, G, R from lowest to highest memory address within each pixel. The X component is ignored when compressing/encoding and undefined when decompressing/decoding.

TJPF_XBGR 

XBGR pixel format.

-

The red, green, and blue components in the image are stored in 4-sample pixels in the order R, G, B from highest to lowest memory address within each pixel. The X component is ignored when compressing and undefined when decompressing.

+
TJPF_XBGR 

XBGR pixel format.

+

The red, green, and blue components in the image are stored in 4-sample pixels in the order R, G, B from highest to lowest memory address within each pixel. The X component is ignored when compressing/encoding and undefined when decompressing/decoding.

TJPF_XRGB 

XRGB pixel format.

-

The red, green, and blue components in the image are stored in 4-sample pixels in the order B, G, R from highest to lowest memory address within each pixel. The X component is ignored when compressing and undefined when decompressing.

+
TJPF_XRGB 

XRGB pixel format.

+

The red, green, and blue components in the image are stored in 4-sample pixels in the order B, G, R from highest to lowest memory address within each pixel. The X component is ignored when compressing/encoding and undefined when decompressing/decoding.

TJPF_GRAY 

Grayscale pixel format.

+
TJPF_GRAY 

Grayscale pixel format.

Each 1-sample pixel represents a luminance (brightness) level from 0 to the maximum sample value (255 for 8-bit samples, 4095 for 12-bit samples, and 65535 for 16-bit samples.)

TJPF_RGBA 

RGBA pixel format.

-

This is the same as TJPF_RGBX, except that when decompressing, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

+
TJPF_RGBA 

RGBA pixel format.

+

This is the same as TJPF_RGBX, except that when decompressing/decoding, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

TJPF_BGRA 

BGRA pixel format.

-

This is the same as TJPF_BGRX, except that when decompressing, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

+
TJPF_BGRA 

BGRA pixel format.

+

This is the same as TJPF_BGRX, except that when decompressing/decoding, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

TJPF_ABGR 

ABGR pixel format.

-

This is the same as TJPF_XBGR, except that when decompressing, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

+
TJPF_ABGR 

ABGR pixel format.

+

This is the same as TJPF_XBGR, except that when decompressing/decoding, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

TJPF_ARGB 

ARGB pixel format.

-

This is the same as TJPF_XRGB, except that when decompressing, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

+
TJPF_ARGB 

ARGB pixel format.

+

This is the same as TJPF_XRGB, except that when decompressing/decoding, the X component is guaranteed to be equal to the maximum sample value, which can be interpreted as an opaque alpha channel.

TJPF_CMYK 

CMYK pixel format.

+
TJPF_CMYK 

CMYK pixel format.

Unlike RGB, which is an additive color model used primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive color model used primarily for printing. In the CMYK color model, the value of each color component typically corresponds to an amount of cyan, magenta, yellow, or black ink that is applied to a white background. In order to convert between CMYK and RGB, it is necessary to use a color management system (CMS.) A CMS will attempt to map colors within the printer's gamut to perceptually similar colors in the display's gamut and vice versa, but the mapping is typically not 1:1 or reversible, nor can it be defined with a simple formula. Thus, such a conversion is out of scope for a codec library. However, the TurboJPEG API allows for compressing packed-pixel CMYK images into YCCK JPEG images (see TJCS_YCCK) and decompressing YCCK JPEG images into packed-pixel CMYK images.

TJPF_UNKNOWN 

Unknown pixel format.

-

Currently this is only used by tj3LoadImage8(), tj3LoadImage12(), and tj3LoadImage16().

+
TJPF_UNKNOWN 

Unknown pixel format.

+

Currently this is only used by tj3LoadImage8(), tj3LoadImage12(), and tj3LoadImage16().

- -

◆ TJSAMP

+ +

◆ TJSAMP

@@ -1071,36 +1095,36 @@ YUV Image Format Notes

Chrominance subsampling options.

-

When pixels are converted from RGB to YCbCr (see TJCS_YCbCr) or from CMYK to YCCK (see TJCS_YCCK) as part of the JPEG compression process, some of the Cb and Cr (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible loss of image clarity. (The human eye is more sensitive to small changes in brightness than to small changes in color.) This is called "chrominance subsampling".

+

When pixels are converted from RGB to YCbCr (see TJCS_YCbCr) or from CMYK to YCCK (see TJCS_YCCK) as part of the JPEG compression process, some of the Cb and Cr (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible loss of image quality. (The human eye is more sensitive to small changes in brightness than to small changes in color.) This is called "chrominance subsampling".

- - - - - - - - @@ -1108,8 +1132,8 @@ YUV Image Format Notes - -

◆ TJXOP

+ +

◆ TJXOP

@@ -1122,40 +1146,40 @@ YUV Image Format Notes

Transform operations for tj3Transform()

Enumerator
TJSAMP_444 

4:4:4 chrominance subsampling (no chrominance subsampling).

+
Enumerator
TJSAMP_444 

4:4:4 chrominance subsampling (no chrominance subsampling)

The JPEG or YUV image will contain one chrominance component for every pixel in the source image.

TJSAMP_422 

4:2:2 chrominance subsampling.

+
TJSAMP_422 

4:2:2 chrominance subsampling

The JPEG or YUV image will contain one chrominance component for every 2x1 block of pixels in the source image.

TJSAMP_420 

4:2:0 chrominance subsampling.

+
TJSAMP_420 

4:2:0 chrominance subsampling

The JPEG or YUV image will contain one chrominance component for every 2x2 block of pixels in the source image.

TJSAMP_GRAY 

Grayscale.

+
TJSAMP_GRAY 

Grayscale.

The JPEG or YUV image will contain no chrominance components.

TJSAMP_440 

4:4:0 chrominance subsampling.

+
TJSAMP_440 

4:4:0 chrominance subsampling

The JPEG or YUV image will contain one chrominance component for every 1x2 block of pixels in the source image.

Note
4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
TJSAMP_411 

4:1:1 chrominance subsampling.

-

The JPEG or YUV image will contain one chrominance component for every 4x1 block of pixels in the source image. JPEG images compressed with 4:1:1 subsampling will be almost exactly the same size as those compressed with 4:2:0 subsampling, and in the aggregate, both subsampling methods produce approximately the same perceptual quality. However, 4:1:1 is better able to reproduce sharp horizontal features.

+
TJSAMP_411 

4:1:1 chrominance subsampling

+

The JPEG or YUV image will contain one chrominance component for every 4x1 block of pixels in the source image. All else being equal, a JPEG image with 4:1:1 subsampling is almost exactly the same size as a JPEG image with 4:2:0 subsampling, and in the aggregate, both subsampling methods produce approximately the same perceptual quality. However, 4:1:1 is better able to reproduce sharp horizontal features.

Note
4:1:1 subsampling is not fully accelerated in libjpeg-turbo.
TJSAMP_441 

4:4:1 chrominance subsampling.

-

The JPEG or YUV image will contain one chrominance component for every 1x4 block of pixels in the source image. JPEG images compressed with 4:4:1 subsampling will be almost exactly the same size as those compressed with 4:2:0 subsampling, and in the aggregate, both subsampling methods produce approximately the same perceptual quality. However, 4:4:1 is better able to reproduce sharp vertical features.

+
TJSAMP_441 

4:4:1 chrominance subsampling

+

The JPEG or YUV image will contain one chrominance component for every 1x4 block of pixels in the source image. All else being equal, a JPEG image with 4:4:1 subsampling is almost exactly the same size as a JPEG image with 4:2:0 subsampling, and in the aggregate, both subsampling methods produce approximately the same perceptual quality. However, 4:4:1 is better able to reproduce sharp vertical features.

Note
4:4:1 subsampling is not fully accelerated in libjpeg-turbo.
TJSAMP_UNKNOWN 

Unknown subsampling.

+
TJSAMP_UNKNOWN 

Unknown subsampling.

The JPEG image uses an unusual type of chrominance subsampling. Such images can be decompressed into packed-pixel images, but they cannot be

  • decompressed into planar YUV images,
  • -
  • losslessly transformed if TJXOPT_CROP is specified, or
  • +
  • losslessly transformed if TJXOPT_CROP is specified and TJXOPT_GRAY is not specified, or
  • partially decompressed using a cropping region.
- - - - - - - -
Enumerator
TJXOP_NONE 

Do not transform the position of the image pixels.

+
Enumerator
TJXOP_NONE 

Do not transform the position of the image pixels.

TJXOP_HFLIP 

Flip (mirror) image horizontally.

-

This transform is imperfect if there are any partial MCU blocks on the right edge (see TJXOPT_PERFECT.)

+
TJXOP_HFLIP 

Flip (mirror) image horizontally.

+

This transform is imperfect if there are any partial iMCUs on the right edge (see TJXOPT_PERFECT.)

TJXOP_VFLIP 

Flip (mirror) image vertically.

-

This transform is imperfect if there are any partial MCU blocks on the bottom edge (see TJXOPT_PERFECT.)

+
TJXOP_VFLIP 

Flip (mirror) image vertically.

+

This transform is imperfect if there are any partial iMCUs on the bottom edge (see TJXOPT_PERFECT.)

TJXOP_TRANSPOSE 

Transpose image (flip/mirror along upper left to lower right axis.) This transform is always perfect.

+
TJXOP_TRANSPOSE 

Transpose image (flip/mirror along upper left to lower right axis.) This transform is always perfect.

TJXOP_TRANSVERSE 

Transverse transpose image (flip/mirror along upper right to lower left axis.) This transform is imperfect if there are any partial MCU blocks in the image (see TJXOPT_PERFECT.)

+
TJXOP_TRANSVERSE 

Transverse transpose image (flip/mirror along upper right to lower left axis.) This transform is imperfect if there are any partial iMCUs in the image (see TJXOPT_PERFECT.)

TJXOP_ROT90 

Rotate image clockwise by 90 degrees.

-

This transform is imperfect if there are any partial MCU blocks on the bottom edge (see TJXOPT_PERFECT.)

+
TJXOP_ROT90 

Rotate image clockwise by 90 degrees.

+

This transform is imperfect if there are any partial iMCUs on the bottom edge (see TJXOPT_PERFECT.)

TJXOP_ROT180 

Rotate image 180 degrees.

-

This transform is imperfect if there are any partial MCU blocks in the image (see TJXOPT_PERFECT.)

+
TJXOP_ROT180 

Rotate image 180 degrees.

+

This transform is imperfect if there are any partial iMCUs in the image (see TJXOPT_PERFECT.)

TJXOP_ROT270 

Rotate image counter-clockwise by 90 degrees.

-

This transform is imperfect if there are any partial MCU blocks on the right edge (see TJXOPT_PERFECT.)

+
TJXOP_ROT270 

Rotate image counter-clockwise by 90 degrees.

+

This transform is imperfect if there are any partial iMCUs on the right edge (see TJXOPT_PERFECT.)

Function Documentation

- -

◆ tj3Alloc()

+ +

◆ tj3Alloc()

- + @@ -1177,8 +1201,8 @@ YUV Image Format Notes - -

◆ tj3Compress12()

+ +

◆ tj3Compress12()

@@ -1249,7 +1273,7 @@ YUV Image Format Notes
DLLEXPORT void* tj3Alloc DLLEXPORT void * tj3Alloc ( size_t  bytes)
heightheight (in pixels) of the source image
pixelFormatpixel format of the source image (see Pixel formats.)
jpegBufaddress 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:
    -
  1. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize(). This should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.)
@@ -1258,12 +1282,12 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Compress16()

+ +

◆ tj3Compress16()

@@ -1334,7 +1358,7 @@ If you choose option 1, then *jpegSize should be set to the size of heightheight (in pixels) of the source image pixelFormatpixel format of the source image (see Pixel formats.) jpegBufaddress 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:
    -
  1. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize(). This should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.)
@@ -1343,12 +1367,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Compress8()

+ +

◆ tj3Compress8()

@@ -1419,7 +1443,7 @@ If you choose option 1, then *jpegSize should be set to the size of heightheight (in pixels) of the source image pixelFormatpixel format of the source image (see Pixel formats.) jpegBufaddress 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:
    -
  1. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize(). This should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.)
@@ -1428,12 +1452,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3CompressFromYUV8()

+ +

◆ tj3CompressFromYUV8()

@@ -1493,11 +1517,11 @@ If you choose option 1, then *jpegSize should be set to the size of - + - +
handlehandle to a TurboJPEG instance that has been initialized for compression
srcBufpointer to a buffer containing a unified planar YUV source image to be compressed. The size of this buffer should match the value returned by tj3YUVBufSize() for the given image width, height, row alignment, and level of chrominance subsampling (see TJPARAM_SUBSAMP.) The Y, U (Cb), and V (Cr) image planes should be stored sequentially in the buffer. (Refer to YUV Image Format Notes.)
widthwidth (in pixels) of the source image. If the width is not an even multiple of the MCU block width (see tjMCUWidth), then an intermediate buffer copy will be performed.
widthwidth (in pixels) of the source image. If the width is not an even multiple of the iMCU width (see tjMCUWidth), then an intermediate buffer copy will be performed.
alignrow alignment (in bytes) of the source image (must be a power of 2.) Setting this parameter to n indicates that each row in each plane of the source image is padded to the nearest multiple of n bytes (1 = unpadded.)
heightheight (in pixels) of the source image. If the height is not an even multiple of the MCU block height (see tjMCUHeight), then an intermediate buffer copy will be performed.
heightheight (in pixels) of the source image. If the height is not an even multiple of the iMCU height (see tjMCUHeight), then an intermediate buffer copy will be performed.
jpegBufaddress 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:
    -
  1. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize(). This should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.)
@@ -1506,12 +1530,12 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3CompressFromYUVPlanes8()

+ +

◆ tj3CompressFromYUVPlanes8()

@@ -1571,11 +1595,11 @@ If you choose option 1, then *jpegSize should be set to the size of - + - +
handlehandle to a TurboJPEG instance that has been initialized for compression
srcPlanesan array of pointers to Y, U (Cb), and V (Cr) image planes (or just a Y plane, if compressing a grayscale image) that contain a YUV source image to be compressed. These planes can be contiguous or non-contiguous in memory. The size of each plane should match the value returned by tj3YUVPlaneSize() for the given image width, height, strides, and level of chrominance subsampling (see TJPARAM_SUBSAMP.) Refer to YUV Image Format Notes for more details.
widthwidth (in pixels) of the source image. If the width is not an even multiple of the MCU block width (see tjMCUWidth), then an intermediate buffer copy will be performed.
widthwidth (in pixels) of the source image. If the width is not an even multiple of the iMCU width (see tjMCUWidth), then an intermediate buffer copy will be performed.
stridesan array of integers, each specifying the number of bytes per row in the corresponding plane of the YUV source image. Setting the stride for any plane to 0 is the same as setting it to the plane width (see YUV Image Format Notes.) If strides is NULL, then the strides for all planes will be set to their respective plane widths. You can adjust the strides in order to specify an arbitrary amount of row padding in each plane or to create a JPEG image from a subregion of a larger planar YUV image.
heightheight (in pixels) of the source image. If the height is not an even multiple of the MCU block height (see tjMCUHeight), then an intermediate buffer copy will be performed.
heightheight (in pixels) of the source image. If the height is not an even multiple of the iMCU height (see tjMCUHeight), then an intermediate buffer copy will be performed.
jpegBufaddress 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:
    -
  1. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set *jpegBuf to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize(). This should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.)
@@ -1584,12 +1608,12 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3DecodeYUV8()

+ +

◆ tj3DecodeYUV8()

@@ -1665,12 +1689,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3DecodeYUVPlanes8()

+ +

◆ tj3DecodeYUVPlanes8()

@@ -1746,12 +1770,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Decompress12()

+ +

◆ tj3Decompress12()

@@ -1813,12 +1837,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Decompress16()

+ +

◆ tj3Decompress16()

@@ -1880,12 +1904,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Decompress8()

+ +

◆ tj3Decompress8()

@@ -1947,12 +1971,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3DecompressHeader()

+ +

◆ tj3DecompressHeader()

@@ -1993,12 +2017,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3DecompressToYUV8()

+ +

◆ tj3DecompressToYUV8()

@@ -2053,12 +2077,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3DecompressToYUVPlanes8()

+ +

◆ tj3DecompressToYUVPlanes8()

@@ -2113,12 +2137,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Destroy()

+ +

◆ tj3Destroy()

@@ -2143,8 +2167,8 @@ If you choose option 1, then *jpegSize should be set to the size of
- -

◆ tj3EncodeYUV8()

+ +

◆ tj3EncodeYUV8()

@@ -2220,12 +2244,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3EncodeYUVPlanes8()

+ +

◆ tj3EncodeYUVPlanes8()

@@ -2301,12 +2325,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3Free()

+ +

◆ tj3Free()

@@ -2322,19 +2346,19 @@ If you choose option 1, then *jpegSize should be set to the size of

Free a byte buffer previously allocated by TurboJPEG.

-

You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by the compression and transform functions or that were manually allocated using tj3Alloc().

+

You should always use this function to free JPEG destination buffer(s) that were automatically (re)allocated by the compression and transform functions or that were manually allocated using tj3Alloc().

Parameters
bufferaddress of the buffer to free. If the address is NULL, then this function has no effect.
-
See also
tj3Alloc()
+
See also
tj3Alloc()
- -

◆ tj3Get()

+ +

◆ tj3Get()

@@ -2371,8 +2395,8 @@ If you choose option 1, then *jpegSize should be set to the size of
- -

◆ tj3GetErrorCode()

+ +

◆ tj3GetErrorCode()

@@ -2399,14 +2423,14 @@ If you choose option 1, then *jpegSize should be set to the size of
- -

◆ tj3GetErrorStr()

+ +

◆ tj3GetErrorStr()

- + @@ -2426,14 +2450,14 @@ If you choose option 1, then *jpegSize should be set to the size of - -

◆ tj3GetScalingFactors()

+ +

◆ tj3GetScalingFactors()

DLLEXPORT char* tj3GetErrorStr DLLEXPORT char * tj3GetErrorStr ( tjhandle  handle)
- + @@ -2449,12 +2473,12 @@ If you choose option 1, then *jpegSize should be set to the size of
DLLEXPORT tjscalingfactor* tj3GetScalingFactors DLLEXPORT tjscalingfactor * tj3GetScalingFactors ( int *  numScalingFactors)
-
Returns
a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see tj3GetErrorStr().)
+
Returns
a pointer to a list of fractional scaling factors, or NULL if an error is encountered (see tj3GetErrorStr().)
- -

◆ tj3Init()

+ +

◆ tj3Init()

@@ -2476,12 +2500,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tj3GetErrorStr().)
+
Returns
a handle to the newly-created instance, or NULL if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3JPEGBufSize()

+ +

◆ tj3JPEGBufSize()

@@ -2518,7 +2542,7 @@ If you choose option 1, then *jpegSize should be set to the size of - +
widthwidth (in pixels) of the image
heightheight (in pixels) of the image
jpegSubsampthe level of chrominance subsampling to be used when generating the JPEG image (see Chrominance subsampling options.) TJSAMP_UNKNOWN is treated like TJSAMP_444, since a buffer large enough to hold a JPEG image with no subsampling should also be large enough to hold a JPEG image with an arbitrary level of subsampling. Note that lossless JPEG images always use TJSAMP_444.
jpegSubsampthe level of chrominance subsampling to be used when generating the JPEG image (see Chrominance subsampling options.) TJSAMP_UNKNOWN is treated like TJSAMP_444, since a buffer large enough to hold a JPEG image with no subsampling should also be large enough to hold a JPEG image with an arbitrary level of subsampling. Note that lossless JPEG images always use TJSAMP_444.
@@ -2526,14 +2550,14 @@ If you choose option 1, then *jpegSize should be set to the size of
- -

◆ tj3LoadImage12()

+ +

◆ tj3LoadImage12()

- + @@ -2584,7 +2608,7 @@ If you choose option 1, then *jpegSize should be set to the size of -
DLLEXPORT short* tj3LoadImage12 DLLEXPORT short * tj3LoadImage12 ( tjhandle  handle,
widthpointer to an integer variable that will receive the width (in pixels) of the packed-pixel image
alignrow 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.)
heightpointer to an integer variable that will receive the height (in pixels) of the packed-pixel image
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function will vary depending on the value of *pixelFormat passed to the function:
    +
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function varies depending on the value of *pixelFormat passed to the function:
  • TJPF_UNKNOWN : The packed-pixel buffer returned by this function will use the most optimal pixel format for the file type, and *pixelFormat will contain the ID of that pixel format upon successful return from this function.
  • TJPF_GRAY : Only PGM files and 8-bit-per-pixel BMP files with a grayscale colormap can be loaded.
  • TJPF_CMYK : The RGB or grayscale pixels stored in the file will be converted using a quick & dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)
  • @@ -2594,18 +2618,18 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
+
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
- -

◆ tj3LoadImage16()

+ +

◆ tj3LoadImage16()

- + @@ -2656,7 +2680,7 @@ If you choose option 1, then *jpegSize should be set to the size of -
DLLEXPORT unsigned short* tj3LoadImage16 DLLEXPORT unsigned short * tj3LoadImage16 ( tjhandle  handle,
widthpointer to an integer variable that will receive the width (in pixels) of the packed-pixel image
alignrow 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.)
heightpointer to an integer variable that will receive the height (in pixels) of the packed-pixel image
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function will vary depending on the value of *pixelFormat passed to the function:
    +
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function varies depending on the value of *pixelFormat passed to the function:
  • TJPF_UNKNOWN : The packed-pixel buffer returned by this function will use the most optimal pixel format for the file type, and *pixelFormat will contain the ID of that pixel format upon successful return from this function.
  • TJPF_GRAY : Only PGM files and 8-bit-per-pixel BMP files with a grayscale colormap can be loaded.
  • TJPF_CMYK : The RGB or grayscale pixels stored in the file will be converted using a quick & dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)
  • @@ -2666,18 +2690,18 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
+
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
- -

◆ tj3LoadImage8()

+ +

◆ tj3LoadImage8()

- + @@ -2728,7 +2752,7 @@ If you choose option 1, then *jpegSize should be set to the size of -
DLLEXPORT unsigned char* tj3LoadImage8 DLLEXPORT unsigned char * tj3LoadImage8 ( tjhandle  handle,
widthpointer to an integer variable that will receive the width (in pixels) of the packed-pixel image
alignrow 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.)
heightpointer to an integer variable that will receive the height (in pixels) of the packed-pixel image
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function will vary depending on the value of *pixelFormat passed to the function:
    +
pixelFormatpointer to an integer variable that specifies or will receive the pixel format of the packed-pixel buffer. The behavior of this function varies depending on the value of *pixelFormat passed to the function:
  • TJPF_UNKNOWN : The packed-pixel buffer returned by this function will use the most optimal pixel format for the file type, and *pixelFormat will contain the ID of that pixel format upon successful return from this function.
  • TJPF_GRAY : Only PGM files and 8-bit-per-pixel BMP files with a grayscale colormap can be loaded.
  • TJPF_CMYK : The RGB or grayscale pixels stored in the file will be converted using a quick & dirty algorithm that is suitable only for testing purposes. (Proper conversion between CMYK and other formats requires a color management system.)
  • @@ -2738,12 +2762,12 @@ If you choose option 1, then *jpegSize should be set to the size of
-
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
+
Returns
a pointer to a newly-allocated buffer containing the packed-pixel image, converted to the chosen pixel format and with the chosen row alignment, or NULL if an error occurred (see tj3GetErrorStr().) This buffer should be freed using tj3Free().
- -

◆ tj3SaveImage12()

+ +

◆ tj3SaveImage12()

@@ -2811,12 +2835,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3SaveImage16()

+ +

◆ tj3SaveImage16()

@@ -2884,12 +2908,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3SaveImage8()

+ +

◆ tj3SaveImage8()

@@ -2957,12 +2981,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3Set()

+ +

◆ tj3Set()

@@ -3002,12 +3026,12 @@ If you choose option 1, then *jpegSize should be set to the size of -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3SetCroppingRegion()

+ +

◆ tj3SetCroppingRegion()

@@ -3036,16 +3060,16 @@ If you choose option 1, then *jpegSize should be set to the size of
Parameters
- +
handlehandle to a TurboJPEG instance that has been initialized for decompression
croppingRegiontjregion structure that specifies a subregion of the JPEG image to decompress, or TJUNCROPPED for no cropping. The left boundary of the cropping region must be evenly divisible by the scaled MCU block width (TJSCALED(tjMCUWidth[subsamp], scalingFactor), where subsamp is the level of chrominance subsampling in the JPEG image (see TJPARAM_SUBSAMP) and scalingFactor is the decompression scaling factor (see tj3SetScalingFactor().) The cropping region should be specified relative to the scaled image dimensions. Unless croppingRegion is TJUNCROPPED, the JPEG header must be read (see tj3DecompressHeader()) prior to calling this function.
croppingRegiontjregion structure that specifies a subregion of the JPEG image to decompress, or TJUNCROPPED for no cropping. The left boundary of the cropping region must be evenly divisible by the scaled iMCU width– TJSCALED(tjMCUWidth[subsamp], scalingFactor), where subsamp is the level of chrominance subsampling in the JPEG image (see TJPARAM_SUBSAMP) and scalingFactor is the decompression scaling factor (see tj3SetScalingFactor().) The cropping region should be specified relative to the scaled image dimensions. Unless croppingRegion is TJUNCROPPED, the JPEG header must be read (see tj3DecompressHeader()) prior to calling this function.
-
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3SetScalingFactor()

+ +

◆ tj3SetScalingFactor()

@@ -3074,16 +3098,16 @@ If you choose option 1, then *jpegSize should be set to the size of
Parameters
- +
handlehandle to a TurboJPEG instance that has been initialized for decompression
scalingFactortjscalingfactor structure that specifies a fractional scaling factor that the decompressor supports (see tj3GetScalingFactors()), or TJUNSCALED for no scaling. Decompression scaling is a function of the IDCT algorithm, so scaling factors are generally limited to multiples of 1/8. If the entire JPEG image will be decompressed, then the width and height of the scaled destination image can be determined by calling TJSCALED() with the JPEG width and height (see TJPARAM_JPEGWIDTH and TJPARAM_JPEGHEIGHT) and the specified scaling factor. When decompressing into a planar YUV image, an intermediate buffer copy will be performed if the width or height of the scaled destination image is not an even multiple of the MCU block size (see tjMCUWidth and tjMCUHeight.) Note that decompression scaling is not available (and the specified scaling factor is ignored) when decompressing lossless JPEG images (see TJPARAM_LOSSLESS), since the IDCT algorithm is not used with those images. Note also that TJPARAM_FASTDCT is ignored when decompression scaling is enabled.
scalingFactortjscalingfactor structure that specifies a fractional scaling factor that the decompressor supports (see tj3GetScalingFactors()), or TJUNSCALED for no scaling. Decompression scaling is a function of the IDCT algorithm, so scaling factors are generally limited to multiples of 1/8. If the entire JPEG image will be decompressed, then the width and height of the scaled destination image can be determined by calling TJSCALED() with the JPEG width and height (see TJPARAM_JPEGWIDTH and TJPARAM_JPEGHEIGHT) and the specified scaling factor. When decompressing into a planar YUV image, an intermediate buffer copy will be performed if the width or height of the scaled destination image is not an even multiple of the iMCU size (see tjMCUWidth and tjMCUHeight.) Note that decompression scaling is not available (and the specified scaling factor is ignored) when decompressing lossless JPEG images (see TJPARAM_LOSSLESS), since the IDCT algorithm is not used with those images. Note also that TJPARAM_FASTDCT is ignored when decompression scaling is enabled.
-
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr().)
- -

◆ tj3Transform()

+ +

◆ tj3Transform()

@@ -3147,9 +3171,9 @@ If you choose option 1, then *jpegSize should be set to the size of jpegSizesize of the JPEG source image (in bytes) nthe number of transformed JPEG images to generate dstBufspointer to an array of n byte buffers. dstBufs[i] will receive a JPEG image that has been transformed using the parameters in transforms[i]. TurboJPEG has the ability to reallocate the JPEG destination buffer to accommodate the size of the transformed JPEG image. Thus, you can choose to:
    -
  1. pre-allocate the JPEG destination buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  2. +
  3. pre-allocate the JPEG destination buffer with an arbitrary size using tj3Alloc() and let TurboJPEG grow the buffer as needed,
  4. set dstBufs[i] to NULL to tell TurboJPEG to allocate the buffer for you, or
  5. -
  6. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize() with the transformed or cropped width and height and the level of subsampling used in the source image. Under normal circumstances, this should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.) Note, however, that there are some rare cases (such as transforming images with a large amount of embedded EXIF or ICC profile data) in which the transformed JPEG image will be larger than the worst-case size, and TJPARAM_NOREALLOC cannot be used in those cases.
  7. +
  8. pre-allocate the buffer to a "worst case" size determined by calling tj3JPEGBufSize() with the transformed or cropped width and height and the level of subsampling used in the destination image (taking into account grayscale conversion and transposition of the width and height.) Under normal circumstances, this should ensure that the buffer never has to be re-allocated. (Setting TJPARAM_NOREALLOC guarantees that it won't be.) Note, however, that there are some rare cases (such as transforming images with a large amount of embedded Exif or ICC profile data) in which the transformed JPEG image will be larger than the worst-case size, and TJPARAM_NOREALLOC cannot be used in those cases unless the embedded data is discarded using TJXOPT_COPYNONE.
If you choose option 1, then dstSizes[i] should be set to the size of your pre-allocated buffer. In any case, unless you have set TJPARAM_NOREALLOC, you should always check dstBufs[i] upon return from this function, as it may have changed. dstSizespointer to an array of n size_t variables that will receive the actual sizes (in bytes) of each transformed JPEG image. If dstBufs[i] points to a pre-allocated buffer, then dstSizes[i] should be set to the size of the buffer. Upon return, dstSizes[i] will contain the size of the transformed JPEG image (in bytes.) @@ -3157,12 +3181,12 @@ If you choose option 1, then dstSizes[i] should be set to the size -
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
+
Returns
0 if successful, or -1 if an error occurred (see tj3GetErrorStr() and tj3GetErrorCode().)
- -

◆ tj3YUVBufSize()

+ +

◆ tj3YUVBufSize()

@@ -3213,8 +3237,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tj3YUVPlaneHeight()

+ +

◆ tj3YUVPlaneHeight()

@@ -3259,8 +3283,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tj3YUVPlaneSize()

+ +

◆ tj3YUVPlaneSize()

@@ -3307,9 +3331,9 @@ If you choose option 1, then dstSizes[i] should be set to the size
Parameters
- + - +
componentIDID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr)
widthwidth (in pixels) of the YUV image. NOTE: this is the width of the whole image, not the plane width.
widthwidth (in pixels) of the YUV image. NOTE: This is the width of the whole image, not the plane width.
stridebytes per row in the image plane. Setting this to 0 is the equivalent of setting it to the plane width.
heightheight (in pixels) of the YUV image. NOTE: this is the height of the whole image, not the plane height.
heightheight (in pixels) of the YUV image. NOTE: This is the height of the whole image, not the plane height.
subsamplevel of chrominance subsampling in the image (see Chrominance subsampling options.)
@@ -3318,8 +3342,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tj3YUVPlaneWidth()

+ +

◆ tj3YUVPlaneWidth()

@@ -3365,8 +3389,8 @@ If you choose option 1, then dstSizes[i] should be set to the size

Variable Documentation

- -

◆ tjAlphaOffset

+ +

◆ tjAlphaOffset

@@ -3386,12 +3410,12 @@ If you choose option 1, then dstSizes[i] should be set to the size

Alpha offset (in samples) for a given pixel format.

-

This specifies the number of samples that the alpha component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRA is stored in unsigned char pixel[], then the alpha component will be pixel[tjAlphaOffset[TJPF_BGRA]]. This will be -1 if the pixel format does not have an alpha component.

+

This specifies the number of samples that the alpha component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRA is stored in unsigned char pixel[], then the alpha component is pixel[tjAlphaOffset[TJPF_BGRA]]. The offset is -1 if the pixel format does not have an alpha component.

- -

◆ tjBlueOffset

+ +

◆ tjBlueOffset

@@ -3411,12 +3435,12 @@ If you choose option 1, then dstSizes[i] should be set to the size

Blue offset (in samples) for a given pixel format.

-

This specifies the number of samples that the blue component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the blue component will be pixel[tjBlueOffset[TJPF_BGRX]]. This will be -1 if the pixel format does not have a blue component.

+

This specifies the number of samples that the blue component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the blue component is pixel[tjBlueOffset[TJPF_BGRX]]. The offset is -1 if the pixel format does not have a blue component.

- -

◆ tjGreenOffset

+ +

◆ tjGreenOffset

@@ -3436,12 +3460,12 @@ If you choose option 1, then dstSizes[i] should be set to the size

Green offset (in samples) for a given pixel format.

-

This specifies the number of samples that the green component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the green component will be pixel[tjGreenOffset[TJPF_BGRX]]. This will be -1 if the pixel format does not have a green component.

+

This specifies the number of samples that the green component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the green component is pixel[tjGreenOffset[TJPF_BGRX]]. The offset is -1 if the pixel format does not have a green component.

- -

◆ tjMCUHeight

+ +

◆ tjMCUHeight

@@ -3460,8 +3484,9 @@ If you choose option 1, then dstSizes[i] should be set to the size
-

MCU block height (in pixels) for a given level of chrominance subsampling.

-

MCU block sizes:

    +

    iMCU height (in pixels) for a given level of chrominance subsampling

    +

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each component are interleaved in a single scan. If the image uses chrominance subsampling, then multiple luminance blocks are stored together, followed by a single block for each chrominance component. The minimum set of full-resolution luminance block(s) and corresponding (possibly subsampled) chrominance blocks necessary to represent at least one DCT block per component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of two luminance blocks followed by one block for each chrominance component.) In a non-interleaved lossy JPEG image, each component is stored in a separate scan, and an MCU is a single DCT block, so we use the term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an interleaved JPEG image. For the common case of interleaved JPEG images, an iMCU is the same as an MCU.

    +

    iMCU sizes:

    • 8x8 for no subsampling or grayscale
    • 16x8 for 4:2:2
    • 8x16 for 4:4:0
    • @@ -3472,8 +3497,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tjMCUWidth

+ +

◆ tjMCUWidth

@@ -3492,8 +3517,9 @@ If you choose option 1, then dstSizes[i] should be set to the size
-

MCU block width (in pixels) for a given level of chrominance subsampling.

-

MCU block sizes:

    +

    iMCU width (in pixels) for a given level of chrominance subsampling

    +

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each component are interleaved in a single scan. If the image uses chrominance subsampling, then multiple luminance blocks are stored together, followed by a single block for each chrominance component. The minimum set of full-resolution luminance block(s) and corresponding (possibly subsampled) chrominance blocks necessary to represent at least one DCT block per component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of two luminance blocks followed by one block for each chrominance component.) In a non-interleaved lossy JPEG image, each component is stored in a separate scan, and an MCU is a single DCT block, so we use the term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an interleaved JPEG image. For the common case of interleaved JPEG images, an iMCU is the same as an MCU.

    +

    iMCU sizes:

    • 8x8 for no subsampling or grayscale
    • 16x8 for 4:2:2
    • 8x16 for 4:4:0
    • @@ -3504,8 +3530,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tjPixelSize

+ +

◆ tjPixelSize

@@ -3528,8 +3554,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ tjRedOffset

+ +

◆ tjRedOffset

@@ -3549,12 +3575,12 @@ If you choose option 1, then dstSizes[i] should be set to the size

Red offset (in samples) for a given pixel format.

-

This specifies the number of samples that the red component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the red component will be pixel[tjRedOffset[TJPF_BGRX]]. This will be -1 if the pixel format does not have a red component.

+

This specifies the number of samples that the red component is offset from the start of the pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored in unsigned char pixel[], then the red component is pixel[tjRedOffset[TJPF_BGRX]]. The offset is -1 if the pixel format does not have a red component.

- -

◆ TJUNCROPPED

+ +

◆ TJUNCROPPED

@@ -3577,8 +3603,8 @@ If you choose option 1, then dstSizes[i] should be set to the size
- -

◆ TJUNSCALED

+ +

◆ TJUNSCALED

@@ -3604,7 +3630,7 @@ If you choose option 1, then dstSizes[i] should be set to the size
diff --git a/doc/html/index.html b/doc/html/index.html index 7c9ccd2..95d1b32 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: Main Page @@ -20,10 +20,9 @@
- - + @@ -31,21 +30,22 @@
-
TurboJPEG -  3 +
+
TurboJPEG 3.0.1
- + +/* @license-end */ +
@@ -57,20 +57,26 @@ $(function() {
- +
+
+
+
+
Loading...
+
Searching...
+
No Matches
+
+
+
-
-
TurboJPEG Documentation
+
TurboJPEG Documentation
diff --git a/doc/html/jquery.js b/doc/html/jquery.js index 103c32d..1dffb65 100644 --- a/doc/html/jquery.js +++ b/doc/html/jquery.js @@ -1,12 +1,11 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("
").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("
"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidtht.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("
"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element -},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/** +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(y){"use strict";y.ui=y.ui||{};y.ui.version="1.13.2";var n,i=0,h=Array.prototype.hasOwnProperty,a=Array.prototype.slice;y.cleanData=(n=y.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=y._data(i,"events"))&&e.remove&&y(i).triggerHandler("remove");n(t)}),y.widget=function(t,i,e){var s,n,o,h={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=y.Widget),Array.isArray(e)&&(e=y.extend.apply(null,[{}].concat(e))),y.expr.pseudos[r.toLowerCase()]=function(t){return!!y.data(t,r)},y[a]=y[a]||{},s=y[a][t],n=y[a][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},y.extend(n,s,{version:e.version,_proto:y.extend({},e),_childConstructors:[]}),(o=new i).options=y.widget.extend({},o.options),y.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}h[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=y.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},h,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(y.each(s._childConstructors,function(t,e){var i=e.prototype;y.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),y.widget.bridge(t,n),n},y.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=y(e||this.defaultElement||this)[0],this.element=y(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=y(),this.hoverable=y(),this.focusable=y(),this.classesElementLookup={},e!==this&&(y.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=y(e.style?e.ownerDocument:e.document||e),this.window=y(this.document[0].defaultView||this.document[0].parentWindow)),this.options=y.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:y.noop,_create:y.noop,_init:y.noop,destroy:function(){var i=this;this._destroy(),y.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:y.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return y.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=y.widget.extend({},this.options[t]),n=0;n
"),i=e.children()[0];return y("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(D(s),D(n))?o.important="horizontal":o.important="vertical",p.using.call(this,t,o)}),h.offset(y.extend(l,{using:t}))})},y.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,h=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),y.ui.plugin={add:function(t,e,i){var s,n=y.ui[t].prototype;for(s in i)n.plugins[s]=n.plugins[s]||[],n.plugins[s].push([e,i[s]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;n
").css({overflow:"hidden",position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,t={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(t),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(t),this._proportionallyResize()),this._setupHandles(),e.autoHide&&y(this.element).on("mouseenter",function(){e.disabled||(i._removeClass("ui-resizable-autohide"),i._handles.show())}).on("mouseleave",function(){e.disabled||i.resizing||(i._addClass("ui-resizable-autohide"),i._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy(),this._addedHandles.remove();function t(t){y(t).removeData("resizable").removeData("ui-resizable").off(".resizable")}var e;return this.elementIsWrapper&&(t(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;case"aspectRatio":this._aspectRatio=!!e}},_setupHandles:function(){var t,e,i,s,n,o=this.options,h=this;if(this.handles=o.handles||(y(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=y(),this._addedHandles=y(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),i=this.handles.split(","),this.handles={},e=0;e"),this._addClass(n,"ui-resizable-handle "+s),n.css({zIndex:o.zIndex}),this.handles[t]=".ui-resizable-"+t,this.element.children(this.handles[t]).length||(this.element.append(n),this._addedHandles=this._addedHandles.add(n));this._renderAxis=function(t){var e,i,s;for(e in t=t||this.element,this.handles)this.handles[e].constructor===String?this.handles[e]=this.element.children(this.handles[e]).first().show():(this.handles[e].jquery||this.handles[e].nodeType)&&(this.handles[e]=y(this.handles[e]),this._on(this.handles[e],{mousedown:h._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(i=y(this.handles[e],this.element),s=/sw|ne|nw|se|n|s/.test(e)?i.outerHeight():i.outerWidth(),i=["padding",/ne|nw|n/.test(e)?"Top":/se|sw|s/.test(e)?"Bottom":/^e$/.test(e)?"Right":"Left"].join(""),t.css(i,s),this._proportionallyResize()),this._handles=this._handles.add(this.handles[e])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){h.resizing||(this.className&&(n=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),h.axis=n&&n[1]?n[1]:"se")}),o.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._addedHandles.remove()},_mouseCapture:function(t){var e,i,s=!1;for(e in this.handles)(i=y(this.handles[e])[0])!==t.target&&!y.contains(i,t.target)||(s=!0);return!this.options.disabled&&s},_mouseStart:function(t){var e,i,s=this.options,n=this.element;return this.resizing=!0,this._renderProxy(),e=this._num(this.helper.css("left")),i=this._num(this.helper.css("top")),s.containment&&(e+=y(s.containment).scrollLeft()||0,i+=y(s.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:e,top:i},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:n.width(),height:n.height()},this.originalSize=this._helper?{width:n.outerWidth(),height:n.outerHeight()}:{width:n.width(),height:n.height()},this.sizeDiff={width:n.outerWidth()-n.width(),height:n.outerHeight()-n.height()},this.originalPosition={left:e,top:i},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio="number"==typeof s.aspectRatio?s.aspectRatio:this.originalSize.width/this.originalSize.height||1,s=y(".ui-resizable-"+this.axis).css("cursor"),y("body").css("cursor","auto"===s?this.axis+"-resize":s),this._addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(t){var e=this.originalMousePosition,i=this.axis,s=t.pageX-e.left||0,e=t.pageY-e.top||0,i=this._change[i];return this._updatePrevProperties(),i&&(e=i.apply(this,[t,s,e]),this._updateVirtualBoundaries(t.shiftKey),(this._aspectRatio||t.shiftKey)&&(e=this._updateRatio(e,t)),e=this._respectSize(e,t),this._updateCache(e),this._propagate("resize",t),e=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),y.isEmptyObject(e)||(this._updatePrevProperties(),this._trigger("resize",t,this.ui()),this._applyChanges())),!1},_mouseStop:function(t){this.resizing=!1;var e,i,s,n=this.options,o=this;return this._helper&&(s=(e=(i=this._proportionallyResizeElements).length&&/textarea/i.test(i[0].nodeName))&&this._hasScroll(i[0],"left")?0:o.sizeDiff.height,i=e?0:o.sizeDiff.width,e={width:o.helper.width()-i,height:o.helper.height()-s},i=parseFloat(o.element.css("left"))+(o.position.left-o.originalPosition.left)||null,s=parseFloat(o.element.css("top"))+(o.position.top-o.originalPosition.top)||null,n.animate||this.element.css(y.extend(e,{top:s,left:i})),o.helper.height(o.size.height),o.helper.width(o.size.width),this._helper&&!n.animate&&this._proportionallyResize()),y("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s=this.options,n={minWidth:this._isNumber(s.minWidth)?s.minWidth:0,maxWidth:this._isNumber(s.maxWidth)?s.maxWidth:1/0,minHeight:this._isNumber(s.minHeight)?s.minHeight:0,maxHeight:this._isNumber(s.maxHeight)?s.maxHeight:1/0};(this._aspectRatio||t)&&(e=n.minHeight*this.aspectRatio,i=n.minWidth/this.aspectRatio,s=n.maxHeight*this.aspectRatio,t=n.maxWidth/this.aspectRatio,e>n.minWidth&&(n.minWidth=e),i>n.minHeight&&(n.minHeight=i),st.width,h=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,a=this.originalPosition.left+this.originalSize.width,r=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),i=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),h&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=a-e.minWidth),s&&l&&(t.left=a-e.maxWidth),h&&i&&(t.top=r-e.minHeight),n&&i&&(t.top=r-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];e<4;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;e
").css({overflow:"hidden"}),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++e.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize;return{left:this.originalPosition.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize;return{top:this.originalPosition.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},sw:function(t,e,i){return y.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,e,i]))},ne:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,e,i]))},nw:function(t,e,i){return y.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,e,i]))}},_propagate:function(t,e){y.ui.plugin.call(this,t,[e,this.ui()]),"resize"!==t&&this._trigger(t,e,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),y.ui.plugin.add("resizable","animate",{stop:function(e){var i=y(this).resizable("instance"),t=i.options,s=i._proportionallyResizeElements,n=s.length&&/textarea/i.test(s[0].nodeName),o=n&&i._hasScroll(s[0],"left")?0:i.sizeDiff.height,h=n?0:i.sizeDiff.width,n={width:i.size.width-h,height:i.size.height-o},h=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,o=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(y.extend(n,o&&h?{top:o,left:h}:{}),{duration:t.animateDuration,easing:t.animateEasing,step:function(){var t={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};s&&s.length&&y(s[0]).css({width:t.width,height:t.height}),i._updateCache(t),i._propagate("resize",e)}})}}),y.ui.plugin.add("resizable","containment",{start:function(){var i,s,n=y(this).resizable("instance"),t=n.options,e=n.element,o=t.containment,h=o instanceof y?o.get(0):/parent/.test(o)?e.parent().get(0):o;h&&(n.containerElement=y(h),/document/.test(o)||o===document?(n.containerOffset={left:0,top:0},n.containerPosition={left:0,top:0},n.parentData={element:y(document),left:0,top:0,width:y(document).width(),height:y(document).height()||document.body.parentNode.scrollHeight}):(i=y(h),s=[],y(["Top","Right","Left","Bottom"]).each(function(t,e){s[t]=n._num(i.css("padding"+e))}),n.containerOffset=i.offset(),n.containerPosition=i.position(),n.containerSize={height:i.innerHeight()-s[3],width:i.innerWidth()-s[1]},t=n.containerOffset,e=n.containerSize.height,o=n.containerSize.width,o=n._hasScroll(h,"left")?h.scrollWidth:o,e=n._hasScroll(h)?h.scrollHeight:e,n.parentData={element:h,left:t.left,top:t.top,width:o,height:e}))},resize:function(t){var e=y(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.position,o=e._aspectRatio||t.shiftKey,h={top:0,left:0},a=e.containerElement,t=!0;a[0]!==document&&/static/.test(a.css("position"))&&(h=s),n.left<(e._helper?s.left:0)&&(e.size.width=e.size.width+(e._helper?e.position.left-s.left:e.position.left-h.left),o&&(e.size.height=e.size.width/e.aspectRatio,t=!1),e.position.left=i.helper?s.left:0),n.top<(e._helper?s.top:0)&&(e.size.height=e.size.height+(e._helper?e.position.top-s.top:e.position.top),o&&(e.size.width=e.size.height*e.aspectRatio,t=!1),e.position.top=e._helper?s.top:0),i=e.containerElement.get(0)===e.element.parent().get(0),n=/relative|absolute/.test(e.containerElement.css("position")),i&&n?(e.offset.left=e.parentData.left+e.position.left,e.offset.top=e.parentData.top+e.position.top):(e.offset.left=e.element.offset().left,e.offset.top=e.element.offset().top),n=Math.abs(e.sizeDiff.width+(e._helper?e.offset.left-h.left:e.offset.left-s.left)),s=Math.abs(e.sizeDiff.height+(e._helper?e.offset.top-h.top:e.offset.top-s.top)),n+e.size.width>=e.parentData.width&&(e.size.width=e.parentData.width-n,o&&(e.size.height=e.size.width/e.aspectRatio,t=!1)),s+e.size.height>=e.parentData.height&&(e.size.height=e.parentData.height-s,o&&(e.size.width=e.size.height*e.aspectRatio,t=!1)),t||(e.position.left=e.prevPosition.left,e.position.top=e.prevPosition.top,e.size.width=e.prevSize.width,e.size.height=e.prevSize.height)},stop:function(){var t=y(this).resizable("instance"),e=t.options,i=t.containerOffset,s=t.containerPosition,n=t.containerElement,o=y(t.helper),h=o.offset(),a=o.outerWidth()-t.sizeDiff.width,o=o.outerHeight()-t.sizeDiff.height;t._helper&&!e.animate&&/relative/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o}),t._helper&&!e.animate&&/static/.test(n.css("position"))&&y(this).css({left:h.left-s.left-i.left,width:a,height:o})}}),y.ui.plugin.add("resizable","alsoResize",{start:function(){var t=y(this).resizable("instance").options;y(t.alsoResize).each(function(){var t=y(this);t.data("ui-resizable-alsoresize",{width:parseFloat(t.width()),height:parseFloat(t.height()),left:parseFloat(t.css("left")),top:parseFloat(t.css("top"))})})},resize:function(t,i){var e=y(this).resizable("instance"),s=e.options,n=e.originalSize,o=e.originalPosition,h={height:e.size.height-n.height||0,width:e.size.width-n.width||0,top:e.position.top-o.top||0,left:e.position.left-o.left||0};y(s.alsoResize).each(function(){var t=y(this),s=y(this).data("ui-resizable-alsoresize"),n={},e=t.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];y.each(e,function(t,e){var i=(s[e]||0)+(h[e]||0);i&&0<=i&&(n[e]=i||null)}),t.css(n)})},stop:function(){y(this).removeData("ui-resizable-alsoresize")}}),y.ui.plugin.add("resizable","ghost",{start:function(){var t=y(this).resizable("instance"),e=t.size;t.ghost=t.originalElement.clone(),t.ghost.css({opacity:.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}),t._addClass(t.ghost,"ui-resizable-ghost"),!1!==y.uiBackCompat&&"string"==typeof t.options.ghost&&t.ghost.addClass(this.options.ghost),t.ghost.appendTo(t.helper)},resize:function(){var t=y(this).resizable("instance");t.ghost&&t.ghost.css({position:"relative",height:t.size.height,width:t.size.width})},stop:function(){var t=y(this).resizable("instance");t.ghost&&t.helper&&t.helper.get(0).removeChild(t.ghost.get(0))}}),y.ui.plugin.add("resizable","grid",{resize:function(){var t,e=y(this).resizable("instance"),i=e.options,s=e.size,n=e.originalSize,o=e.originalPosition,h=e.axis,a="number"==typeof i.grid?[i.grid,i.grid]:i.grid,r=a[0]||1,l=a[1]||1,u=Math.round((s.width-n.width)/r)*r,p=Math.round((s.height-n.height)/l)*l,d=n.width+u,c=n.height+p,f=i.maxWidth&&i.maxWidthd,s=i.minHeight&&i.minHeight>c;i.grid=a,m&&(d+=r),s&&(c+=l),f&&(d-=r),g&&(c-=l),/^(se|s|e)$/.test(h)?(e.size.width=d,e.size.height=c):/^(ne)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.top=o.top-p):/^(sw)$/.test(h)?(e.size.width=d,e.size.height=c,e.position.left=o.left-u):((c-l<=0||d-r<=0)&&(t=e._getPaddingPlusBorderDimensions(this)),0'+ + var url; + var link; + link = data.children[i].url; + if (link.substring(0,1)=='^') { + url = link.substring(1); + } else { + url = relPath+link; + } + result+='
  • '+ data.children[i].text+''+ makeTree(data.children[i],relPath)+'
  • '; } @@ -36,15 +44,92 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { } return result; } - - $('#main-nav').append(makeTree(menudata,relPath)); - $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + var searchBoxHtml; if (searchEnabled) { if (serverSide) { - $('#main-menu').append('
  • '); + searchBoxHtml='
    '+ + '
    '+ + '
     '+ + ''+ + '
    '+ + '
    '+ + '
    '+ + '
    '; } else { - $('#main-menu').append('
  • '); + searchBoxHtml='
    '+ + ''+ + ' '+ + ''+ + ''+ + ''+ + ''+ + ''+ + '
    '; + } + } + + $('#main-nav').before('
    '+ + ''+ + ''+ + '
    '); + $('#main-nav').append(makeTree(menudata,relPath)); + $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu'); + if (searchBoxHtml) { + $('#main-menu').append('
  • '); + } + var $mainMenuState = $('#main-menu-state'); + var prevWidth = 0; + if ($mainMenuState.length) { + function initResizableIfExists() { + if (typeof initResizable==='function') initResizable(); + } + // animate mobile menu + $mainMenuState.change(function(e) { + var $menu = $('#main-menu'); + var options = { duration: 250, step: initResizableIfExists }; + if (this.checked) { + options['complete'] = function() { $menu.css('display', 'block') }; + $menu.hide().slideDown(options); + } else { + options['complete'] = function() { $menu.css('display', 'none') }; + $menu.show().slideUp(options); + } + }); + // set default menu visibility + function resetState() { + var $menu = $('#main-menu'); + var $mainMenuState = $('#main-menu-state'); + var newWidth = $(window).outerWidth(); + if (newWidth!=prevWidth) { + if ($(window).outerWidth()<768) { + $mainMenuState.prop('checked',false); $menu.hide(); + $('#searchBoxPos1').html(searchBoxHtml); + $('#searchBoxPos2').hide(); + } else { + $menu.show(); + $('#searchBoxPos1').empty(); + $('#searchBoxPos2').html(searchBoxHtml); + $('#searchBoxPos2').show(); + } + if (typeof searchBox!=='undefined') { + searchBox.CloseResultsWindow(); + } + prevWidth = newWidth; + } } + $(window).ready(function() { resetState(); initResizableIfExists(); }); + $(window).resize(resetState); } $('#main-menu').smartmenus(); } diff --git a/doc/html/menudata.js b/doc/html/menudata.js index fa25d42..308ed25 100644 --- a/doc/html/menudata.js +++ b/doc/html/menudata.js @@ -24,7 +24,7 @@ */ var menudata={children:[ {text:"Main Page",url:"index.html"}, -{text:"Modules",url:"modules.html"}, +{text:"Topics",url:"topics.html"}, {text:"Data Structures",url:"annotated.html",children:[ {text:"Data Structures",url:"annotated.html"}, {text:"Data Structure Index",url:"classes.html"}, diff --git a/doc/html/minus.svg b/doc/html/minus.svg new file mode 100644 index 0000000..f70d0c1 --- /dev/null +++ b/doc/html/minus.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doc/html/minusd.svg b/doc/html/minusd.svg new file mode 100644 index 0000000..5f8e879 --- /dev/null +++ b/doc/html/minusd.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doc/html/modules.html b/doc/html/modules.html deleted file mode 100644 index b6c30d8..0000000 --- a/doc/html/modules.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - -TurboJPEG: Modules - - - - - - - - - - -
    -
    - - - - - - -
    -
    TurboJPEG -  3 -
    -
    -
    - - - - - - - -
    - -
    -
    - - -
    - -
    - -
    -
    -
    Modules
    -
    -
    -
    Here is a list of all modules:
    - - -
     TurboJPEGTurboJPEG API
    -
    -
    - - - - diff --git a/doc/html/nav_fd.png b/doc/html/nav_fd.png new file mode 100644 index 0000000..032fbdd Binary files /dev/null and b/doc/html/nav_fd.png differ diff --git a/doc/html/nav_hd.png b/doc/html/nav_hd.png new file mode 100644 index 0000000..de80f18 Binary files /dev/null and b/doc/html/nav_hd.png differ diff --git a/doc/html/plus.svg b/doc/html/plus.svg new file mode 100644 index 0000000..0752016 --- /dev/null +++ b/doc/html/plus.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/html/plusd.svg b/doc/html/plusd.svg new file mode 100644 index 0000000..0c65bfe --- /dev/null +++ b/doc/html/plusd.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/html/search/all_0.html b/doc/html/search/all_0.html deleted file mode 100644 index a34319f..0000000 --- a/doc/html/search/all_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_1.html b/doc/html/search/all_1.html deleted file mode 100644 index 51aff6f..0000000 --- a/doc/html/search/all_1.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_1.js b/doc/html/search/all_1.js index 73ec5f5..cde1fd1 100644 --- a/doc/html/search/all_1.js +++ b/doc/html/search/all_1.js @@ -1,5 +1,5 @@ var searchData= [ - ['data_1',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]], - ['denom_2',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]] + ['data_0',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]], + ['denom_1',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]] ]; diff --git a/doc/html/search/all_2.html b/doc/html/search/all_2.html deleted file mode 100644 index 1f81f66..0000000 --- a/doc/html/search/all_2.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_2.js b/doc/html/search/all_2.js index 1c5615e..133cd74 100644 --- a/doc/html/search/all_2.js +++ b/doc/html/search/all_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['h_3',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]] + ['format_20notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]] ]; diff --git a/doc/html/search/all_3.html b/doc/html/search/all_3.html deleted file mode 100644 index 2e31ab9..0000000 --- a/doc/html/search/all_3.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_3.js b/doc/html/search/all_3.js index 77d139a..613c6d8 100644 --- a/doc/html/search/all_3.js +++ b/doc/html/search/all_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['num_4',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]] + ['h_0',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]] ]; diff --git a/doc/html/search/all_4.html b/doc/html/search/all_4.html deleted file mode 100644 index 0540c16..0000000 --- a/doc/html/search/all_4.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_4.js b/doc/html/search/all_4.js index f976db4..7bf9e0c 100644 --- a/doc/html/search/all_4.js +++ b/doc/html/search/all_4.js @@ -1,5 +1,4 @@ var searchData= [ - ['op_5',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]], - ['options_6',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]] + ['image_20format_20notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]] ]; diff --git a/doc/html/search/all_5.html b/doc/html/search/all_5.html deleted file mode 100644 index ebec30b..0000000 --- a/doc/html/search/all_5.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_5.js b/doc/html/search/all_5.js index 193b900..b6955cc 100644 --- a/doc/html/search/all_5.js +++ b/doc/html/search/all_5.js @@ -1,4 +1,5 @@ var searchData= [ - ['r_7',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]] + ['notes_0',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]], + ['num_1',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]] ]; diff --git a/doc/html/search/all_6.html b/doc/html/search/all_6.html deleted file mode 100644 index 31cbd05..0000000 --- a/doc/html/search/all_6.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_6.js b/doc/html/search/all_6.js index a3fa784..42a3475 100644 --- a/doc/html/search/all_6.js +++ b/doc/html/search/all_6.js @@ -1,141 +1,5 @@ var searchData= [ - ['tj3alloc_8',['tj3Alloc',['../group___turbo_j_p_e_g.html#gab40a0b231122f536e503e3394569a68d',1,'turbojpeg.h']]], - ['tj3compress12_9',['tj3Compress12',['../group___turbo_j_p_e_g.html#ga9a1968c384ec7abb6122830253ebf570',1,'turbojpeg.h']]], - ['tj3compress16_10',['tj3Compress16',['../group___turbo_j_p_e_g.html#ga77901b71d0471784f318ada31ff4e7bd',1,'turbojpeg.h']]], - ['tj3compress8_11',['tj3Compress8',['../group___turbo_j_p_e_g.html#ga2cc418a2dab709ad7f30f5b25905f138',1,'turbojpeg.h']]], - ['tj3compressfromyuv8_12',['tj3CompressFromYUV8',['../group___turbo_j_p_e_g.html#ga041c870d9c669eb3f385c78f4346c43f',1,'turbojpeg.h']]], - ['tj3compressfromyuvplanes8_13',['tj3CompressFromYUVPlanes8',['../group___turbo_j_p_e_g.html#gac9f5ace3e73805b476c95dda9f8d0cd0',1,'turbojpeg.h']]], - ['tj3decodeyuv8_14',['tj3DecodeYUV8',['../group___turbo_j_p_e_g.html#gaa1eb574f38b1c1de43a6c7aafcf68d8c',1,'turbojpeg.h']]], - ['tj3decodeyuvplanes8_15',['tj3DecodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gad366f1915f82c1ad4e7e37ebe073ca89',1,'turbojpeg.h']]], - ['tj3decompress12_16',['tj3Decompress12',['../group___turbo_j_p_e_g.html#ga39b848f01781ad74a5b3941c012b6199',1,'turbojpeg.h']]], - ['tj3decompress16_17',['tj3Decompress16',['../group___turbo_j_p_e_g.html#gaa074e63f9beb0b3ff42b833a4049df6e',1,'turbojpeg.h']]], - ['tj3decompress8_18',['tj3Decompress8',['../group___turbo_j_p_e_g.html#ga1169c7c1a26ec18c9e6122cb8ae64013',1,'turbojpeg.h']]], - ['tj3decompressheader_19',['tj3DecompressHeader',['../group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1',1,'turbojpeg.h']]], - ['tj3decompresstoyuv8_20',['tj3DecompressToYUV8',['../group___turbo_j_p_e_g.html#ga1e6bf6a19fec3f9fa7534348879d8320',1,'turbojpeg.h']]], - ['tj3decompresstoyuvplanes8_21',['tj3DecompressToYUVPlanes8',['../group___turbo_j_p_e_g.html#ga934373482dbbf257f2280505b6ff4fb5',1,'turbojpeg.h']]], - ['tj3destroy_22',['tj3Destroy',['../group___turbo_j_p_e_g.html#ga53fbadf4560e95a65b8f5ab81703fe82',1,'turbojpeg.h']]], - ['tj3encodeyuv8_23',['tj3EncodeYUV8',['../group___turbo_j_p_e_g.html#ga2a8d50f130bde10f0a04030f8cc59936',1,'turbojpeg.h']]], - ['tj3encodeyuvplanes8_24',['tj3EncodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gae2e9df38790e9bddc249d04cb158a4cf',1,'turbojpeg.h']]], - ['tj3free_25',['tj3Free',['../group___turbo_j_p_e_g.html#gaddb84fb6c81769e9faa0f5a63b296606',1,'turbojpeg.h']]], - ['tj3get_26',['tj3Get',['../group___turbo_j_p_e_g.html#ga34af9ba3183bdf0ec7c8f47bb9a4c84f',1,'turbojpeg.h']]], - ['tj3geterrorcode_27',['tj3GetErrorCode',['../group___turbo_j_p_e_g.html#gab8c8279f1415fe425ff30dbbc56013bd',1,'turbojpeg.h']]], - ['tj3geterrorstr_28',['tj3GetErrorStr',['../group___turbo_j_p_e_g.html#gaf2aab0e6dbb3edc57646b0fec25e8bb2',1,'turbojpeg.h']]], - ['tj3getscalingfactors_29',['tj3GetScalingFactors',['../group___turbo_j_p_e_g.html#ga74397f8e0587d4233182c72f085aaf04',1,'turbojpeg.h']]], - ['tj3init_30',['tj3Init',['../group___turbo_j_p_e_g.html#ga69c09d39f97ec30250ad3605ace7e5df',1,'turbojpeg.h']]], - ['tj3jpegbufsize_31',['tj3JPEGBufSize',['../group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4',1,'turbojpeg.h']]], - ['tj3loadimage12_32',['tj3LoadImage12',['../group___turbo_j_p_e_g.html#ga1f03c26892a26d4ce077ed6a4ac40e8f',1,'turbojpeg.h']]], - ['tj3loadimage16_33',['tj3LoadImage16',['../group___turbo_j_p_e_g.html#ga638aeba63e0ccb89d472fdbf34224cfc',1,'turbojpeg.h']]], - ['tj3loadimage8_34',['tj3LoadImage8',['../group___turbo_j_p_e_g.html#ga565aaae7be3f8ca9099b56655c893251',1,'turbojpeg.h']]], - ['tj3saveimage12_35',['tj3SaveImage12',['../group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90',1,'turbojpeg.h']]], - ['tj3saveimage16_36',['tj3SaveImage16',['../group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71',1,'turbojpeg.h']]], - ['tj3saveimage8_37',['tj3SaveImage8',['../group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722',1,'turbojpeg.h']]], - ['tj3set_38',['tj3Set',['../group___turbo_j_p_e_g.html#gaddf92640bfee3e8622218c713e77e7db',1,'turbojpeg.h']]], - ['tj3setcroppingregion_39',['tj3SetCroppingRegion',['../group___turbo_j_p_e_g.html#gaa49c7bd4c9431667a043cfc93388ba1c',1,'turbojpeg.h']]], - ['tj3setscalingfactor_40',['tj3SetScalingFactor',['../group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75',1,'turbojpeg.h']]], - ['tj3transform_41',['tj3Transform',['../group___turbo_j_p_e_g.html#gaff23ba1dcabed456794b844791613920',1,'turbojpeg.h']]], - ['tj3yuvbufsize_42',['tj3YUVBufSize',['../group___turbo_j_p_e_g.html#gaaebaa16973a0f550a66eca5765ed0546',1,'turbojpeg.h']]], - ['tj3yuvplaneheight_43',['tj3YUVPlaneHeight',['../group___turbo_j_p_e_g.html#ga969767ec8180cc3edd99cf507f87299b',1,'turbojpeg.h']]], - ['tj3yuvplanesize_44',['tj3YUVPlaneSize',['../group___turbo_j_p_e_g.html#gacc19d265edce76b46146f59579f9438d',1,'turbojpeg.h']]], - ['tj3yuvplanewidth_45',['tj3YUVPlaneWidth',['../group___turbo_j_p_e_g.html#gac99d1933ede1d59fcada9a826e88eb2d',1,'turbojpeg.h']]], - ['tj_5fnumcs_46',['TJ_NUMCS',['../group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71',1,'turbojpeg.h']]], - ['tj_5fnumerr_47',['TJ_NUMERR',['../group___turbo_j_p_e_g.html#ga79bde1b4a3e2351e00887e47781b966e',1,'turbojpeg.h']]], - ['tj_5fnuminit_48',['TJ_NUMINIT',['../group___turbo_j_p_e_g.html#ga5e0e8c784295c636f0bf8dab93c4bddf',1,'turbojpeg.h']]], - ['tj_5fnumparam_49',['TJ_NUMPARAM',['../group___turbo_j_p_e_g.html#gaa628be5db276fc3676dfba205d45d780',1,'turbojpeg.h']]], - ['tj_5fnumpf_50',['TJ_NUMPF',['../group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e',1,'turbojpeg.h']]], - ['tj_5fnumsamp_51',['TJ_NUMSAMP',['../group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c',1,'turbojpeg.h']]], - ['tj_5fnumxop_52',['TJ_NUMXOP',['../group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c',1,'turbojpeg.h']]], - ['tjalphaoffset_53',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]], - ['tjblueoffset_54',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]], - ['tjcs_55',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]], - ['tjcs_5fcmyk_56',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]], - ['tjcs_5fgray_57',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]], - ['tjcs_5frgb_58',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]], - ['tjcs_5fycbcr_59',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]], - ['tjcs_5fycck_60',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]], - ['tjerr_61',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], - ['tjerr_5ffatal_62',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], - ['tjerr_5fwarning_63',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], - ['tjgreenoffset_64',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]], - ['tjhandle_65',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]], - ['tjinit_66',['TJINIT',['../group___turbo_j_p_e_g.html#ga3850bbee1313e752e667b4eb08b1e086',1,'turbojpeg.h']]], - ['tjinit_5fcompress_67',['TJINIT_COMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086aa45ac279e3dc6ffabc4b0f45864da796',1,'turbojpeg.h']]], - ['tjinit_5fdecompress_68',['TJINIT_DECOMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a4b8ca1ef700699b71350700bf95c2167',1,'turbojpeg.h']]], - ['tjinit_5ftransform_69',['TJINIT_TRANSFORM',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a8d58a2a4c45b3e0cd349746544a6e0c2',1,'turbojpeg.h']]], - ['tjmcuheight_70',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]], - ['tjmcuwidth_71',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]], - ['tjparam_72',['TJPARAM',['../group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82',1,'turbojpeg.h']]], - ['tjparam_5farithmetic_73',['TJPARAM_ARITHMETIC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1c756757384308145602c040524aebf7',1,'turbojpeg.h']]], - ['tjparam_5fbottomup_74',['TJPARAM_BOTTOMUP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a924657172695ed6cb0b128219546fcce',1,'turbojpeg.h']]], - ['tjparam_5fcolorspace_75',['TJPARAM_COLORSPACE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a46a10d46309514907d0c39fcd86c324c',1,'turbojpeg.h']]], - ['tjparam_5fdensityunits_76',['TJPARAM_DENSITYUNITS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4c045981bd8a303521a401dbbe1df208',1,'turbojpeg.h']]], - ['tjparam_5ffastdct_77',['TJPARAM_FASTDCT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a6914692ac6ec5567787d592b7563f627',1,'turbojpeg.h']]], - ['tjparam_5ffastupsample_78',['TJPARAM_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0e051ac106f7b7402b690a5daf4869c0',1,'turbojpeg.h']]], - ['tjparam_5fjpegheight_79',['TJPARAM_JPEGHEIGHT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f',1,'turbojpeg.h']]], - ['tjparam_5fjpegwidth_80',['TJPARAM_JPEGWIDTH',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a02ab77fb294a0c9061a78cd424c82dd8',1,'turbojpeg.h']]], - ['tjparam_5flossless_81',['TJPARAM_LOSSLESS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a249f35f0770792b19f995e603bb17c6f',1,'turbojpeg.h']]], - ['tjparam_5flosslesspsv_82',['TJPARAM_LOSSLESSPSV',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abcc997d40e5bec84817c12b76ef84159',1,'turbojpeg.h']]], - ['tjparam_5flosslesspt_83',['TJPARAM_LOSSLESSPT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4a6c6f25764ecaf4231a36bff844e46a',1,'turbojpeg.h']]], - ['tjparam_5fnorealloc_84',['TJPARAM_NOREALLOC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b',1,'turbojpeg.h']]], - ['tjparam_5foptimize_85',['TJPARAM_OPTIMIZE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f0af9afc0b36443751f9ee82b760aa6',1,'turbojpeg.h']]], - ['tjparam_5fprecision_86',['TJPARAM_PRECISION',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8',1,'turbojpeg.h']]], - ['tjparam_5fprogressive_87',['TJPARAM_PROGRESSIVE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1716f242b3859905b4a317dae8cfb75f',1,'turbojpeg.h']]], - ['tjparam_5fquality_88',['TJPARAM_QUALITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0467e8792621f2d817dc2af563d3186c',1,'turbojpeg.h']]], - ['tjparam_5frestartblocks_89',['TJPARAM_RESTARTBLOCKS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a343c72883b7160f23f3ef46fc548a0ec',1,'turbojpeg.h']]], - ['tjparam_5frestartrows_90',['TJPARAM_RESTARTROWS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a714367585952fe5c863f0dba5bd37e5c',1,'turbojpeg.h']]], - ['tjparam_5fscanlimit_91',['TJPARAM_SCANLIMIT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac478910e20ecf61b914f9824d80f8167',1,'turbojpeg.h']]], - ['tjparam_5fstoponwarning_92',['TJPARAM_STOPONWARNING',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a555e2212079fa49b30bcd2879c6c8ddb',1,'turbojpeg.h']]], - ['tjparam_5fsubsamp_93',['TJPARAM_SUBSAMP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a',1,'turbojpeg.h']]], - ['tjparam_5fxdensity_94',['TJPARAM_XDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4de5c9d7cab5be806143a43c3b0e0877',1,'turbojpeg.h']]], - ['tjparam_5fydensity_95',['TJPARAM_YDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abda48f2df7eb9b88e2b7621efb017eba',1,'turbojpeg.h']]], - ['tjpf_96',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]], - ['tjpf_5fabgr_97',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]], - ['tjpf_5fargb_98',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]], - ['tjpf_5fbgr_99',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]], - ['tjpf_5fbgra_100',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]], - ['tjpf_5fbgrx_101',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]], - ['tjpf_5fcmyk_102',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]], - ['tjpf_5fgray_103',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]], - ['tjpf_5frgb_104',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]], - ['tjpf_5frgba_105',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]], - ['tjpf_5frgbx_106',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]], - ['tjpf_5funknown_107',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]], - ['tjpf_5fxbgr_108',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]], - ['tjpf_5fxrgb_109',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]], - ['tjpixelsize_110',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]], - ['tjredoffset_111',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]], - ['tjregion_112',['tjregion',['../structtjregion.html',1,'']]], - ['tjsamp_113',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]], - ['tjsamp_5f411_114',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]], - ['tjsamp_5f420_115',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]], - ['tjsamp_5f422_116',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]], - ['tjsamp_5f440_117',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]], - ['tjsamp_5f441_118',['TJSAMP_441',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3351696e1dd34a083a35b6be8b90122d',1,'turbojpeg.h']]], - ['tjsamp_5f444_119',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]], - ['tjsamp_5fgray_120',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]], - ['tjsamp_5funknown_121',['TJSAMP_UNKNOWN',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074ac124fa8f6cb41147e3d670dfbdfb7173',1,'turbojpeg.h']]], - ['tjscaled_122',['TJSCALED',['../group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df',1,'turbojpeg.h']]], - ['tjscalingfactor_123',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]], - ['tjtransform_124',['tjtransform',['../structtjtransform.html',1,'tjtransform'],['../group___turbo_j_p_e_g.html#ga504805ec0161f1b505397ca0118bf8fd',1,'tjtransform(): turbojpeg.h']]], - ['tjuncropped_125',['TJUNCROPPED',['../group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf',1,'turbojpeg.h']]], - ['tjunscaled_126',['TJUNSCALED',['../group___turbo_j_p_e_g.html#ga7880644a0849161ad20933536169ee19',1,'turbojpeg.h']]], - ['tjxop_127',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]], - ['tjxop_5fhflip_128',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]], - ['tjxop_5fnone_129',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]], - ['tjxop_5frot180_130',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]], - ['tjxop_5frot270_131',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]], - ['tjxop_5frot90_132',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]], - ['tjxop_5ftranspose_133',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]], - ['tjxop_5ftransverse_134',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]], - ['tjxop_5fvflip_135',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]], - ['tjxopt_5farithmetic_136',['TJXOPT_ARITHMETIC',['../group___turbo_j_p_e_g.html#gaecaaa3b7e2af812592c015d83207f010',1,'turbojpeg.h']]], - ['tjxopt_5fcopynone_137',['TJXOPT_COPYNONE',['../group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8',1,'turbojpeg.h']]], - ['tjxopt_5fcrop_138',['TJXOPT_CROP',['../group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2',1,'turbojpeg.h']]], - ['tjxopt_5fgray_139',['TJXOPT_GRAY',['../group___turbo_j_p_e_g.html#ga3acee7b48ade1b99e5588736007c2589',1,'turbojpeg.h']]], - ['tjxopt_5fnooutput_140',['TJXOPT_NOOUTPUT',['../group___turbo_j_p_e_g.html#gafbf992bbf6e006705886333703ffab31',1,'turbojpeg.h']]], - ['tjxopt_5foptimize_141',['TJXOPT_OPTIMIZE',['../group___turbo_j_p_e_g.html#ga6bedf37aa9e1122f3ec9f7302ca59117',1,'turbojpeg.h']]], - ['tjxopt_5fperfect_142',['TJXOPT_PERFECT',['../group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00',1,'turbojpeg.h']]], - ['tjxopt_5fprogressive_143',['TJXOPT_PROGRESSIVE',['../group___turbo_j_p_e_g.html#gad2371c80674584ecc1a7d75e564cf026',1,'turbojpeg.h']]], - ['tjxopt_5ftrim_144',['TJXOPT_TRIM',['../group___turbo_j_p_e_g.html#ga319826b7eb1583c0595bbe7b95428709',1,'turbojpeg.h']]], - ['turbojpeg_145',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]] + ['op_0',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]], + ['options_1',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]] ]; diff --git a/doc/html/search/all_7.html b/doc/html/search/all_7.html deleted file mode 100644 index 18c555d..0000000 --- a/doc/html/search/all_7.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_7.js b/doc/html/search/all_7.js index 7d2132b..65fe61f 100644 --- a/doc/html/search/all_7.js +++ b/doc/html/search/all_7.js @@ -1,4 +1,4 @@ var searchData= [ - ['w_146',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]] + ['r_0',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]] ]; diff --git a/doc/html/search/all_8.html b/doc/html/search/all_8.html deleted file mode 100644 index 0f9eb41..0000000 --- a/doc/html/search/all_8.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_8.js b/doc/html/search/all_8.js index 4ef2012..8e5ee81 100644 --- a/doc/html/search/all_8.js +++ b/doc/html/search/all_8.js @@ -1,4 +1,142 @@ var searchData= [ - ['x_147',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]] + ['tj3alloc_0',['tj3Alloc',['../group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57',1,'turbojpeg.h']]], + ['tj3compress12_1',['tj3Compress12',['../group___turbo_j_p_e_g.html#ga9a1968c384ec7abb6122830253ebf570',1,'turbojpeg.h']]], + ['tj3compress16_2',['tj3Compress16',['../group___turbo_j_p_e_g.html#ga77901b71d0471784f318ada31ff4e7bd',1,'turbojpeg.h']]], + ['tj3compress8_3',['tj3Compress8',['../group___turbo_j_p_e_g.html#ga2cc418a2dab709ad7f30f5b25905f138',1,'turbojpeg.h']]], + ['tj3compressfromyuv8_4',['tj3CompressFromYUV8',['../group___turbo_j_p_e_g.html#ga041c870d9c669eb3f385c78f4346c43f',1,'turbojpeg.h']]], + ['tj3compressfromyuvplanes8_5',['tj3CompressFromYUVPlanes8',['../group___turbo_j_p_e_g.html#gac9f5ace3e73805b476c95dda9f8d0cd0',1,'turbojpeg.h']]], + ['tj3decodeyuv8_6',['tj3DecodeYUV8',['../group___turbo_j_p_e_g.html#gaa1eb574f38b1c1de43a6c7aafcf68d8c',1,'turbojpeg.h']]], + ['tj3decodeyuvplanes8_7',['tj3DecodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gad366f1915f82c1ad4e7e37ebe073ca89',1,'turbojpeg.h']]], + ['tj3decompress12_8',['tj3Decompress12',['../group___turbo_j_p_e_g.html#ga39b848f01781ad74a5b3941c012b6199',1,'turbojpeg.h']]], + ['tj3decompress16_9',['tj3Decompress16',['../group___turbo_j_p_e_g.html#gaa074e63f9beb0b3ff42b833a4049df6e',1,'turbojpeg.h']]], + ['tj3decompress8_10',['tj3Decompress8',['../group___turbo_j_p_e_g.html#ga1169c7c1a26ec18c9e6122cb8ae64013',1,'turbojpeg.h']]], + ['tj3decompressheader_11',['tj3DecompressHeader',['../group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1',1,'turbojpeg.h']]], + ['tj3decompresstoyuv8_12',['tj3DecompressToYUV8',['../group___turbo_j_p_e_g.html#ga1e6bf6a19fec3f9fa7534348879d8320',1,'turbojpeg.h']]], + ['tj3decompresstoyuvplanes8_13',['tj3DecompressToYUVPlanes8',['../group___turbo_j_p_e_g.html#ga934373482dbbf257f2280505b6ff4fb5',1,'turbojpeg.h']]], + ['tj3destroy_14',['tj3Destroy',['../group___turbo_j_p_e_g.html#ga53fbadf4560e95a65b8f5ab81703fe82',1,'turbojpeg.h']]], + ['tj3encodeyuv8_15',['tj3EncodeYUV8',['../group___turbo_j_p_e_g.html#ga2a8d50f130bde10f0a04030f8cc59936',1,'turbojpeg.h']]], + ['tj3encodeyuvplanes8_16',['tj3EncodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gae2e9df38790e9bddc249d04cb158a4cf',1,'turbojpeg.h']]], + ['tj3free_17',['tj3Free',['../group___turbo_j_p_e_g.html#gaddb84fb6c81769e9faa0f5a63b296606',1,'turbojpeg.h']]], + ['tj3get_18',['tj3Get',['../group___turbo_j_p_e_g.html#ga34af9ba3183bdf0ec7c8f47bb9a4c84f',1,'turbojpeg.h']]], + ['tj3geterrorcode_19',['tj3GetErrorCode',['../group___turbo_j_p_e_g.html#gab8c8279f1415fe425ff30dbbc56013bd',1,'turbojpeg.h']]], + ['tj3geterrorstr_20',['tj3GetErrorStr',['../group___turbo_j_p_e_g.html#ga5a23ad0776c5333cda0d7c6d826e9d29',1,'turbojpeg.h']]], + ['tj3getscalingfactors_21',['tj3GetScalingFactors',['../group___turbo_j_p_e_g.html#gaf9253e0c2e9f464142d389673da085fa',1,'turbojpeg.h']]], + ['tj3init_22',['tj3Init',['../group___turbo_j_p_e_g.html#ga69c09d39f97ec30250ad3605ace7e5df',1,'turbojpeg.h']]], + ['tj3jpegbufsize_23',['tj3JPEGBufSize',['../group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4',1,'turbojpeg.h']]], + ['tj3loadimage12_24',['tj3LoadImage12',['../group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44',1,'turbojpeg.h']]], + ['tj3loadimage16_25',['tj3LoadImage16',['../group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69',1,'turbojpeg.h']]], + ['tj3loadimage8_26',['tj3LoadImage8',['../group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001',1,'turbojpeg.h']]], + ['tj3saveimage12_27',['tj3SaveImage12',['../group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90',1,'turbojpeg.h']]], + ['tj3saveimage16_28',['tj3SaveImage16',['../group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71',1,'turbojpeg.h']]], + ['tj3saveimage8_29',['tj3SaveImage8',['../group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722',1,'turbojpeg.h']]], + ['tj3set_30',['tj3Set',['../group___turbo_j_p_e_g.html#gaddf92640bfee3e8622218c713e77e7db',1,'turbojpeg.h']]], + ['tj3setcroppingregion_31',['tj3SetCroppingRegion',['../group___turbo_j_p_e_g.html#gaa49c7bd4c9431667a043cfc93388ba1c',1,'turbojpeg.h']]], + ['tj3setscalingfactor_32',['tj3SetScalingFactor',['../group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75',1,'turbojpeg.h']]], + ['tj3transform_33',['tj3Transform',['../group___turbo_j_p_e_g.html#gaff23ba1dcabed456794b844791613920',1,'turbojpeg.h']]], + ['tj3yuvbufsize_34',['tj3YUVBufSize',['../group___turbo_j_p_e_g.html#gaaebaa16973a0f550a66eca5765ed0546',1,'turbojpeg.h']]], + ['tj3yuvplaneheight_35',['tj3YUVPlaneHeight',['../group___turbo_j_p_e_g.html#ga969767ec8180cc3edd99cf507f87299b',1,'turbojpeg.h']]], + ['tj3yuvplanesize_36',['tj3YUVPlaneSize',['../group___turbo_j_p_e_g.html#gacc19d265edce76b46146f59579f9438d',1,'turbojpeg.h']]], + ['tj3yuvplanewidth_37',['tj3YUVPlaneWidth',['../group___turbo_j_p_e_g.html#gac99d1933ede1d59fcada9a826e88eb2d',1,'turbojpeg.h']]], + ['tj_5fnumcs_38',['TJ_NUMCS',['../group___turbo_j_p_e_g.html#ga39f57a6fb02d9cf32e7b6890099b5a71',1,'turbojpeg.h']]], + ['tj_5fnumerr_39',['TJ_NUMERR',['../group___turbo_j_p_e_g.html#ga79bde1b4a3e2351e00887e47781b966e',1,'turbojpeg.h']]], + ['tj_5fnuminit_40',['TJ_NUMINIT',['../group___turbo_j_p_e_g.html#ga5e0e8c784295c636f0bf8dab93c4bddf',1,'turbojpeg.h']]], + ['tj_5fnumpf_41',['TJ_NUMPF',['../group___turbo_j_p_e_g.html#ga7010a4402f54a45ba822ad8675a4655e',1,'turbojpeg.h']]], + ['tj_5fnumsamp_42',['TJ_NUMSAMP',['../group___turbo_j_p_e_g.html#ga5ef3d169162ce77ce348e292a0b7477c',1,'turbojpeg.h']]], + ['tj_5fnumxop_43',['TJ_NUMXOP',['../group___turbo_j_p_e_g.html#ga0f6dbd18adf38b7d46ac547f0f4d562c',1,'turbojpeg.h']]], + ['tjalphaoffset_44',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]], + ['tjblueoffset_45',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]], + ['tjcs_46',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]], + ['tjcs_5fcmyk_47',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]], + ['tjcs_5fgray_48',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]], + ['tjcs_5frgb_49',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]], + ['tjcs_5fycbcr_50',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]], + ['tjcs_5fycck_51',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]], + ['tjerr_52',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], + ['tjerr_5ffatal_53',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], + ['tjerr_5fwarning_54',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], + ['tjgreenoffset_55',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]], + ['tjhandle_56',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]], + ['tjinit_57',['TJINIT',['../group___turbo_j_p_e_g.html#ga3850bbee1313e752e667b4eb08b1e086',1,'turbojpeg.h']]], + ['tjinit_5fcompress_58',['TJINIT_COMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086aa45ac279e3dc6ffabc4b0f45864da796',1,'turbojpeg.h']]], + ['tjinit_5fdecompress_59',['TJINIT_DECOMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a4b8ca1ef700699b71350700bf95c2167',1,'turbojpeg.h']]], + ['tjinit_5ftransform_60',['TJINIT_TRANSFORM',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a8d58a2a4c45b3e0cd349746544a6e0c2',1,'turbojpeg.h']]], + ['tjmcuheight_61',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]], + ['tjmcuwidth_62',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]], + ['tjparam_63',['TJPARAM',['../group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82',1,'turbojpeg.h']]], + ['tjparam_5farithmetic_64',['TJPARAM_ARITHMETIC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1c756757384308145602c040524aebf7',1,'turbojpeg.h']]], + ['tjparam_5fbottomup_65',['TJPARAM_BOTTOMUP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a924657172695ed6cb0b128219546fcce',1,'turbojpeg.h']]], + ['tjparam_5fcolorspace_66',['TJPARAM_COLORSPACE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a46a10d46309514907d0c39fcd86c324c',1,'turbojpeg.h']]], + ['tjparam_5fdensityunits_67',['TJPARAM_DENSITYUNITS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4c045981bd8a303521a401dbbe1df208',1,'turbojpeg.h']]], + ['tjparam_5ffastdct_68',['TJPARAM_FASTDCT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a6914692ac6ec5567787d592b7563f627',1,'turbojpeg.h']]], + ['tjparam_5ffastupsample_69',['TJPARAM_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0e051ac106f7b7402b690a5daf4869c0',1,'turbojpeg.h']]], + ['tjparam_5fjpegheight_70',['TJPARAM_JPEGHEIGHT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f',1,'turbojpeg.h']]], + ['tjparam_5fjpegwidth_71',['TJPARAM_JPEGWIDTH',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a02ab77fb294a0c9061a78cd424c82dd8',1,'turbojpeg.h']]], + ['tjparam_5flossless_72',['TJPARAM_LOSSLESS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a249f35f0770792b19f995e603bb17c6f',1,'turbojpeg.h']]], + ['tjparam_5flosslesspsv_73',['TJPARAM_LOSSLESSPSV',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abcc997d40e5bec84817c12b76ef84159',1,'turbojpeg.h']]], + ['tjparam_5flosslesspt_74',['TJPARAM_LOSSLESSPT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4a6c6f25764ecaf4231a36bff844e46a',1,'turbojpeg.h']]], + ['tjparam_5fmaxmemory_75',['TJPARAM_MAXMEMORY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0de0a8281da45d1fc984edc8918f7dd2',1,'turbojpeg.h']]], + ['tjparam_5fmaxpixels_76',['TJPARAM_MAXPIXELS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac4e95dd2ecd766854feee579406eae68',1,'turbojpeg.h']]], + ['tjparam_5fnorealloc_77',['TJPARAM_NOREALLOC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b',1,'turbojpeg.h']]], + ['tjparam_5foptimize_78',['TJPARAM_OPTIMIZE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f0af9afc0b36443751f9ee82b760aa6',1,'turbojpeg.h']]], + ['tjparam_5fprecision_79',['TJPARAM_PRECISION',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8',1,'turbojpeg.h']]], + ['tjparam_5fprogressive_80',['TJPARAM_PROGRESSIVE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1716f242b3859905b4a317dae8cfb75f',1,'turbojpeg.h']]], + ['tjparam_5fquality_81',['TJPARAM_QUALITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0467e8792621f2d817dc2af563d3186c',1,'turbojpeg.h']]], + ['tjparam_5frestartblocks_82',['TJPARAM_RESTARTBLOCKS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a343c72883b7160f23f3ef46fc548a0ec',1,'turbojpeg.h']]], + ['tjparam_5frestartrows_83',['TJPARAM_RESTARTROWS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a714367585952fe5c863f0dba5bd37e5c',1,'turbojpeg.h']]], + ['tjparam_5fscanlimit_84',['TJPARAM_SCANLIMIT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac478910e20ecf61b914f9824d80f8167',1,'turbojpeg.h']]], + ['tjparam_5fstoponwarning_85',['TJPARAM_STOPONWARNING',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a555e2212079fa49b30bcd2879c6c8ddb',1,'turbojpeg.h']]], + ['tjparam_5fsubsamp_86',['TJPARAM_SUBSAMP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a',1,'turbojpeg.h']]], + ['tjparam_5fxdensity_87',['TJPARAM_XDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4de5c9d7cab5be806143a43c3b0e0877',1,'turbojpeg.h']]], + ['tjparam_5fydensity_88',['TJPARAM_YDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abda48f2df7eb9b88e2b7621efb017eba',1,'turbojpeg.h']]], + ['tjpf_89',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]], + ['tjpf_5fabgr_90',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]], + ['tjpf_5fargb_91',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]], + ['tjpf_5fbgr_92',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]], + ['tjpf_5fbgra_93',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]], + ['tjpf_5fbgrx_94',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]], + ['tjpf_5fcmyk_95',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]], + ['tjpf_5fgray_96',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]], + ['tjpf_5frgb_97',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]], + ['tjpf_5frgba_98',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]], + ['tjpf_5frgbx_99',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]], + ['tjpf_5funknown_100',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]], + ['tjpf_5fxbgr_101',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]], + ['tjpf_5fxrgb_102',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]], + ['tjpixelsize_103',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]], + ['tjredoffset_104',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]], + ['tjregion_105',['tjregion',['../structtjregion.html',1,'']]], + ['tjsamp_106',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]], + ['tjsamp_5f411_107',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]], + ['tjsamp_5f420_108',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]], + ['tjsamp_5f422_109',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]], + ['tjsamp_5f440_110',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]], + ['tjsamp_5f441_111',['TJSAMP_441',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3351696e1dd34a083a35b6be8b90122d',1,'turbojpeg.h']]], + ['tjsamp_5f444_112',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]], + ['tjsamp_5fgray_113',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]], + ['tjsamp_5funknown_114',['TJSAMP_UNKNOWN',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074ac124fa8f6cb41147e3d670dfbdfb7173',1,'turbojpeg.h']]], + ['tjscaled_115',['TJSCALED',['../group___turbo_j_p_e_g.html#ga84878bb65404204743aa18cac02781df',1,'turbojpeg.h']]], + ['tjscalingfactor_116',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]], + ['tjtransform_117',['tjtransform',['../structtjtransform.html',1,'tjtransform'],['../group___turbo_j_p_e_g.html#ga504805ec0161f1b505397ca0118bf8fd',1,'tjtransform: turbojpeg.h']]], + ['tjuncropped_118',['TJUNCROPPED',['../group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf',1,'turbojpeg.h']]], + ['tjunscaled_119',['TJUNSCALED',['../group___turbo_j_p_e_g.html#ga7880644a0849161ad20933536169ee19',1,'turbojpeg.h']]], + ['tjxop_120',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]], + ['tjxop_5fhflip_121',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]], + ['tjxop_5fnone_122',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]], + ['tjxop_5frot180_123',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]], + ['tjxop_5frot270_124',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]], + ['tjxop_5frot90_125',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]], + ['tjxop_5ftranspose_126',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]], + ['tjxop_5ftransverse_127',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]], + ['tjxop_5fvflip_128',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]], + ['tjxopt_5farithmetic_129',['TJXOPT_ARITHMETIC',['../group___turbo_j_p_e_g.html#gaecaaa3b7e2af812592c015d83207f010',1,'turbojpeg.h']]], + ['tjxopt_5fcopynone_130',['TJXOPT_COPYNONE',['../group___turbo_j_p_e_g.html#ga153b468cfb905d0de61706c838986fe8',1,'turbojpeg.h']]], + ['tjxopt_5fcrop_131',['TJXOPT_CROP',['../group___turbo_j_p_e_g.html#ga9c771a757fc1294add611906b89ab2d2',1,'turbojpeg.h']]], + ['tjxopt_5fgray_132',['TJXOPT_GRAY',['../group___turbo_j_p_e_g.html#ga3acee7b48ade1b99e5588736007c2589',1,'turbojpeg.h']]], + ['tjxopt_5fnooutput_133',['TJXOPT_NOOUTPUT',['../group___turbo_j_p_e_g.html#gafbf992bbf6e006705886333703ffab31',1,'turbojpeg.h']]], + ['tjxopt_5foptimize_134',['TJXOPT_OPTIMIZE',['../group___turbo_j_p_e_g.html#ga6bedf37aa9e1122f3ec9f7302ca59117',1,'turbojpeg.h']]], + ['tjxopt_5fperfect_135',['TJXOPT_PERFECT',['../group___turbo_j_p_e_g.html#ga50e03cb5ed115330e212417429600b00',1,'turbojpeg.h']]], + ['tjxopt_5fprogressive_136',['TJXOPT_PROGRESSIVE',['../group___turbo_j_p_e_g.html#gad2371c80674584ecc1a7d75e564cf026',1,'turbojpeg.h']]], + ['tjxopt_5ftrim_137',['TJXOPT_TRIM',['../group___turbo_j_p_e_g.html#ga319826b7eb1583c0595bbe7b95428709',1,'turbojpeg.h']]], + ['turbojpeg_138',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]] ]; diff --git a/doc/html/search/all_9.html b/doc/html/search/all_9.html deleted file mode 100644 index d27c0f7..0000000 --- a/doc/html/search/all_9.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/all_9.js b/doc/html/search/all_9.js index 3a72aaf..3f2be24 100644 --- a/doc/html/search/all_9.js +++ b/doc/html/search/all_9.js @@ -1,4 +1,4 @@ var searchData= [ - ['y_148',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]] + ['w_0',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]] ]; diff --git a/doc/html/search/all_a.js b/doc/html/search/all_a.js new file mode 100644 index 0000000..97fbc17 --- /dev/null +++ b/doc/html/search/all_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['x_0',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]] +]; diff --git a/doc/html/search/all_b.js b/doc/html/search/all_b.js new file mode 100644 index 0000000..85e5cc5 --- /dev/null +++ b/doc/html/search/all_b.js @@ -0,0 +1,5 @@ +var searchData= +[ + ['y_0',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]], + ['yuv_20image_20format_20notes_1',['YUV Image Format Notes',['../group___turbo_j_p_e_g.html#autotoc_md0',1,'']]] +]; diff --git a/doc/html/search/classes_0.html b/doc/html/search/classes_0.html deleted file mode 100644 index 7e0afc8..0000000 --- a/doc/html/search/classes_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/classes_0.js b/doc/html/search/classes_0.js index ff3fb9a..dfd2e2a 100644 --- a/doc/html/search/classes_0.js +++ b/doc/html/search/classes_0.js @@ -1,6 +1,6 @@ var searchData= [ - ['tjregion_149',['tjregion',['../structtjregion.html',1,'']]], - ['tjscalingfactor_150',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]], - ['tjtransform_151',['tjtransform',['../structtjtransform.html',1,'']]] + ['tjregion_0',['tjregion',['../structtjregion.html',1,'']]], + ['tjscalingfactor_1',['tjscalingfactor',['../structtjscalingfactor.html',1,'']]], + ['tjtransform_2',['tjtransform',['../structtjtransform.html',1,'']]] ]; diff --git a/doc/html/search/close.svg b/doc/html/search/close.svg index a933eea..337d6cc 100644 --- a/doc/html/search/close.svg +++ b/doc/html/search/close.svg @@ -1,27 +1,14 @@ + - - - - image/svg+xml - - - - - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/enums_0.js b/doc/html/search/enums_0.js index 2f372f6..dc8e9e7 100644 --- a/doc/html/search/enums_0.js +++ b/doc/html/search/enums_0.js @@ -1,10 +1,10 @@ var searchData= [ - ['tjcs_212',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]], - ['tjerr_213',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], - ['tjinit_214',['TJINIT',['../group___turbo_j_p_e_g.html#ga3850bbee1313e752e667b4eb08b1e086',1,'turbojpeg.h']]], - ['tjparam_215',['TJPARAM',['../group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82',1,'turbojpeg.h']]], - ['tjpf_216',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]], - ['tjsamp_217',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]], - ['tjxop_218',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]] + ['tjcs_0',['TJCS',['../group___turbo_j_p_e_g.html#ga4f83ad3368e0e29d1957be0efa7c3720',1,'turbojpeg.h']]], + ['tjerr_1',['TJERR',['../group___turbo_j_p_e_g.html#gafbc17cfa57d0d5d11fea35ac025950fe',1,'turbojpeg.h']]], + ['tjinit_2',['TJINIT',['../group___turbo_j_p_e_g.html#ga3850bbee1313e752e667b4eb08b1e086',1,'turbojpeg.h']]], + ['tjparam_3',['TJPARAM',['../group___turbo_j_p_e_g.html#gaa0f6be63ba78278299c9f5c12031fe82',1,'turbojpeg.h']]], + ['tjpf_4',['TJPF',['../group___turbo_j_p_e_g.html#gac916144e26c3817ac514e64ae5d12e2a',1,'turbojpeg.h']]], + ['tjsamp_5',['TJSAMP',['../group___turbo_j_p_e_g.html#ga1d047060ea80bb9820d540bb928e9074',1,'turbojpeg.h']]], + ['tjxop_6',['TJXOP',['../group___turbo_j_p_e_g.html#ga2de531af4e7e6c4f124908376b354866',1,'turbojpeg.h']]] ]; diff --git a/doc/html/search/enumvalues_0.html b/doc/html/search/enumvalues_0.html deleted file mode 100644 index c2cd472..0000000 --- a/doc/html/search/enumvalues_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/enumvalues_0.js b/doc/html/search/enumvalues_0.js index 4baa519..9f1a91c 100644 --- a/doc/html/search/enumvalues_0.js +++ b/doc/html/search/enumvalues_0.js @@ -1,65 +1,67 @@ var searchData= [ - ['tjcs_5fcmyk_219',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]], - ['tjcs_5fgray_220',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]], - ['tjcs_5frgb_221',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]], - ['tjcs_5fycbcr_222',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]], - ['tjcs_5fycck_223',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]], - ['tjerr_5ffatal_224',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], - ['tjerr_5fwarning_225',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], - ['tjinit_5fcompress_226',['TJINIT_COMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086aa45ac279e3dc6ffabc4b0f45864da796',1,'turbojpeg.h']]], - ['tjinit_5fdecompress_227',['TJINIT_DECOMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a4b8ca1ef700699b71350700bf95c2167',1,'turbojpeg.h']]], - ['tjinit_5ftransform_228',['TJINIT_TRANSFORM',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a8d58a2a4c45b3e0cd349746544a6e0c2',1,'turbojpeg.h']]], - ['tjparam_5farithmetic_229',['TJPARAM_ARITHMETIC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1c756757384308145602c040524aebf7',1,'turbojpeg.h']]], - ['tjparam_5fbottomup_230',['TJPARAM_BOTTOMUP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a924657172695ed6cb0b128219546fcce',1,'turbojpeg.h']]], - ['tjparam_5fcolorspace_231',['TJPARAM_COLORSPACE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a46a10d46309514907d0c39fcd86c324c',1,'turbojpeg.h']]], - ['tjparam_5fdensityunits_232',['TJPARAM_DENSITYUNITS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4c045981bd8a303521a401dbbe1df208',1,'turbojpeg.h']]], - ['tjparam_5ffastdct_233',['TJPARAM_FASTDCT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a6914692ac6ec5567787d592b7563f627',1,'turbojpeg.h']]], - ['tjparam_5ffastupsample_234',['TJPARAM_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0e051ac106f7b7402b690a5daf4869c0',1,'turbojpeg.h']]], - ['tjparam_5fjpegheight_235',['TJPARAM_JPEGHEIGHT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f',1,'turbojpeg.h']]], - ['tjparam_5fjpegwidth_236',['TJPARAM_JPEGWIDTH',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a02ab77fb294a0c9061a78cd424c82dd8',1,'turbojpeg.h']]], - ['tjparam_5flossless_237',['TJPARAM_LOSSLESS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a249f35f0770792b19f995e603bb17c6f',1,'turbojpeg.h']]], - ['tjparam_5flosslesspsv_238',['TJPARAM_LOSSLESSPSV',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abcc997d40e5bec84817c12b76ef84159',1,'turbojpeg.h']]], - ['tjparam_5flosslesspt_239',['TJPARAM_LOSSLESSPT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4a6c6f25764ecaf4231a36bff844e46a',1,'turbojpeg.h']]], - ['tjparam_5fnorealloc_240',['TJPARAM_NOREALLOC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b',1,'turbojpeg.h']]], - ['tjparam_5foptimize_241',['TJPARAM_OPTIMIZE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f0af9afc0b36443751f9ee82b760aa6',1,'turbojpeg.h']]], - ['tjparam_5fprecision_242',['TJPARAM_PRECISION',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8',1,'turbojpeg.h']]], - ['tjparam_5fprogressive_243',['TJPARAM_PROGRESSIVE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1716f242b3859905b4a317dae8cfb75f',1,'turbojpeg.h']]], - ['tjparam_5fquality_244',['TJPARAM_QUALITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0467e8792621f2d817dc2af563d3186c',1,'turbojpeg.h']]], - ['tjparam_5frestartblocks_245',['TJPARAM_RESTARTBLOCKS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a343c72883b7160f23f3ef46fc548a0ec',1,'turbojpeg.h']]], - ['tjparam_5frestartrows_246',['TJPARAM_RESTARTROWS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a714367585952fe5c863f0dba5bd37e5c',1,'turbojpeg.h']]], - ['tjparam_5fscanlimit_247',['TJPARAM_SCANLIMIT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac478910e20ecf61b914f9824d80f8167',1,'turbojpeg.h']]], - ['tjparam_5fstoponwarning_248',['TJPARAM_STOPONWARNING',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a555e2212079fa49b30bcd2879c6c8ddb',1,'turbojpeg.h']]], - ['tjparam_5fsubsamp_249',['TJPARAM_SUBSAMP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a',1,'turbojpeg.h']]], - ['tjparam_5fxdensity_250',['TJPARAM_XDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4de5c9d7cab5be806143a43c3b0e0877',1,'turbojpeg.h']]], - ['tjparam_5fydensity_251',['TJPARAM_YDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abda48f2df7eb9b88e2b7621efb017eba',1,'turbojpeg.h']]], - ['tjpf_5fabgr_252',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]], - ['tjpf_5fargb_253',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]], - ['tjpf_5fbgr_254',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]], - ['tjpf_5fbgra_255',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]], - ['tjpf_5fbgrx_256',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]], - ['tjpf_5fcmyk_257',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]], - ['tjpf_5fgray_258',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]], - ['tjpf_5frgb_259',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]], - ['tjpf_5frgba_260',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]], - ['tjpf_5frgbx_261',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]], - ['tjpf_5funknown_262',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]], - ['tjpf_5fxbgr_263',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]], - ['tjpf_5fxrgb_264',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]], - ['tjsamp_5f411_265',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]], - ['tjsamp_5f420_266',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]], - ['tjsamp_5f422_267',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]], - ['tjsamp_5f440_268',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]], - ['tjsamp_5f441_269',['TJSAMP_441',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3351696e1dd34a083a35b6be8b90122d',1,'turbojpeg.h']]], - ['tjsamp_5f444_270',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]], - ['tjsamp_5fgray_271',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]], - ['tjsamp_5funknown_272',['TJSAMP_UNKNOWN',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074ac124fa8f6cb41147e3d670dfbdfb7173',1,'turbojpeg.h']]], - ['tjxop_5fhflip_273',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]], - ['tjxop_5fnone_274',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]], - ['tjxop_5frot180_275',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]], - ['tjxop_5frot270_276',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]], - ['tjxop_5frot90_277',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]], - ['tjxop_5ftranspose_278',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]], - ['tjxop_5ftransverse_279',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]], - ['tjxop_5fvflip_280',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]] + ['tjcs_5fcmyk_0',['TJCS_CMYK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a6c8b636152ac8195b869587db315ee53',1,'turbojpeg.h']]], + ['tjcs_5fgray_1',['TJCS_GRAY',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720ab3e7d6a87f695e45b81c1b5262b5a50a',1,'turbojpeg.h']]], + ['tjcs_5frgb_2',['TJCS_RGB',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a677cb7ccb85c4038ac41964a2e09e555',1,'turbojpeg.h']]], + ['tjcs_5fycbcr_3',['TJCS_YCbCr',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a7389b8f65bb387ffedce3efd0d78ec75',1,'turbojpeg.h']]], + ['tjcs_5fycck_4',['TJCS_YCCK',['../group___turbo_j_p_e_g.html#gga4f83ad3368e0e29d1957be0efa7c3720a53839e0fe867b76b58d16b0a1a7c598e',1,'turbojpeg.h']]], + ['tjerr_5ffatal_5',['TJERR_FATAL',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950feafc9cceeada13122b09e4851e3788039a',1,'turbojpeg.h']]], + ['tjerr_5fwarning_6',['TJERR_WARNING',['../group___turbo_j_p_e_g.html#ggafbc17cfa57d0d5d11fea35ac025950fea342dd6e2aedb47bb257b4e7568329b59',1,'turbojpeg.h']]], + ['tjinit_5fcompress_7',['TJINIT_COMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086aa45ac279e3dc6ffabc4b0f45864da796',1,'turbojpeg.h']]], + ['tjinit_5fdecompress_8',['TJINIT_DECOMPRESS',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a4b8ca1ef700699b71350700bf95c2167',1,'turbojpeg.h']]], + ['tjinit_5ftransform_9',['TJINIT_TRANSFORM',['../group___turbo_j_p_e_g.html#gga3850bbee1313e752e667b4eb08b1e086a8d58a2a4c45b3e0cd349746544a6e0c2',1,'turbojpeg.h']]], + ['tjparam_5farithmetic_10',['TJPARAM_ARITHMETIC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1c756757384308145602c040524aebf7',1,'turbojpeg.h']]], + ['tjparam_5fbottomup_11',['TJPARAM_BOTTOMUP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a924657172695ed6cb0b128219546fcce',1,'turbojpeg.h']]], + ['tjparam_5fcolorspace_12',['TJPARAM_COLORSPACE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a46a10d46309514907d0c39fcd86c324c',1,'turbojpeg.h']]], + ['tjparam_5fdensityunits_13',['TJPARAM_DENSITYUNITS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4c045981bd8a303521a401dbbe1df208',1,'turbojpeg.h']]], + ['tjparam_5ffastdct_14',['TJPARAM_FASTDCT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a6914692ac6ec5567787d592b7563f627',1,'turbojpeg.h']]], + ['tjparam_5ffastupsample_15',['TJPARAM_FASTUPSAMPLE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0e051ac106f7b7402b690a5daf4869c0',1,'turbojpeg.h']]], + ['tjparam_5fjpegheight_16',['TJPARAM_JPEGHEIGHT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f76673be73f2b659440a9572a65a95f',1,'turbojpeg.h']]], + ['tjparam_5fjpegwidth_17',['TJPARAM_JPEGWIDTH',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a02ab77fb294a0c9061a78cd424c82dd8',1,'turbojpeg.h']]], + ['tjparam_5flossless_18',['TJPARAM_LOSSLESS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a249f35f0770792b19f995e603bb17c6f',1,'turbojpeg.h']]], + ['tjparam_5flosslesspsv_19',['TJPARAM_LOSSLESSPSV',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abcc997d40e5bec84817c12b76ef84159',1,'turbojpeg.h']]], + ['tjparam_5flosslesspt_20',['TJPARAM_LOSSLESSPT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4a6c6f25764ecaf4231a36bff844e46a',1,'turbojpeg.h']]], + ['tjparam_5fmaxmemory_21',['TJPARAM_MAXMEMORY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0de0a8281da45d1fc984edc8918f7dd2',1,'turbojpeg.h']]], + ['tjparam_5fmaxpixels_22',['TJPARAM_MAXPIXELS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac4e95dd2ecd766854feee579406eae68',1,'turbojpeg.h']]], + ['tjparam_5fnorealloc_23',['TJPARAM_NOREALLOC',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ae64ffb358bc7b194fd48e0f27750b29b',1,'turbojpeg.h']]], + ['tjparam_5foptimize_24',['TJPARAM_OPTIMIZE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a8f0af9afc0b36443751f9ee82b760aa6',1,'turbojpeg.h']]], + ['tjparam_5fprecision_25',['TJPARAM_PRECISION',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a781db82741934e8cd008d308597c59d8',1,'turbojpeg.h']]], + ['tjparam_5fprogressive_26',['TJPARAM_PROGRESSIVE',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a1716f242b3859905b4a317dae8cfb75f',1,'turbojpeg.h']]], + ['tjparam_5fquality_27',['TJPARAM_QUALITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a0467e8792621f2d817dc2af563d3186c',1,'turbojpeg.h']]], + ['tjparam_5frestartblocks_28',['TJPARAM_RESTARTBLOCKS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a343c72883b7160f23f3ef46fc548a0ec',1,'turbojpeg.h']]], + ['tjparam_5frestartrows_29',['TJPARAM_RESTARTROWS',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a714367585952fe5c863f0dba5bd37e5c',1,'turbojpeg.h']]], + ['tjparam_5fscanlimit_30',['TJPARAM_SCANLIMIT',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82ac478910e20ecf61b914f9824d80f8167',1,'turbojpeg.h']]], + ['tjparam_5fstoponwarning_31',['TJPARAM_STOPONWARNING',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a555e2212079fa49b30bcd2879c6c8ddb',1,'turbojpeg.h']]], + ['tjparam_5fsubsamp_32',['TJPARAM_SUBSAMP',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a2a3494a8215d3de4fdbaeb2ba6f6b03a',1,'turbojpeg.h']]], + ['tjparam_5fxdensity_33',['TJPARAM_XDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82a4de5c9d7cab5be806143a43c3b0e0877',1,'turbojpeg.h']]], + ['tjparam_5fydensity_34',['TJPARAM_YDENSITY',['../group___turbo_j_p_e_g.html#ggaa0f6be63ba78278299c9f5c12031fe82abda48f2df7eb9b88e2b7621efb017eba',1,'turbojpeg.h']]], + ['tjpf_5fabgr_35',['TJPF_ABGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa1ba1a7f1631dbeaa49a0a85fc4a40081',1,'turbojpeg.h']]], + ['tjpf_5fargb_36',['TJPF_ARGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aae8f846ed9d9de99b6e1dfe448848765c',1,'turbojpeg.h']]], + ['tjpf_5fbgr_37',['TJPF_BGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aab10624437fb8ef495a0b153e65749839',1,'turbojpeg.h']]], + ['tjpf_5fbgra_38',['TJPF_BGRA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aac037ff1845cf9b74bb81a3659c2b9fb4',1,'turbojpeg.h']]], + ['tjpf_5fbgrx_39',['TJPF_BGRX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa2a1fbf569ca79897eae886e3376ca4c8',1,'turbojpeg.h']]], + ['tjpf_5fcmyk_40',['TJPF_CMYK',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7f5100ec44c91994e243f1cf55553f8b',1,'turbojpeg.h']]], + ['tjpf_5fgray_41',['TJPF_GRAY',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa5431b54b015337705f13118073711a1a',1,'turbojpeg.h']]], + ['tjpf_5frgb_42',['TJPF_RGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa7ce93230bff449518ce387c17e6ed37c',1,'turbojpeg.h']]], + ['tjpf_5frgba_43',['TJPF_RGBA',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa88d2e88fab67f6503cf972e14851cc12',1,'turbojpeg.h']]], + ['tjpf_5frgbx_44',['TJPF_RGBX',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa83973bebb7e2dc6fa8bae89ff3f42e01',1,'turbojpeg.h']]], + ['tjpf_5funknown_45',['TJPF_UNKNOWN',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aa84c1a6cead7952998e2fb895844a21ed',1,'turbojpeg.h']]], + ['tjpf_5fxbgr_46',['TJPF_XBGR',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aaf6603b27147de47e212e75dac027b2af',1,'turbojpeg.h']]], + ['tjpf_5fxrgb_47',['TJPF_XRGB',['../group___turbo_j_p_e_g.html#ggac916144e26c3817ac514e64ae5d12e2aadae996905efcfa3b42a0bb3bea7f9d84',1,'turbojpeg.h']]], + ['tjsamp_5f411_48',['TJSAMP_411',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a28ec62575e5ea295c3fde3001dc628e2',1,'turbojpeg.h']]], + ['tjsamp_5f420_49',['TJSAMP_420',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a63085dbf683cfe39e513cdb6343e3737',1,'turbojpeg.h']]], + ['tjsamp_5f422_50',['TJSAMP_422',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a136130902cc578f11f32429b59368404',1,'turbojpeg.h']]], + ['tjsamp_5f440_51',['TJSAMP_440',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074accf740e6f3aa6ba20ba922cad13cb974',1,'turbojpeg.h']]], + ['tjsamp_5f441_52',['TJSAMP_441',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3351696e1dd34a083a35b6be8b90122d',1,'turbojpeg.h']]], + ['tjsamp_5f444_53',['TJSAMP_444',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074afb8da4f44197837bdec0a4f593dacae3',1,'turbojpeg.h']]], + ['tjsamp_5fgray_54',['TJSAMP_GRAY',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074a3f1c9504842ddc7a48d0f690754b6248',1,'turbojpeg.h']]], + ['tjsamp_5funknown_55',['TJSAMP_UNKNOWN',['../group___turbo_j_p_e_g.html#gga1d047060ea80bb9820d540bb928e9074ac124fa8f6cb41147e3d670dfbdfb7173',1,'turbojpeg.h']]], + ['tjxop_5fhflip_56',['TJXOP_HFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aa0df69776caa30f0fa28e26332d311ce',1,'turbojpeg.h']]], + ['tjxop_5fnone_57',['TJXOP_NONE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866aad88c0366cd3f7d0eac9d7a3fa1c2c27',1,'turbojpeg.h']]], + ['tjxop_5frot180_58',['TJXOP_ROT180',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a140952eb8dd0300accfcc22726d69692',1,'turbojpeg.h']]], + ['tjxop_5frot270_59',['TJXOP_ROT270',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a3064ee5dfb7f032df332818587567a08',1,'turbojpeg.h']]], + ['tjxop_5frot90_60',['TJXOP_ROT90',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a43b2bbb23bc4bd548422d43fbe9af128',1,'turbojpeg.h']]], + ['tjxop_5ftranspose_61',['TJXOP_TRANSPOSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a31060aed199f886afdd417f80499c32d',1,'turbojpeg.h']]], + ['tjxop_5ftransverse_62',['TJXOP_TRANSVERSE',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866af3b14d488aea6ece9e5b3df73a74d6a4',1,'turbojpeg.h']]], + ['tjxop_5fvflip_63',['TJXOP_VFLIP',['../group___turbo_j_p_e_g.html#gga2de531af4e7e6c4f124908376b354866a324eddfbec53b7e691f61e56929d0d5d',1,'turbojpeg.h']]] ]; diff --git a/doc/html/search/functions_0.html b/doc/html/search/functions_0.html deleted file mode 100644 index f04535a..0000000 --- a/doc/html/search/functions_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/functions_0.js b/doc/html/search/functions_0.js index 18f7e3f..87d6313 100644 --- a/doc/html/search/functions_0.js +++ b/doc/html/search/functions_0.js @@ -1,41 +1,41 @@ var searchData= [ - ['tj3alloc_152',['tj3Alloc',['../group___turbo_j_p_e_g.html#gab40a0b231122f536e503e3394569a68d',1,'turbojpeg.h']]], - ['tj3compress12_153',['tj3Compress12',['../group___turbo_j_p_e_g.html#ga9a1968c384ec7abb6122830253ebf570',1,'turbojpeg.h']]], - ['tj3compress16_154',['tj3Compress16',['../group___turbo_j_p_e_g.html#ga77901b71d0471784f318ada31ff4e7bd',1,'turbojpeg.h']]], - ['tj3compress8_155',['tj3Compress8',['../group___turbo_j_p_e_g.html#ga2cc418a2dab709ad7f30f5b25905f138',1,'turbojpeg.h']]], - ['tj3compressfromyuv8_156',['tj3CompressFromYUV8',['../group___turbo_j_p_e_g.html#ga041c870d9c669eb3f385c78f4346c43f',1,'turbojpeg.h']]], - ['tj3compressfromyuvplanes8_157',['tj3CompressFromYUVPlanes8',['../group___turbo_j_p_e_g.html#gac9f5ace3e73805b476c95dda9f8d0cd0',1,'turbojpeg.h']]], - ['tj3decodeyuv8_158',['tj3DecodeYUV8',['../group___turbo_j_p_e_g.html#gaa1eb574f38b1c1de43a6c7aafcf68d8c',1,'turbojpeg.h']]], - ['tj3decodeyuvplanes8_159',['tj3DecodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gad366f1915f82c1ad4e7e37ebe073ca89',1,'turbojpeg.h']]], - ['tj3decompress12_160',['tj3Decompress12',['../group___turbo_j_p_e_g.html#ga39b848f01781ad74a5b3941c012b6199',1,'turbojpeg.h']]], - ['tj3decompress16_161',['tj3Decompress16',['../group___turbo_j_p_e_g.html#gaa074e63f9beb0b3ff42b833a4049df6e',1,'turbojpeg.h']]], - ['tj3decompress8_162',['tj3Decompress8',['../group___turbo_j_p_e_g.html#ga1169c7c1a26ec18c9e6122cb8ae64013',1,'turbojpeg.h']]], - ['tj3decompressheader_163',['tj3DecompressHeader',['../group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1',1,'turbojpeg.h']]], - ['tj3decompresstoyuv8_164',['tj3DecompressToYUV8',['../group___turbo_j_p_e_g.html#ga1e6bf6a19fec3f9fa7534348879d8320',1,'turbojpeg.h']]], - ['tj3decompresstoyuvplanes8_165',['tj3DecompressToYUVPlanes8',['../group___turbo_j_p_e_g.html#ga934373482dbbf257f2280505b6ff4fb5',1,'turbojpeg.h']]], - ['tj3destroy_166',['tj3Destroy',['../group___turbo_j_p_e_g.html#ga53fbadf4560e95a65b8f5ab81703fe82',1,'turbojpeg.h']]], - ['tj3encodeyuv8_167',['tj3EncodeYUV8',['../group___turbo_j_p_e_g.html#ga2a8d50f130bde10f0a04030f8cc59936',1,'turbojpeg.h']]], - ['tj3encodeyuvplanes8_168',['tj3EncodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gae2e9df38790e9bddc249d04cb158a4cf',1,'turbojpeg.h']]], - ['tj3free_169',['tj3Free',['../group___turbo_j_p_e_g.html#gaddb84fb6c81769e9faa0f5a63b296606',1,'turbojpeg.h']]], - ['tj3get_170',['tj3Get',['../group___turbo_j_p_e_g.html#ga34af9ba3183bdf0ec7c8f47bb9a4c84f',1,'turbojpeg.h']]], - ['tj3geterrorcode_171',['tj3GetErrorCode',['../group___turbo_j_p_e_g.html#gab8c8279f1415fe425ff30dbbc56013bd',1,'turbojpeg.h']]], - ['tj3geterrorstr_172',['tj3GetErrorStr',['../group___turbo_j_p_e_g.html#gaf2aab0e6dbb3edc57646b0fec25e8bb2',1,'turbojpeg.h']]], - ['tj3getscalingfactors_173',['tj3GetScalingFactors',['../group___turbo_j_p_e_g.html#ga74397f8e0587d4233182c72f085aaf04',1,'turbojpeg.h']]], - ['tj3init_174',['tj3Init',['../group___turbo_j_p_e_g.html#ga69c09d39f97ec30250ad3605ace7e5df',1,'turbojpeg.h']]], - ['tj3jpegbufsize_175',['tj3JPEGBufSize',['../group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4',1,'turbojpeg.h']]], - ['tj3loadimage12_176',['tj3LoadImage12',['../group___turbo_j_p_e_g.html#ga1f03c26892a26d4ce077ed6a4ac40e8f',1,'turbojpeg.h']]], - ['tj3loadimage16_177',['tj3LoadImage16',['../group___turbo_j_p_e_g.html#ga638aeba63e0ccb89d472fdbf34224cfc',1,'turbojpeg.h']]], - ['tj3loadimage8_178',['tj3LoadImage8',['../group___turbo_j_p_e_g.html#ga565aaae7be3f8ca9099b56655c893251',1,'turbojpeg.h']]], - ['tj3saveimage12_179',['tj3SaveImage12',['../group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90',1,'turbojpeg.h']]], - ['tj3saveimage16_180',['tj3SaveImage16',['../group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71',1,'turbojpeg.h']]], - ['tj3saveimage8_181',['tj3SaveImage8',['../group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722',1,'turbojpeg.h']]], - ['tj3set_182',['tj3Set',['../group___turbo_j_p_e_g.html#gaddf92640bfee3e8622218c713e77e7db',1,'turbojpeg.h']]], - ['tj3setcroppingregion_183',['tj3SetCroppingRegion',['../group___turbo_j_p_e_g.html#gaa49c7bd4c9431667a043cfc93388ba1c',1,'turbojpeg.h']]], - ['tj3setscalingfactor_184',['tj3SetScalingFactor',['../group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75',1,'turbojpeg.h']]], - ['tj3transform_185',['tj3Transform',['../group___turbo_j_p_e_g.html#gaff23ba1dcabed456794b844791613920',1,'turbojpeg.h']]], - ['tj3yuvbufsize_186',['tj3YUVBufSize',['../group___turbo_j_p_e_g.html#gaaebaa16973a0f550a66eca5765ed0546',1,'turbojpeg.h']]], - ['tj3yuvplaneheight_187',['tj3YUVPlaneHeight',['../group___turbo_j_p_e_g.html#ga969767ec8180cc3edd99cf507f87299b',1,'turbojpeg.h']]], - ['tj3yuvplanesize_188',['tj3YUVPlaneSize',['../group___turbo_j_p_e_g.html#gacc19d265edce76b46146f59579f9438d',1,'turbojpeg.h']]], - ['tj3yuvplanewidth_189',['tj3YUVPlaneWidth',['../group___turbo_j_p_e_g.html#gac99d1933ede1d59fcada9a826e88eb2d',1,'turbojpeg.h']]] + ['tj3alloc_0',['tj3Alloc',['../group___turbo_j_p_e_g.html#ga1a2c96d8b47530b6e6050ba6f10b7c57',1,'turbojpeg.h']]], + ['tj3compress12_1',['tj3Compress12',['../group___turbo_j_p_e_g.html#ga9a1968c384ec7abb6122830253ebf570',1,'turbojpeg.h']]], + ['tj3compress16_2',['tj3Compress16',['../group___turbo_j_p_e_g.html#ga77901b71d0471784f318ada31ff4e7bd',1,'turbojpeg.h']]], + ['tj3compress8_3',['tj3Compress8',['../group___turbo_j_p_e_g.html#ga2cc418a2dab709ad7f30f5b25905f138',1,'turbojpeg.h']]], + ['tj3compressfromyuv8_4',['tj3CompressFromYUV8',['../group___turbo_j_p_e_g.html#ga041c870d9c669eb3f385c78f4346c43f',1,'turbojpeg.h']]], + ['tj3compressfromyuvplanes8_5',['tj3CompressFromYUVPlanes8',['../group___turbo_j_p_e_g.html#gac9f5ace3e73805b476c95dda9f8d0cd0',1,'turbojpeg.h']]], + ['tj3decodeyuv8_6',['tj3DecodeYUV8',['../group___turbo_j_p_e_g.html#gaa1eb574f38b1c1de43a6c7aafcf68d8c',1,'turbojpeg.h']]], + ['tj3decodeyuvplanes8_7',['tj3DecodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gad366f1915f82c1ad4e7e37ebe073ca89',1,'turbojpeg.h']]], + ['tj3decompress12_8',['tj3Decompress12',['../group___turbo_j_p_e_g.html#ga39b848f01781ad74a5b3941c012b6199',1,'turbojpeg.h']]], + ['tj3decompress16_9',['tj3Decompress16',['../group___turbo_j_p_e_g.html#gaa074e63f9beb0b3ff42b833a4049df6e',1,'turbojpeg.h']]], + ['tj3decompress8_10',['tj3Decompress8',['../group___turbo_j_p_e_g.html#ga1169c7c1a26ec18c9e6122cb8ae64013',1,'turbojpeg.h']]], + ['tj3decompressheader_11',['tj3DecompressHeader',['../group___turbo_j_p_e_g.html#ga96d2c4b3432f9d88ad14758ae240b8d1',1,'turbojpeg.h']]], + ['tj3decompresstoyuv8_12',['tj3DecompressToYUV8',['../group___turbo_j_p_e_g.html#ga1e6bf6a19fec3f9fa7534348879d8320',1,'turbojpeg.h']]], + ['tj3decompresstoyuvplanes8_13',['tj3DecompressToYUVPlanes8',['../group___turbo_j_p_e_g.html#ga934373482dbbf257f2280505b6ff4fb5',1,'turbojpeg.h']]], + ['tj3destroy_14',['tj3Destroy',['../group___turbo_j_p_e_g.html#ga53fbadf4560e95a65b8f5ab81703fe82',1,'turbojpeg.h']]], + ['tj3encodeyuv8_15',['tj3EncodeYUV8',['../group___turbo_j_p_e_g.html#ga2a8d50f130bde10f0a04030f8cc59936',1,'turbojpeg.h']]], + ['tj3encodeyuvplanes8_16',['tj3EncodeYUVPlanes8',['../group___turbo_j_p_e_g.html#gae2e9df38790e9bddc249d04cb158a4cf',1,'turbojpeg.h']]], + ['tj3free_17',['tj3Free',['../group___turbo_j_p_e_g.html#gaddb84fb6c81769e9faa0f5a63b296606',1,'turbojpeg.h']]], + ['tj3get_18',['tj3Get',['../group___turbo_j_p_e_g.html#ga34af9ba3183bdf0ec7c8f47bb9a4c84f',1,'turbojpeg.h']]], + ['tj3geterrorcode_19',['tj3GetErrorCode',['../group___turbo_j_p_e_g.html#gab8c8279f1415fe425ff30dbbc56013bd',1,'turbojpeg.h']]], + ['tj3geterrorstr_20',['tj3GetErrorStr',['../group___turbo_j_p_e_g.html#ga5a23ad0776c5333cda0d7c6d826e9d29',1,'turbojpeg.h']]], + ['tj3getscalingfactors_21',['tj3GetScalingFactors',['../group___turbo_j_p_e_g.html#gaf9253e0c2e9f464142d389673da085fa',1,'turbojpeg.h']]], + ['tj3init_22',['tj3Init',['../group___turbo_j_p_e_g.html#ga69c09d39f97ec30250ad3605ace7e5df',1,'turbojpeg.h']]], + ['tj3jpegbufsize_23',['tj3JPEGBufSize',['../group___turbo_j_p_e_g.html#gac6285e58e35a35d871d7162ec5a929c4',1,'turbojpeg.h']]], + ['tj3loadimage12_24',['tj3LoadImage12',['../group___turbo_j_p_e_g.html#gaa1d3772cfdb53afa21aae3c606238d44',1,'turbojpeg.h']]], + ['tj3loadimage16_25',['tj3LoadImage16',['../group___turbo_j_p_e_g.html#gace4240b665dc47742cbb3b76b03dfd69',1,'turbojpeg.h']]], + ['tj3loadimage8_26',['tj3LoadImage8',['../group___turbo_j_p_e_g.html#ga884023536e70985616126a073f662001',1,'turbojpeg.h']]], + ['tj3saveimage12_27',['tj3SaveImage12',['../group___turbo_j_p_e_g.html#ga7c64b5106d04267a46aad85f9714ad90',1,'turbojpeg.h']]], + ['tj3saveimage16_28',['tj3SaveImage16',['../group___turbo_j_p_e_g.html#ga0fd87851f4266aca24bf4594dd0c0e71',1,'turbojpeg.h']]], + ['tj3saveimage8_29',['tj3SaveImage8',['../group___turbo_j_p_e_g.html#gaa4ec838988e469cc15618e4690cc8722',1,'turbojpeg.h']]], + ['tj3set_30',['tj3Set',['../group___turbo_j_p_e_g.html#gaddf92640bfee3e8622218c713e77e7db',1,'turbojpeg.h']]], + ['tj3setcroppingregion_31',['tj3SetCroppingRegion',['../group___turbo_j_p_e_g.html#gaa49c7bd4c9431667a043cfc93388ba1c',1,'turbojpeg.h']]], + ['tj3setscalingfactor_32',['tj3SetScalingFactor',['../group___turbo_j_p_e_g.html#ga89da17ee1e43ff423382cbc145803c75',1,'turbojpeg.h']]], + ['tj3transform_33',['tj3Transform',['../group___turbo_j_p_e_g.html#gaff23ba1dcabed456794b844791613920',1,'turbojpeg.h']]], + ['tj3yuvbufsize_34',['tj3YUVBufSize',['../group___turbo_j_p_e_g.html#gaaebaa16973a0f550a66eca5765ed0546',1,'turbojpeg.h']]], + ['tj3yuvplaneheight_35',['tj3YUVPlaneHeight',['../group___turbo_j_p_e_g.html#ga969767ec8180cc3edd99cf507f87299b',1,'turbojpeg.h']]], + ['tj3yuvplanesize_36',['tj3YUVPlaneSize',['../group___turbo_j_p_e_g.html#gacc19d265edce76b46146f59579f9438d',1,'turbojpeg.h']]], + ['tj3yuvplanewidth_37',['tj3YUVPlaneWidth',['../group___turbo_j_p_e_g.html#gac99d1933ede1d59fcada9a826e88eb2d',1,'turbojpeg.h']]] ]; diff --git a/doc/html/search/groups_0.html b/doc/html/search/groups_0.html deleted file mode 100644 index 5c10318..0000000 --- a/doc/html/search/groups_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/groups_0.js b/doc/html/search/groups_0.js index 97bded0..aba750b 100644 --- a/doc/html/search/groups_0.js +++ b/doc/html/search/groups_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['turbojpeg_281',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]] + ['turbojpeg_0',['TurboJPEG',['../group___turbo_j_p_e_g.html',1,'']]] ]; diff --git a/doc/html/search/mag.svg b/doc/html/search/mag.svg new file mode 100644 index 0000000..ffb6cf0 --- /dev/null +++ b/doc/html/search/mag.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/doc/html/search/mag_d.svg b/doc/html/search/mag_d.svg new file mode 100644 index 0000000..4122773 --- /dev/null +++ b/doc/html/search/mag_d.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/doc/html/search/mag_sel.svg b/doc/html/search/mag_sel.svg index 03626f6..553dba8 100644 --- a/doc/html/search/mag_sel.svg +++ b/doc/html/search/mag_sel.svg @@ -1,59 +1,17 @@ - + - - - - image/svg+xml - - - - - + > - + /> + /> diff --git a/doc/html/search/mag_seld.svg b/doc/html/search/mag_seld.svg new file mode 100644 index 0000000..c906f84 --- /dev/null +++ b/doc/html/search/mag_seld.svg @@ -0,0 +1,31 @@ + + + + + + + + + diff --git a/doc/html/search/nomatches.html b/doc/html/search/nomatches.html deleted file mode 100644 index 4377320..0000000 --- a/doc/html/search/nomatches.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - -
    -
    No Matches
    -
    - - diff --git a/doc/html/search/search.css b/doc/html/search/search.css index 933cf08..19f76f9 100644 --- a/doc/html/search/search.css +++ b/doc/html/search/search.css @@ -1,10 +1,33 @@ -/*---------------- Search Box */ +/*---------------- Search Box positioning */ + +#main-menu > li:last-child { + /* This
  • object is the parent of the search bar */ + display: flex; + justify-content: center; + align-items: center; + height: 36px; + margin-right: 1em; +} + +/*---------------- Search box styling */ + +.SRPage * { + font-weight: normal; + line-height: normal; +} + +dark-mode-toggle { + margin-left: 5px; + display: flex; + float: right; +} #MSearchBox { + display: inline-block; white-space : nowrap; - background: white; + background: var(--search-background-color); border-radius: 0.65em; - box-shadow: inset 0.5px 0.5px 3px 0px #555; + box-shadow: var(--search-box-shadow); z-index: 102; } @@ -17,28 +40,47 @@ #MSearchSelect { display: inline-block; vertical-align: middle; - height: 1.4em; - padding: 0 0 0 0.3em; - margin: 0; + width: 20px; + height: 19px; + background-image: var(--search-magnification-select-image); + margin: 0 0 0 0.3em; + padding: 0; +} + +#MSearchSelectExt { + display: inline-block; + vertical-align: middle; + width: 10px; + height: 19px; + background-image: var(--search-magnification-image); + margin: 0 0 0 0.5em; + padding: 0; } + #MSearchField { display: inline-block; vertical-align: middle; width: 7.5em; - height: 1.1em; + height: 19px; margin: 0 0.15em; padding: 0; line-height: 1em; border:none; - color: #909090; + color: var(--search-foreground-color); outline: none; - font-family: Arial, Verdana, sans-serif; + font-family: var(--font-family-search); -webkit-border-radius: 0px; border-radius: 0px; background: none; } +@media(hover: none) { + /* to avoid zooming on iOS */ + #MSearchField { + font-size: 16px; + } +} #MSearchBox .right { display: inline-block; @@ -59,23 +101,15 @@ } #MSearchCloseImg { - height: 1.4em; padding: 0.3em; margin: 0; } .MSearchBoxActive #MSearchField { - color: #000000; + color: var(--search-active-color); } -#main-menu > li:last-child { - /* This
  • object is the parent of the search bar */ - display: flex; - justify-content: center; - align-items: center; - height: 36px; - margin-right: 1em; -} + /*---------------- Search filter selection */ @@ -83,8 +117,8 @@ display: none; position: absolute; left: 0; top: 0; - border: 1px solid #90A5CE; - background-color: #F9FAFC; + border: 1px solid var(--search-filter-border-color); + background-color: var(--search-filter-background-color); z-index: 10001; padding-top: 4px; padding-bottom: 4px; @@ -97,7 +131,7 @@ } .SelectItem { - font: 8pt Arial, Verdana, sans-serif; + font: 8pt var(--font-family-search); padding-left: 2px; padding-right: 12px; border: 0px; @@ -105,7 +139,7 @@ span.SelectionMark { margin-right: 4px; - font-family: monospace; + font-family: var(--font-family-monospace); outline-style: none; text-decoration: none; } @@ -113,7 +147,7 @@ span.SelectionMark { a.SelectItem { display: block; outline-style: none; - color: #000000; + color: var(--search-filter-foreground-color); text-decoration: none; padding-left: 6px; padding-right: 12px; @@ -121,14 +155,14 @@ a.SelectItem { a.SelectItem:focus, a.SelectItem:active { - color: #000000; + color: var(--search-filter-foreground-color); outline-style: none; text-decoration: none; } a.SelectItem:hover { - color: #FFFFFF; - background-color: #3D578C; + color: var(--search-filter-highlight-text-color); + background-color: var(--search-filter-highlight-bg-color); outline-style: none; text-decoration: none; cursor: pointer; @@ -138,7 +172,7 @@ a.SelectItem:hover { /*---------------- Search results window */ iframe#MSearchResults { - width: 60ex; + /*width: 60ex;*/ height: 15em; } @@ -146,9 +180,12 @@ iframe#MSearchResults { display: none; position: absolute; left: 0; top: 0; - border: 1px solid #000; - background-color: #EEF1F7; + border: 1px solid var(--search-results-border-color); + background-color: var(--search-results-background-color); z-index:10000; + width: 300px; + height: 400px; + overflow: auto; } /* ----------------------------------- */ @@ -156,7 +193,6 @@ iframe#MSearchResults { #SRIndex { clear:both; - padding-bottom: 15px; } .SREntry { @@ -169,8 +205,9 @@ iframe#MSearchResults { padding: 1px 5px; } -body.SRPage { +div.SRPage { margin: 5px 2px; + background-color: var(--search-results-background-color); } .SRChildren { @@ -182,17 +219,18 @@ body.SRPage { } .SRSymbol { - font-weight: bold; - color: #425E97; - font-family: Arial, Verdana, sans-serif; + font-weight: bold; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); text-decoration: none; outline: none; } a.SRScope { display: block; - color: #425E97; - font-family: Arial, Verdana, sans-serif; + color: var(--search-results-foreground-color); + font-family: var(--font-family-search); + font-size: 8pt; text-decoration: none; outline: none; } @@ -204,33 +242,31 @@ a.SRScope:focus, a.SRScope:active { span.SRScope { padding-left: 4px; + font-family: var(--font-family-search); } .SRPage .SRStatus { padding: 2px 5px; font-size: 8pt; font-style: italic; + font-family: var(--font-family-search); } .SRResult { display: none; } -DIV.searchresults { +div.searchresults { margin-left: 10px; margin-right: 10px; } /*---------------- External search page results */ -.searchresult { - background-color: #F0F3F8; -} - .pages b { color: white; padding: 5px 5px 3px 5px; - background-image: url("../tab_a.png"); + background-image: var(--nav-gradient-active-image-parent); background-repeat: repeat-x; text-shadow: 0 1px 1px #000000; } diff --git a/doc/html/search/search.js b/doc/html/search/search.js index 92b6094..6fd40c6 100644 --- a/doc/html/search/search.js +++ b/doc/html/search/search.js @@ -73,6 +73,8 @@ function getYPos(item) return y; } +var searchResults = new SearchResults("searchResults"); + /* A class handling everything associated with the search panel. Parameters: @@ -80,9 +82,10 @@ function getYPos(item) storing this instance. Is needed to be able to set timeouts. resultPath - path to use for external files */ -function SearchBox(name, resultsPath, inFrame, label) +function SearchBox(name, resultsPath, extension) { if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); } + if (!extension || extension == "") { extension = ".html"; } // ---------- Instance variables this.name = name; @@ -95,8 +98,7 @@ function SearchBox(name, resultsPath, inFrame, label) this.hideTimeout = 0; this.searchIndex = 0; this.searchActive = false; - this.insideFrame = inFrame; - this.searchLabel = label; + this.extension = extension; // ----------- DOM Elements @@ -134,30 +136,14 @@ function SearchBox(name, resultsPath, inFrame, label) var searchSelectWindow = this.DOMSearchSelectWindow(); var searchField = this.DOMSearchSelect(); - if (this.insideFrame) - { - var left = getXPos(searchField); - var top = getYPos(searchField); - left += searchField.offsetWidth + 6; - top += searchField.offsetHeight; - - // show search selection popup - searchSelectWindow.style.display='block'; - left -= searchSelectWindow.offsetWidth; - searchSelectWindow.style.left = left + 'px'; - searchSelectWindow.style.top = top + 'px'; - } - else - { - var left = getXPos(searchField); - var top = getYPos(searchField); - top += searchField.offsetHeight; + var left = getXPos(searchField); + var top = getYPos(searchField); + top += searchField.offsetHeight; - // show search selection popup - searchSelectWindow.style.display='block'; - searchSelectWindow.style.left = left + 'px'; - searchSelectWindow.style.top = top + 'px'; - } + // show search selection popup + searchSelectWindow.style.display='block'; + searchSelectWindow.style.left = left + 'px'; + searchSelectWindow.style.top = top + 'px'; // stop selection hide timer if (this.hideTimeout) @@ -170,7 +156,7 @@ function SearchBox(name, resultsPath, inFrame, label) this.OnSearchSelectHide = function() { - this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()", + this.hideTimeout = setTimeout(this.CloseSelectionWindow.bind(this), this.closeSelectionTimeout); } @@ -203,11 +189,13 @@ function SearchBox(name, resultsPath, inFrame, label) } else { - window.frames.MSearchResults.postMessage("take_focus", "*"); + var elem = searchResults.NavNext(0); + if (elem) elem.focus(); } } else if (e.keyCode==27) // Escape out of the search field { + e.stopPropagation(); this.DOMSearchField().blur(); this.DOMPopupSearchResultsWindow().style.display = 'none'; this.DOMSearchClose().style.display = 'none'; @@ -224,7 +212,7 @@ function SearchBox(name, resultsPath, inFrame, label) if (searchValue != "") // non-empty search { // set timer for search update - this.keyTimeout = setTimeout(this.name + '.Search()', + this.keyTimeout = setTimeout(this.Search.bind(this), this.keyTimeoutLength); } else // empty search field @@ -302,6 +290,7 @@ function SearchBox(name, resultsPath, inFrame, label) } else if (e.keyCode==13 || e.keyCode==27) { + e.stopPropagation(); this.OnSelectItem(this.searchIndex); this.CloseSelectionWindow(); this.DOMSearchField().focus(); @@ -339,55 +328,70 @@ function SearchBox(name, resultsPath, inFrame, label) idxChar = searchValue.substr(0, 2); } - var resultsPage; - var resultsPageWithSearch; - var hasResultsPage; + var jsFile; var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar); if (idx!=-1) { var hexCode=idx.toString(16); - resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; - resultsPageWithSearch = resultsPage+'?'+escape(searchValue); - hasResultsPage = true; + jsFile = this.resultsPath + indexSectionNames[this.searchIndex] + '_' + hexCode + '.js'; } - else // nothing available for this search term - { - resultsPage = this.resultsPath + '/nomatches.html'; - resultsPageWithSearch = resultsPage; - hasResultsPage = false; + + var loadJS = function(url, impl, loc){ + var scriptTag = document.createElement('script'); + scriptTag.src = url; + scriptTag.onload = impl; + scriptTag.onreadystatechange = impl; + loc.appendChild(scriptTag); } - window.frames.MSearchResults.location = resultsPageWithSearch; var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + var domSearchBox = this.DOMSearchBox(); + var domPopupSearchResults = this.DOMPopupSearchResults(); + var domSearchClose = this.DOMSearchClose(); + var resultsPath = this.resultsPath; + + var handleResults = function() { + document.getElementById("Loading").style.display="none"; + if (typeof searchData !== 'undefined') { + createResults(resultsPath); + document.getElementById("NoMatches").style.display="none"; + } + + if (idx!=-1) { + searchResults.Search(searchValue); + } else { // no file with search results => force empty search results + searchResults.Search('===='); + } - if (domPopupSearchResultsWindow.style.display!='block') - { - var domSearchBox = this.DOMSearchBox(); - this.DOMSearchClose().style.display = 'inline-block'; - if (this.insideFrame) - { - var domPopupSearchResults = this.DOMPopupSearchResults(); - domPopupSearchResultsWindow.style.position = 'relative'; - domPopupSearchResultsWindow.style.display = 'block'; - var width = document.body.clientWidth - 8; // the -8 is for IE :-( - domPopupSearchResultsWindow.style.width = width + 'px'; - domPopupSearchResults.style.width = width + 'px'; - } - else - { - var domPopupSearchResults = this.DOMPopupSearchResults(); - var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth; - var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1; - domPopupSearchResultsWindow.style.display = 'block'; - left -= domPopupSearchResults.offsetWidth; - domPopupSearchResultsWindow.style.top = top + 'px'; - domPopupSearchResultsWindow.style.left = left + 'px'; - } + if (domPopupSearchResultsWindow.style.display!='block') + { + domSearchClose.style.display = 'inline-block'; + var left = getXPos(domSearchBox) + 150; + var top = getYPos(domSearchBox) + 20; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + var maxWidth = document.body.clientWidth; + var maxHeight = document.body.clientHeight; + var width = 300; + if (left<10) left=10; + if (width+left+8>maxWidth) width=maxWidth-left-8; + var height = 400; + if (height+top+8>maxHeight) height=maxHeight-top-8; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResultsWindow.style.height = height + 'px'; + } + } + + if (jsFile) { + loadJS(jsFile, handleResults, this.DOMPopupSearchResultsWindow()); + } else { + handleResults(); } this.lastSearchValue = searchValue; - this.lastResultsPage = resultsPage; } // -------- Activation Functions @@ -401,22 +405,15 @@ function SearchBox(name, resultsPath, inFrame, label) ) { this.DOMSearchBox().className = 'MSearchBoxActive'; - - var searchField = this.DOMSearchField(); - - if (searchField.value == this.searchLabel) // clear "Search" term upon entry - { - searchField.value = ''; - this.searchActive = true; - } + this.searchActive = true; } else if (!isActive) // directly remove the panel { this.DOMSearchBox().className = 'MSearchBoxInactive'; - this.DOMSearchField().value = this.searchLabel; this.searchActive = false; this.lastSearchValue = '' this.lastResultsPage = ''; + this.DOMSearchField().value = ''; } } } @@ -439,12 +436,12 @@ function SearchResults(name) while (element && element!=parentElement) { - if (element.nodeName == 'DIV' && element.className == 'SRChildren') + if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren') { return element; } - if (element.nodeName == 'DIV' && element.hasChildNodes()) + if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes()) { element = element.firstChild; } @@ -645,7 +642,7 @@ function SearchResults(name) } else // return focus to search field { - parent.document.getElementById("MSearchField").focus(); + document.getElementById("MSearchField").focus(); } } else if (this.lastKey==40) // Down @@ -675,8 +672,9 @@ function SearchResults(name) } else if (this.lastKey==27) // Escape { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { @@ -718,8 +716,9 @@ function SearchResults(name) } else if (this.lastKey==27) // Escape { - parent.searchBox.CloseResultsWindow(); - parent.document.getElementById("MSearchField").focus(); + e.stopPropagation(); + searchBox.CloseResultsWindow(); + document.getElementById("MSearchField").focus(); } else if (this.lastKey==13) // Enter { @@ -742,9 +741,10 @@ function setClassAttr(elem,attr) elem.setAttribute('className',attr); } -function createResults() +function createResults(resultsPath) { var results = document.getElementById("SRResults"); + results.innerHTML = ''; for (var e=0; e - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/typedefs_0.js b/doc/html/search/typedefs_0.js index 968490f..a25259c 100644 --- a/doc/html/search/typedefs_0.js +++ b/doc/html/search/typedefs_0.js @@ -1,5 +1,5 @@ var searchData= [ - ['tjhandle_210',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]], - ['tjtransform_211',['tjtransform',['../group___turbo_j_p_e_g.html#ga504805ec0161f1b505397ca0118bf8fd',1,'turbojpeg.h']]] + ['tjhandle_0',['tjhandle',['../group___turbo_j_p_e_g.html#ga758d2634ecb4949de7815cba621f5763',1,'turbojpeg.h']]], + ['tjtransform_1',['tjtransform',['../group___turbo_j_p_e_g.html#ga504805ec0161f1b505397ca0118bf8fd',1,'turbojpeg.h']]] ]; diff --git a/doc/html/search/variables_0.html b/doc/html/search/variables_0.html deleted file mode 100644 index 2edd111..0000000 --- a/doc/html/search/variables_0.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_0.js b/doc/html/search/variables_0.js index 40a95a8..07cc58c 100644 --- a/doc/html/search/variables_0.js +++ b/doc/html/search/variables_0.js @@ -1,4 +1,4 @@ var searchData= [ - ['customfilter_190',['customFilter',['../structtjtransform.html#a0dc7697d59a7abe48afc629e96cbc1d2',1,'tjtransform']]] + ['customfilter_0',['customFilter',['../structtjtransform.html#a0dc7697d59a7abe48afc629e96cbc1d2',1,'tjtransform']]] ]; diff --git a/doc/html/search/variables_1.html b/doc/html/search/variables_1.html deleted file mode 100644 index 98b95a9..0000000 --- a/doc/html/search/variables_1.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_1.js b/doc/html/search/variables_1.js index 9113a24..cde1fd1 100644 --- a/doc/html/search/variables_1.js +++ b/doc/html/search/variables_1.js @@ -1,5 +1,5 @@ var searchData= [ - ['data_191',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]], - ['denom_192',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]] + ['data_0',['data',['../structtjtransform.html#a688fe8f1a8ecc12a538d9e561cf338e3',1,'tjtransform']]], + ['denom_1',['denom',['../structtjscalingfactor.html#aefbcdf3e9e62274b2d312c695f133ce3',1,'tjscalingfactor']]] ]; diff --git a/doc/html/search/variables_2.html b/doc/html/search/variables_2.html deleted file mode 100644 index 3e0c591..0000000 --- a/doc/html/search/variables_2.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_2.js b/doc/html/search/variables_2.js index a907b81..613c6d8 100644 --- a/doc/html/search/variables_2.js +++ b/doc/html/search/variables_2.js @@ -1,4 +1,4 @@ var searchData= [ - ['h_193',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]] + ['h_0',['h',['../structtjregion.html#aecefc45a26f4d8b60dd4d825c1710115',1,'tjregion']]] ]; diff --git a/doc/html/search/variables_3.html b/doc/html/search/variables_3.html deleted file mode 100644 index 7867da3..0000000 --- a/doc/html/search/variables_3.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_3.js b/doc/html/search/variables_3.js index 7b5a616..544402e 100644 --- a/doc/html/search/variables_3.js +++ b/doc/html/search/variables_3.js @@ -1,4 +1,4 @@ var searchData= [ - ['num_194',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]] + ['num_0',['num',['../structtjscalingfactor.html#a9b011e57f981ee23083e2c1aa5e640ec',1,'tjscalingfactor']]] ]; diff --git a/doc/html/search/variables_4.html b/doc/html/search/variables_4.html deleted file mode 100644 index 732dee2..0000000 --- a/doc/html/search/variables_4.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_4.js b/doc/html/search/variables_4.js index c2bfaa8..42a3475 100644 --- a/doc/html/search/variables_4.js +++ b/doc/html/search/variables_4.js @@ -1,5 +1,5 @@ var searchData= [ - ['op_195',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]], - ['options_196',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]] + ['op_0',['op',['../structtjtransform.html#a2525aab4ba6978a1c273f74fef50e498',1,'tjtransform']]], + ['options_1',['options',['../structtjtransform.html#ac0e74655baa4402209a21e1ae481c8f6',1,'tjtransform']]] ]; diff --git a/doc/html/search/variables_5.html b/doc/html/search/variables_5.html deleted file mode 100644 index ad9b545..0000000 --- a/doc/html/search/variables_5.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_5.js b/doc/html/search/variables_5.js index 0ae92ea..65fe61f 100644 --- a/doc/html/search/variables_5.js +++ b/doc/html/search/variables_5.js @@ -1,4 +1,4 @@ var searchData= [ - ['r_197',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]] + ['r_0',['r',['../structtjtransform.html#ac324e5e442abec8a961e5bf219db12cf',1,'tjtransform']]] ]; diff --git a/doc/html/search/variables_6.html b/doc/html/search/variables_6.html deleted file mode 100644 index 1cf2da1..0000000 --- a/doc/html/search/variables_6.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_6.js b/doc/html/search/variables_6.js index 2e7c0b3..91f6e8b 100644 --- a/doc/html/search/variables_6.js +++ b/doc/html/search/variables_6.js @@ -1,12 +1,12 @@ var searchData= [ - ['tjalphaoffset_198',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]], - ['tjblueoffset_199',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]], - ['tjgreenoffset_200',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]], - ['tjmcuheight_201',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]], - ['tjmcuwidth_202',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]], - ['tjpixelsize_203',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]], - ['tjredoffset_204',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]], - ['tjuncropped_205',['TJUNCROPPED',['../group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf',1,'turbojpeg.h']]], - ['tjunscaled_206',['TJUNSCALED',['../group___turbo_j_p_e_g.html#ga7880644a0849161ad20933536169ee19',1,'turbojpeg.h']]] + ['tjalphaoffset_0',['tjAlphaOffset',['../group___turbo_j_p_e_g.html#ga5af0ab065feefd526debf1e20c43e837',1,'turbojpeg.h']]], + ['tjblueoffset_1',['tjBlueOffset',['../group___turbo_j_p_e_g.html#ga84e2e35d3f08025f976ec1ec53693dea',1,'turbojpeg.h']]], + ['tjgreenoffset_2',['tjGreenOffset',['../group___turbo_j_p_e_g.html#ga82d6e35da441112a411da41923c0ba2f',1,'turbojpeg.h']]], + ['tjmcuheight_3',['tjMCUHeight',['../group___turbo_j_p_e_g.html#gabd247bb9fecb393eca57366feb8327bf',1,'turbojpeg.h']]], + ['tjmcuwidth_4',['tjMCUWidth',['../group___turbo_j_p_e_g.html#ga9e61e7cd47a15a173283ba94e781308c',1,'turbojpeg.h']]], + ['tjpixelsize_5',['tjPixelSize',['../group___turbo_j_p_e_g.html#gad77cf8fe5b2bfd3cb3f53098146abb4c',1,'turbojpeg.h']]], + ['tjredoffset_6',['tjRedOffset',['../group___turbo_j_p_e_g.html#gadd9b446742ac8a3923f7992c7988fea8',1,'turbojpeg.h']]], + ['tjuncropped_7',['TJUNCROPPED',['../group___turbo_j_p_e_g.html#ga6f192ad58a5a5802e145149d83c643bf',1,'turbojpeg.h']]], + ['tjunscaled_8',['TJUNSCALED',['../group___turbo_j_p_e_g.html#ga7880644a0849161ad20933536169ee19',1,'turbojpeg.h']]] ]; diff --git a/doc/html/search/variables_7.html b/doc/html/search/variables_7.html deleted file mode 100644 index ab2db0b..0000000 --- a/doc/html/search/variables_7.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_7.js b/doc/html/search/variables_7.js index c8c66b6..3f2be24 100644 --- a/doc/html/search/variables_7.js +++ b/doc/html/search/variables_7.js @@ -1,4 +1,4 @@ var searchData= [ - ['w_207',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]] + ['w_0',['w',['../structtjregion.html#ab6eb73ceef584fc23c8c8097926dce42',1,'tjregion']]] ]; diff --git a/doc/html/search/variables_8.html b/doc/html/search/variables_8.html deleted file mode 100644 index baec040..0000000 --- a/doc/html/search/variables_8.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_8.js b/doc/html/search/variables_8.js index 5f81e56..97fbc17 100644 --- a/doc/html/search/variables_8.js +++ b/doc/html/search/variables_8.js @@ -1,4 +1,4 @@ var searchData= [ - ['x_208',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]] + ['x_0',['x',['../structtjregion.html#a4b6a37a93997091b26a75831fa291ad9',1,'tjregion']]] ]; diff --git a/doc/html/search/variables_9.html b/doc/html/search/variables_9.html deleted file mode 100644 index df2fea0..0000000 --- a/doc/html/search/variables_9.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - -
    -
    Loading...
    -
    - -
    Searching...
    -
    No Matches
    - -
    - - diff --git a/doc/html/search/variables_9.js b/doc/html/search/variables_9.js index bb57e20..2f2b08e 100644 --- a/doc/html/search/variables_9.js +++ b/doc/html/search/variables_9.js @@ -1,4 +1,4 @@ var searchData= [ - ['y_209',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]] + ['y_0',['y',['../structtjregion.html#a7b3e0c24cfe87acc80e334cafdcf22c2',1,'tjregion']]] ]; diff --git a/doc/html/splitbard.png b/doc/html/splitbard.png new file mode 100644 index 0000000..8367416 Binary files /dev/null and b/doc/html/splitbard.png differ diff --git a/doc/html/structtjregion.html b/doc/html/structtjregion.html index e678584..fce4016 100644 --- a/doc/html/structtjregion.html +++ b/doc/html/structtjregion.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: tjregion Struct Reference @@ -20,10 +20,9 @@
    - - + @@ -31,21 +30,22 @@
    -
    TurboJPEG -  3 +
    +
    TurboJPEG 3.0.1
    - + +/* @license-end */ +
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    -
    tjregion Struct Reference
    +
    tjregion Struct Reference
    @@ -75,26 +81,26 @@ $(function() {

    #include <turbojpeg.h>

    - - - + + - - + + - - + + - - + +

    +

    Data Fields

    int x
     The left boundary of the cropping region. More...
    int x
     The left boundary of the cropping region.
     
    int y
     The upper boundary of the cropping region. More...
    int y
     The upper boundary of the cropping region.
     
    int w
     The width of the cropping region. More...
    int w
     The width of the cropping region.
     
    int h
     The height of the cropping region. More...
    int h
     The height of the cropping region.
     

    Detailed Description

    Cropping region.

    Field Documentation

    - -

    ◆ h

    + +

    ◆ h

    @@ -110,8 +116,8 @@ Data Fields
    - -

    ◆ w

    + +

    ◆ w

    @@ -127,8 +133,8 @@ Data Fields
    - -

    ◆ x

    + +

    ◆ x

    @@ -140,12 +146,12 @@ Data Fields

    The left boundary of the cropping region.

    -

    This must be evenly divisible by the MCU block width (see tjMCUWidth.)

    +

    For lossless transformation, this must be evenly divisible by the iMCU width (see tjMCUWidth) of the destination image. For decompression, this must be evenly divisible by the scaled iMCU width of the source image.

    - -

    ◆ y

    + +

    ◆ y

    @@ -157,17 +163,17 @@ Data Fields

    The upper boundary of the cropping region.

    -

    For lossless transformation, this must be evenly divisible by the MCU block height (see tjMCUHeight.)

    +

    For lossless transformation, this must be evenly divisible by the iMCU height (see tjMCUHeight) of the destination image.


    The documentation for this struct was generated from the following file:
      -
    • turbojpeg.h
    • +
    • turbojpeg.h
    diff --git a/doc/html/structtjscalingfactor.html b/doc/html/structtjscalingfactor.html index 818dfbd..464e542 100644 --- a/doc/html/structtjscalingfactor.html +++ b/doc/html/structtjscalingfactor.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: tjscalingfactor Struct Reference @@ -20,10 +20,9 @@
    - - + @@ -31,21 +30,22 @@
    -
    TurboJPEG -  3 +
    +
    TurboJPEG 3.0.1
    - + +/* @license-end */ +
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    -
    tjscalingfactor Struct Reference
    +
    tjscalingfactor Struct Reference
    @@ -75,20 +81,20 @@ $(function() {

    #include <turbojpeg.h>

    - - - + + - - + +

    +

    Data Fields

    int num
     Numerator. More...
    int num
     Numerator.
     
    int denom
     Denominator. More...
    int denom
     Denominator.
     

    Detailed Description

    Scaling factor.

    Field Documentation

    - -

    ◆ denom

    + +

    ◆ denom

    @@ -103,8 +109,8 @@ Data Fields
    - -

    ◆ num

    + +

    ◆ num

    @@ -120,12 +126,12 @@ Data Fields

    The documentation for this struct was generated from the following file:
      -
    • turbojpeg.h
    • +
    • turbojpeg.h
    diff --git a/doc/html/structtjtransform.html b/doc/html/structtjtransform.html index 9facd85..c562ead 100644 --- a/doc/html/structtjtransform.html +++ b/doc/html/structtjtransform.html @@ -1,9 +1,9 @@ - + - - + + TurboJPEG: tjtransform Struct Reference @@ -20,10 +20,9 @@
    - - + @@ -31,21 +30,22 @@
    -
    TurboJPEG -  3 +
    +
    TurboJPEG 3.0.1
    - + +/* @license-end */ +
    - +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    -
    -
    tjtransform Struct Reference
    +
    tjtransform Struct Reference
    @@ -75,29 +81,29 @@ $(function() {

    #include <turbojpeg.h>

    - - - + + - - + + - - + + - - + + - - + +

    +

    Data Fields

    tjregion r
     Cropping region. More...
    tjregion r
     Cropping region.
     
    int op
     One of the transform operations. More...
    int op
     One of the transform operations.
     
    int options
     The bitwise OR of one of more of the transform options. More...
    int options
     The bitwise OR of one of more of the transform options.
     
    void * data
     Arbitrary data that can be accessed within the body of the callback function. More...
    void * data
     Arbitrary data that can be accessed within the body of the callback function.
     
    int(* customFilter )(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentID, int transformID, struct tjtransform *transform)
     A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image. More...
    int(* customFilter )(short *coeffs, tjregion arrayRegion, tjregion planeRegion, int componentID, int transformID, struct tjtransform *transform)
     A callback function that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image.
     

    Detailed Description

    Lossless transform.

    Field Documentation

    - -

    ◆ customFilter

    + +

    ◆ customFilter

    @@ -112,7 +118,7 @@ Data Fields

    This allows for custom filters or other transformations to be applied in the frequency domain.

    Parameters
    - + @@ -125,8 +131,8 @@ Data Fields - -

    ◆ data

    + +

    ◆ data

    @@ -141,8 +147,8 @@ Data Fields
    - -

    ◆ op

    + +

    ◆ op

    @@ -157,8 +163,8 @@ Data Fields
    - -

    ◆ options

    + +

    ◆ options

    @@ -173,8 +179,8 @@ Data Fields
    - -

    ◆ r

    + +

    ◆ r

    @@ -190,12 +196,12 @@ Data Fields

    The documentation for this struct was generated from the following file:
      -
    • turbojpeg.h
    • +
    • turbojpeg.h
    diff --git a/doc/html/tab_ad.png b/doc/html/tab_ad.png new file mode 100644 index 0000000..e34850a Binary files /dev/null and b/doc/html/tab_ad.png differ diff --git a/doc/html/tab_bd.png b/doc/html/tab_bd.png new file mode 100644 index 0000000..91c2524 Binary files /dev/null and b/doc/html/tab_bd.png differ diff --git a/doc/html/tab_hd.png b/doc/html/tab_hd.png new file mode 100644 index 0000000..2489273 Binary files /dev/null and b/doc/html/tab_hd.png differ diff --git a/doc/html/tab_sd.png b/doc/html/tab_sd.png new file mode 100644 index 0000000..757a565 Binary files /dev/null and b/doc/html/tab_sd.png differ diff --git a/doc/html/tabs.css b/doc/html/tabs.css index 85a0cd5..71c8a47 100644 --- a/doc/html/tabs.css +++ b/doc/html/tabs.css @@ -1 +1 @@ -.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace!important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0!important;-webkit-border-radius:0;border-radius:0!important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px!important;-webkit-border-radius:5px;border-radius:5px!important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0!important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px!important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}} \ No newline at end of file +.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:var(--nav-menu-button-color);-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:var(--nav-gradient-image)}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:var(--font-family-nav);font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:var(--nav-text-normal-shadow);color:var(--nav-text-normal-color);outline:0}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:var(--nav-menu-toggle-color);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:var(--nav-menu-background-color)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:var(--nav-menu-background-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:var(--nav-gradient-image);line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:var(--nav-text-normal-color) transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:var(--nav-separator-image);background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox a:hover span.sub-arrow{border-color:var(--nav-text-hover-color) transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent var(--nav-menu-background-color) transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:var(--nav-menu-background-color);-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent var(--nav-menu-foreground-color);border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:var(--nav-menu-foreground-color);background-image:none;border:0 !important;color:var(--nav-menu-foreground-color);background-image:none}.sm-dox ul a:hover{background-image:var(--nav-gradient-active-image);background-repeat:repeat-x;color:var(--nav-text-hover-color);text-shadow:var(--nav-text-hover-shadow)}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent var(--nav-text-hover-color)}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:var(--nav-menu-background-color);height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent var(--nav-menu-foreground-color) transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:var(--nav-menu-foreground-color) transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:var(--nav-gradient-image)}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:var(--nav-menu-background-color)}} \ No newline at end of file diff --git a/doc/html/topics.html b/doc/html/topics.html new file mode 100644 index 0000000..5b4a88f --- /dev/null +++ b/doc/html/topics.html @@ -0,0 +1,87 @@ + + + + + + + +TurboJPEG: Topics + + + + + + + + + + +
    +
    +
    coeffspointer to an array of transformed DCT coefficients. (NOTE: this pointer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to another function or library should make a copy of them within the body of the callback.)
    coeffspointer to an array of transformed DCT coefficients. (NOTE: This pointer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to another function or library should make a copy of them within the body of the callback.)
    arrayRegiontjregion structure containing the width and height of the array pointed to by coeffs as well as its offset relative to the component plane. TurboJPEG implementations may choose to split each component plane into multiple DCT coefficient arrays and call the callback function once for each array.
    planeRegiontjregion structure containing the width and height of the component plane to which coeffs belongs
    componentIDID number of the component plane to which coeffs belongs. (Y, Cb, and Cr have, respectively, ID's of 0, 1, and 2 in typical JPEG images.)
    + + + + + +
    +
    TurboJPEG 3.0.1 +
    +
    +
    + + + + + + + +
    + +
    +
    + + +
    +
    +
    +
    +
    +
    Loading...
    +
    Searching...
    +
    No Matches
    +
    +
    +
    +
    + +
    +
    Topics
    +
    +
    +
    Here is a list of all topics with brief descriptions:
    + + +
     TurboJPEGTurboJPEG API
    +
    +
    + + + + diff --git a/doxygen-extra.css b/doxygen-extra.css index f1bd4c2..be54168 100644 --- a/doxygen-extra.css +++ b/doxygen-extra.css @@ -1,3 +1,7 @@ code { color: #4665A2; } + +th.markdownTableHeadNone { + color: black; +} diff --git a/doxygen.config b/doxygen.config index 1309a05..09e4489 100644 --- a/doxygen.config +++ b/doxygen.config @@ -1,5 +1,5 @@ PROJECT_NAME = TurboJPEG -PROJECT_NUMBER = 3 +PROJECT_NUMBER = 3.0.1 OUTPUT_DIRECTORY = doc/ USE_WINDOWS_ENCODING = NO OPTIMIZE_OUTPUT_FOR_C = YES diff --git a/example.c b/example.c index 4a82695..43d5f52 100644 --- a/example.c +++ b/example.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software. * Copyright (C) 1992-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2017, 2019, 2022-2023, D. R. Commander. + * Copyright (C) 2017, 2019, 2022-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -271,13 +271,6 @@ write_JPEG_file(char *filename, int quality, int data_precision) * destination module that can demand suspension of the compressor. * (If you don't know what that's for, you don't need it.) * - * If the compressor requires full-image buffers (for entropy-coding - * optimization or a multi-scan JPEG file), it will create temporary - * files for anything that doesn't fit within the maximum-memory setting. - * (Note that temp files are NOT needed if you use the default parameters.) - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.txt. - * * Scanlines MUST be supplied in top-to-bottom order if you want your JPEG * files to be compatible with everyone else's. If you cannot readily read * your data in that order, you'll need an intermediate array to hold the @@ -450,7 +443,7 @@ do_read_JPEG_file(struct jpeg_decompress_struct *cinfo, char *infilename, */ /* emit header for raw PPM format */ - fprintf(outfile, "P6\n%d %d\n%d\n", WIDTH, HEIGHT, + fprintf(outfile, "P6\n%u %u\n%d\n", cinfo->image_width, cinfo->image_height, cinfo->data_precision == 12 ? MAXJ12SAMPLE : MAXJSAMPLE); /* Step 4: set parameters for decompression */ @@ -562,10 +555,6 @@ do_read_JPEG_file(struct jpeg_decompress_struct *cinfo, char *infilename, * which is standardly top-to-bottom. If you must emit data bottom-to-top, * you can use one of the virtual arrays provided by the JPEG memory manager * to invert the data. See wrbmp.c for an example. - * - * As with compression, some operating modes may require temporary files. - * On some systems you may need to set up a signal handler to ensure that - * temporary files are deleted if the program is interrupted. See libjpeg.txt. */ diff --git a/fuzz/CMakeLists.txt b/fuzz/CMakeLists.txt index a08cb46..2ed3f72 100644 --- a/fuzz/CMakeLists.txt +++ b/fuzz/CMakeLists.txt @@ -30,15 +30,15 @@ add_executable(cjpeg_fuzzer${FUZZER_SUFFIX} cjpeg.cc ../cdjpeg.c ../rdbmp.c set_property(TARGET cjpeg_fuzzer${FUZZER_SUFFIX} PROPERTY COMPILE_FLAGS ${COMPILE_FLAGS}) target_link_libraries(cjpeg_fuzzer${FUZZER_SUFFIX} ${FUZZ_LIBRARY} jpeg-static) -install(TARGETS cjpeg_fuzzer${FUZZER_SUFFIX} RUNTIME DESTINATION - ${FUZZ_BINDIR}) +install(TARGETS cjpeg_fuzzer${FUZZER_SUFFIX} + RUNTIME DESTINATION ${FUZZ_BINDIR} COMPONENT bin) macro(add_fuzz_target target source_file) add_executable(${target}_fuzzer${FUZZER_SUFFIX} ${source_file}) target_link_libraries(${target}_fuzzer${FUZZER_SUFFIX} ${FUZZ_LIBRARY} turbojpeg-static) - install(TARGETS ${target}_fuzzer${FUZZER_SUFFIX} RUNTIME DESTINATION - ${FUZZ_BINDIR}) + install(TARGETS ${target}_fuzzer${FUZZER_SUFFIX} + RUNTIME DESTINATION ${FUZZ_BINDIR} COMPONENT bin) endmacro() add_fuzz_target(compress compress.cc) diff --git a/fuzz/build.sh b/fuzz/build.sh index d87cbdf..a856c5e 100644 --- a/fuzz/build.sh +++ b/fuzz/build.sh @@ -9,6 +9,10 @@ if [ $# -ge 1 ]; then FUZZER_SUFFIX="`echo $1 | sed 's/\./_/g'`" fi +if [ "$SANITIZER" = "memory" ]; then + export CFLAGS="$CFLAGS -DZERO_BUFFERS=1" +fi + cmake . -DCMAKE_BUILD_TYPE=RelWithDebInfo -DENABLE_STATIC=1 -DENABLE_SHARED=0 \ -DCMAKE_C_FLAGS_RELWITHDEBINFO="-g -DNDEBUG" \ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO="-g -DNDEBUG" -DCMAKE_INSTALL_PREFIX=$WORK \ diff --git a/fuzz/cjpeg.cc b/fuzz/cjpeg.cc index ee7b7ab..4d598f3 100644 --- a/fuzz/cjpeg.cc +++ b/fuzz/cjpeg.cc @@ -57,13 +57,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) (char *)"-targa", NULL }; int fd = -1; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_cjpeg_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) diff --git a/fuzz/compress.cc b/fuzz/compress.cc index f59f66d..995840b 100644 --- a/fuzz/compress.cc +++ b/fuzz/compress.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021, 2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021, 2023-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, TJSAMP_GRAY, 50 }, { TJPF_CMYK, TJSAMP_440, 40 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -96,7 +89,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp); if (tj3Get(handle, TJPARAM_NOREALLOC)) { - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; } else dstBuf = NULL; diff --git a/fuzz/compress12.cc b/fuzz/compress12.cc index 8a08299..63131c8 100644 --- a/fuzz/compress12.cc +++ b/fuzz/compress12.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021, 2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021, 2023-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -60,13 +60,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, TJSAMP_GRAY, 50 }, { TJPF_CMYK, TJSAMP_440, 40 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress12_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -96,7 +89,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp); if (tj3Get(handle, TJPARAM_NOREALLOC)) { - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; } else dstBuf = NULL; diff --git a/fuzz/compress12_lossless.cc b/fuzz/compress12_lossless.cc index 76a0a0d..fb94608 100644 --- a/fuzz/compress12_lossless.cc +++ b/fuzz/compress12_lossless.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -92,7 +85,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444); if (tj3Get(handle, TJPARAM_NOREALLOC)) { - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; } else dstBuf = NULL; diff --git a/fuzz/compress16_lossless.cc b/fuzz/compress16_lossless.cc index aa6037e..fe646bf 100644 --- a/fuzz/compress16_lossless.cc +++ b/fuzz/compress16_lossless.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -59,13 +59,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -92,7 +85,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444); if (tj3Get(handle, TJPARAM_NOREALLOC)) { - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; } else dstBuf = NULL; diff --git a/fuzz/compress_lossless.cc b/fuzz/compress_lossless.cc index 7c2bb79..34dbb89 100644 --- a/fuzz/compress_lossless.cc +++ b/fuzz/compress_lossless.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -58,13 +58,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_GRAY, 6, 3 }, { TJPF_CMYK, 7, 0 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -91,7 +84,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) maxBufSize = tj3JPEGBufSize(width, height, TJSAMP_444); if (tj3Get(handle, TJPARAM_NOREALLOC)) { - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; } else dstBuf = NULL; diff --git a/fuzz/compress_yuv.cc b/fuzz/compress_yuv.cc index 0b12e0c..af30b70 100644 --- a/fuzz/compress_yuv.cc +++ b/fuzz/compress_yuv.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -58,13 +58,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { TJPF_BGR, TJSAMP_GRAY, 60 }, { TJPF_GRAY, TJSAMP_GRAY, 50 } }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif snprintf(filename, FILENAME_MAX, "/tmp/libjpeg-turbo_compress_yuv_fuzz.XXXXXX"); if ((fd = mkstemp(filename)) < 0 || write(fd, data, size) < 0) @@ -94,7 +87,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) continue; maxBufSize = tj3JPEGBufSize(width, height, tests[ti].subsamp); - if ((dstBuf = (unsigned char *)malloc(maxBufSize)) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(maxBufSize)) == NULL) goto bailout; if ((yuvBuf = (unsigned char *)malloc(tj3YUVBufSize(width, 1, height, diff --git a/fuzz/decompress.cc b/fuzz/decompress.cc index eadc734..1b1aefd 100644 --- a/fuzz/decompress.cc +++ b/fuzz/decompress.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,13 +44,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_RGB, TJPF_BGRX, TJPF_GRAY, TJPF_CMYK }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_DECOMPRESS)) == NULL) goto bailout; @@ -102,7 +95,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) tj3SetCroppingRegion(handle, TJUNCROPPED); } - if ((dstBuf = malloc(w * h * tjPixelSize[pf] * sampleSize)) == NULL) + if ((dstBuf = tj3Alloc(w * h * tjPixelSize[pf] * sampleSize)) == NULL) goto bailout; if (precision == 8) { diff --git a/fuzz/decompress_yuv.cc b/fuzz/decompress_yuv.cc index 4e869df..3f371c6 100644 --- a/fuzz/decompress_yuv.cc +++ b/fuzz/decompress_yuv.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -44,13 +44,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) necessary to achieve full coverage. */ enum TJPF pixelFormats[NUMPF] = { TJPF_BGR, TJPF_XRGB, TJPF_GRAY }; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_DECOMPRESS)) == NULL) goto bailout; @@ -90,7 +83,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) tj3SetScalingFactor(handle, TJUNSCALED); } - if ((dstBuf = (unsigned char *)malloc(w * h * tjPixelSize[pf])) == NULL) + if ((dstBuf = (unsigned char *)tj3Alloc(w * h * tjPixelSize[pf])) == NULL) goto bailout; if ((yuvBuf = (unsigned char *)malloc(tj3YUVBufSize(w, 1, h, jpegSubsamp))) == NULL) diff --git a/fuzz/transform.cc b/fuzz/transform.cc index 8d2e6ac..d826203 100644 --- a/fuzz/transform.cc +++ b/fuzz/transform.cc @@ -1,5 +1,5 @@ /* - * Copyright (C)2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,15 +37,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) tjhandle handle = NULL; unsigned char *dstBufs[1] = { NULL }; size_t dstSizes[1] = { 0 }, maxBufSize; - int width = 0, height = 0, jpegSubsamp, i; + int width = 0, height = 0, jpegSubsamp, dstSubsamp, i; tjtransform transforms[1]; -#if defined(__has_feature) && __has_feature(memory_sanitizer) - char env[18] = "JSIMD_FORCENONE=1"; - - /* The libjpeg-turbo SIMD extensions produce false positives with - MemorySanitizer. */ - putenv(env); -#endif if ((handle = tj3Init(TJINIT_TRANSFORM)) == NULL) goto bailout; @@ -77,7 +70,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) transforms[0].op = TJXOP_NONE; transforms[0].options = TJXOPT_PROGRESSIVE | TJXOPT_COPYNONE; dstBufs[0] = - (unsigned char *)malloc(tj3JPEGBufSize(width, height, jpegSubsamp)); + (unsigned char *)tj3Alloc(tj3JPEGBufSize(width, height, jpegSubsamp)); if (!dstBufs[0]) goto bailout; @@ -108,12 +101,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) transforms[0].options = TJXOPT_GRAY | TJXOPT_CROP | TJXOPT_COPYNONE | TJXOPT_OPTIMIZE; dstBufs[0] = - (unsigned char *)malloc(tj3JPEGBufSize((height + 1) / 2, (width + 1) / 2, - jpegSubsamp)); + (unsigned char *)tj3Alloc(tj3JPEGBufSize((height + 1) / 2, (width + 1) / 2, + TJSAMP_GRAY)); if (!dstBufs[0]) goto bailout; - maxBufSize = tj3JPEGBufSize((height + 1) / 2, (width + 1) / 2, jpegSubsamp); + maxBufSize = tj3JPEGBufSize((height + 1) / 2, (width + 1) / 2, TJSAMP_GRAY); if (tj3Transform(handle, data, size, 1, dstBufs, dstSizes, transforms) == 0) { @@ -131,12 +124,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) transforms[0].op = TJXOP_ROT90; transforms[0].options = TJXOPT_TRIM | TJXOPT_ARITHMETIC; + dstSubsamp = jpegSubsamp; + if (dstSubsamp == TJSAMP_422) dstSubsamp = TJSAMP_440; + else if (dstSubsamp == TJSAMP_440) dstSubsamp = TJSAMP_422; + else if (dstSubsamp == TJSAMP_411) dstSubsamp = TJSAMP_441; + else if (dstSubsamp == TJSAMP_441) dstSubsamp = TJSAMP_411; dstBufs[0] = - (unsigned char *)malloc(tj3JPEGBufSize(height, width, jpegSubsamp)); + (unsigned char *)tj3Alloc(tj3JPEGBufSize(height, width, dstSubsamp)); if (!dstBufs[0]) goto bailout; - maxBufSize = tj3JPEGBufSize(height, width, jpegSubsamp); + maxBufSize = tj3JPEGBufSize(height, width, dstSubsamp); if (tj3Transform(handle, data, size, 1, dstBufs, dstSizes, transforms) == 0) { diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 3d863bd..e699e94 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -56,7 +56,8 @@ if(MSYS) endif() add_custom_target(javadoc COMMAND - javadoc -notimestamp -d ${CMAKE_CURRENT_SOURCE_DIR}/doc -sourcepath ${CMAKE_CURRENT_SOURCE_DIR} org.libjpegturbo.turbojpeg) + javadoc -notimestamp -d ${CMAKE_CURRENT_SOURCE_DIR}/doc + -sourcepath ${CMAKE_CURRENT_SOURCE_DIR} org.libjpegturbo.turbojpeg) set(JAVACLASSPATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/turbojpeg-java.dir) if(Java_VERSION_MAJOR GREATER 9) add_custom_target(javah @@ -68,10 +69,14 @@ if(Java_VERSION_MAJOR GREATER 9) ${CMAKE_CURRENT_SOURCE_DIR}/org/libjpegturbo/turbojpeg/TJTransformer.java) else() add_custom_target(javah - COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJ - COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJCompressor - COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJDecompressor - COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} org.libjpegturbo.turbojpeg.TJTransformer) + COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} + org.libjpegturbo.turbojpeg.TJ + COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} + org.libjpegturbo.turbojpeg.TJCompressor + COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} + org.libjpegturbo.turbojpeg.TJDecompressor + COMMAND javah -d ${CMAKE_CURRENT_SOURCE_DIR} -classpath ${JAVACLASSPATH} + org.libjpegturbo.turbojpeg.TJTransformer) endif() if(NOT DEFINED CMAKE_INSTALL_DEFAULT_JAVADIR) @@ -84,5 +89,10 @@ GNUInstallDirs_get_absolute_install_dir(CMAKE_INSTALL_FULL_JAVADIR set(CMAKE_INSTALL_JAVADIR ${CMAKE_INSTALL_JAVADIR} PARENT_SCOPE) set(CMAKE_INSTALL_FULL_JAVADIR ${CMAKE_INSTALL_FULL_JAVADIR} PARENT_SCOPE) report_directory(JAVADIR) -install_jar(turbojpeg-java ${CMAKE_INSTALL_JAVADIR}) +if(CMAKE_VERSION VERSION_EQUAL "3.4" OR CMAKE_VERSION VERSION_GREATER "3.4") + install_jar(turbojpeg-java DESTINATION ${CMAKE_INSTALL_JAVADIR} + COMPONENT java) +else() + install_jar(turbojpeg-java ${CMAKE_INSTALL_JAVADIR}) +endif() mark_as_advanced(CLEAR CMAKE_INSTALL_JAVADIR) diff --git a/java/TJBench.java b/java/TJBench.java index e653add..5be141a 100644 --- a/java/TJBench.java +++ b/java/TJBench.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2014, 2016-2019, 2021-2023 D. R. Commander. + * Copyright (C)2009-2014, 2016-2019, 2021-2024 D. R. Commander. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,8 +41,9 @@ final class TJBench { private static boolean stopOnWarning, bottomUp, fastUpsample, fastDCT, optimize, progressive, limitScans, arithmetic, lossless; - private static int precision = 8, quiet = 0, pf = TJ.PF_BGR, yuvAlign = 1, - restartIntervalBlocks, restartIntervalRows = 0; + private static int maxMemory = 0, maxPixels = 0, precision = 8, quiet = 0, + pf = TJ.PF_BGR, yuvAlign = 1, restartIntervalBlocks = 0, + restartIntervalRows = 0; private static boolean compOnly, decompOnly, doTile, doYUV, write = true, bmp = false; @@ -183,6 +184,8 @@ final class TJBench { tjd.set(TJ.PARAM_FASTUPSAMPLE, fastUpsample ? 1 : 0); tjd.set(TJ.PARAM_FASTDCT, fastDCT ? 1 : 0); tjd.set(TJ.PARAM_SCANLIMIT, limitScans ? 500 : 0); + tjd.set(TJ.PARAM_MAXMEMORY, maxMemory); + tjd.set(TJ.PARAM_MAXPIXELS, maxPixels); if (isCropped(cr)) { try { @@ -364,6 +367,7 @@ final class TJBench { tjc.set(TJ.PARAM_QUALITY, jpegQual); tjc.set(TJ.PARAM_RESTARTBLOCKS, restartIntervalBlocks); tjc.set(TJ.PARAM_RESTARTROWS, restartIntervalRows); + tjc.set(TJ.PARAM_MAXMEMORY, maxMemory); for (tilew = doTile ? 8 : w, tileh = doTile ? 8 : h; ; tilew *= 2, tileh *= 2) { @@ -550,6 +554,8 @@ final class TJBench { tjt.set(TJ.PARAM_FASTUPSAMPLE, fastUpsample ? 1 : 0); tjt.set(TJ.PARAM_FASTDCT, fastDCT ? 1 : 0); tjt.set(TJ.PARAM_SCANLIMIT, limitScans ? 500 : 0); + tjt.set(TJ.PARAM_MAXMEMORY, maxMemory); + tjt.set(TJ.PARAM_MAXPIXELS, maxPixels); try { tjt.setSourceImage(srcBuf, srcSize); @@ -560,7 +566,7 @@ final class TJBench { precision = tjt.get(TJ.PARAM_PRECISION); cs = tjt.get(TJ.PARAM_COLORSPACE); if (tjt.get(TJ.PARAM_PROGRESSIVE) == 1) - System.out.println("JPEG image uses progressive entropy coding\n"); + System.out.println("JPEG image is progressive\n"); if (tjt.get(TJ.PARAM_ARITHMETIC) == 1) System.out.println("JPEG image uses arithmetic entropy coding\n"); tjt.set(TJ.PARAM_PROGRESSIVE, progressive ? 1 : 0); @@ -623,6 +629,22 @@ final class TJBench { } tsubsamp = subsamp; + if ((xformOpt & TJTransform.OPT_GRAY) != 0) + tsubsamp = TJ.SAMP_GRAY; + if (xformOp == TJTransform.OP_TRANSPOSE || + xformOp == TJTransform.OP_TRANSVERSE || + xformOp == TJTransform.OP_ROT90 || + xformOp == TJTransform.OP_ROT270) { + if (tsubsamp == TJ.SAMP_422) + tsubsamp = TJ.SAMP_440; + else if (tsubsamp == TJ.SAMP_440) + tsubsamp = TJ.SAMP_422; + else if (tsubsamp == TJ.SAMP_411) + tsubsamp = TJ.SAMP_441; + else if (tsubsamp == TJ.SAMP_441) + tsubsamp = TJ.SAMP_411; + } + if (doTile || xformOp != TJTransform.OP_NONE || xformOpt != 0 || customFilter != null) { if (xformOp == TJTransform.OP_TRANSPOSE || @@ -635,40 +657,22 @@ final class TJBench { if (xformOp != TJTransform.OP_NONE && xformOp != TJTransform.OP_TRANSPOSE && subsamp == TJ.SAMP_UNKNOWN) throw new Exception("Could not determine subsampling level of JPEG image"); - if ((xformOpt & TJTransform.OPT_GRAY) != 0) - tsubsamp = TJ.SAMP_GRAY; if (xformOp == TJTransform.OP_HFLIP || + xformOp == TJTransform.OP_TRANSVERSE || + xformOp == TJTransform.OP_ROT90 || xformOp == TJTransform.OP_ROT180) tw = tw - (tw % TJ.getMCUWidth(tsubsamp)); if (xformOp == TJTransform.OP_VFLIP || - xformOp == TJTransform.OP_ROT180) - th = th - (th % TJ.getMCUHeight(tsubsamp)); - if (xformOp == TJTransform.OP_TRANSVERSE || - xformOp == TJTransform.OP_ROT90) - tw = tw - (tw % TJ.getMCUHeight(tsubsamp)); - if (xformOp == TJTransform.OP_TRANSVERSE || + xformOp == TJTransform.OP_TRANSVERSE || + xformOp == TJTransform.OP_ROT180 || xformOp == TJTransform.OP_ROT270) - th = th - (th % TJ.getMCUWidth(tsubsamp)); + th = th - (th % TJ.getMCUHeight(tsubsamp)); tntilesw = (tw + ttilew - 1) / ttilew; tntilesh = (th + ttileh - 1) / ttileh; - if (xformOp == TJTransform.OP_TRANSPOSE || - xformOp == TJTransform.OP_TRANSVERSE || - xformOp == TJTransform.OP_ROT90 || - xformOp == TJTransform.OP_ROT270) { - if (tsubsamp == TJ.SAMP_422) - tsubsamp = TJ.SAMP_440; - else if (tsubsamp == TJ.SAMP_440) - tsubsamp = TJ.SAMP_422; - else if (tsubsamp == TJ.SAMP_411) - tsubsamp = TJ.SAMP_441; - else if (tsubsamp == TJ.SAMP_441) - tsubsamp = TJ.SAMP_411; - } - TJTransform[] t = new TJTransform[tntilesw * tntilesh]; jpegBufs = - new byte[tntilesw * tntilesh][TJ.bufSize(ttilew, ttileh, subsamp)]; + new byte[tntilesw * tntilesh][TJ.bufSize(ttilew, ttileh, tsubsamp)]; for (y = 0, tile = 0; y < th; y += ttileh) { for (x = 0; x < tw; x += ttilew, tile++) { @@ -731,7 +735,7 @@ final class TJBench { } else { if (quiet == 1) System.out.print("N/A N/A "); - jpegBufs = new byte[1][TJ.bufSize(ttilew, ttileh, subsamp)]; + jpegBufs = new byte[1][TJ.bufSize(ttilew, ttileh, tsubsamp)]; jpegSizes = new int[1]; jpegBufs[0] = srcBuf; jpegSizes[0] = srcSize; @@ -775,6 +779,11 @@ final class TJBench { System.out.println("-componly = Stop after running compression tests. Do not test decompression."); System.out.println("-lossless = Generate lossless JPEG images when compressing (implies"); System.out.println(" -subsamp 444). PSV is the predictor selection value (1-7)."); + System.out.println("-maxmemory N = Memory limit (in megabytes) for intermediate buffers used with"); + System.out.println(" progressive JPEG compression and decompression, Huffman table"); + System.out.println(" optimization, lossless JPEG compression, and lossless transformation"); + System.out.println(" [default = no limit]"); + System.out.println("-maxpixels N = Input image size limit (in pixels) [default = no limit]"); System.out.println("-nowrite = Do not write reference or output images (improves consistency of"); System.out.println(" benchmark results)"); System.out.println("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb ="); @@ -786,10 +795,9 @@ final class TJBench { System.out.println(" default = 8; if N is 16, then -lossless must also be specified]"); System.out.println(" (-precision 12 implies -optimize unless -arithmetic is also specified)"); System.out.println("-quiet = Output results in tabular rather than verbose format"); - System.out.println("-restart N = When compressing, add a restart marker every N MCU rows (lossy) or"); - System.out.println(" N sample rows (lossless) [default = 0 (no restart markers)]. Append 'B'"); - System.out.println(" to specify the restart marker interval in MCU blocks (lossy) or samples"); - System.out.println(" (lossless)."); + System.out.println("-restart N = When compressing, add a restart marker every N MCU rows"); + System.out.println(" [default = 0 (no restart markers)]. Append 'B' to specify the restart"); + System.out.println(" marker interval in MCUs (lossy only.)"); System.out.println("-stoponwarning = Immediately discontinue the current"); System.out.println(" compression/decompression/transform operation if a warning (non-fatal"); System.out.println(" error) occurs"); @@ -807,14 +815,14 @@ final class TJBench { System.out.println(" and H are the width and height of the region (0 = maximum possible width"); System.out.println(" or height) and X and Y are the left and upper boundary of the region, all"); System.out.println(" specified relative to the scaled image dimensions. X must be divible by"); - System.out.println(" the scaled MCU width."); + System.out.println(" the scaled iMCU width."); System.out.println("-fastdct = Use the fastest DCT/IDCT algorithm available"); System.out.println("-fastupsample = Use the fastest chrominance upsampling algorithm available"); - System.out.println("-optimize = Use optimized baseline entropy coding in JPEG images generated by"); + System.out.println("-optimize = Compute optimal Huffman tables for JPEG images generated by"); System.out.println(" compession and transform operations"); - System.out.println("-progressive = Use progressive entropy coding in JPEG images generated by"); - System.out.println(" compression and transform operations (can be combined with -arithmetic;"); - System.out.println(" implies -optimize unless -arithmetic is also specified)"); + System.out.println("-progressive = Generate progressive JPEG images when compressing or"); + System.out.println(" transforming (can be combined with -arithmetic; implies -optimize unless"); + System.out.println(" -arithmetic is also specified)"); System.out.println("-limitscans = Refuse to decompress or transform progressive JPEG images that"); System.out.println(" have an unreasonably large number of scans"); System.out.println("-scale M/N = When decompressing, scale the width/height of the JPEG image by a"); @@ -842,7 +850,7 @@ final class TJBench { System.out.println(" prior to decompression (these operations are mutually exclusive)"); System.out.println("-grayscale = Transform the input image into a grayscale JPEG image prior to"); System.out.println(" decompression (can be combined with the other transform operations above)"); - System.out.println("-copynone = Do not copy any extra markers (including EXIF and ICC profile data)"); + System.out.println("-copynone = Do not copy any extra markers (including Exif and ICC profile data)"); System.out.println(" when transforming the input image"); System.out.println("-yuv = Compress from/decompress to intermediate planar YUV images"); System.out.println(" ** 8-bit data precision only **"); @@ -915,21 +923,19 @@ final class TJBench { System.out.println("Using fastest DCT/IDCT algorithm\n"); fastDCT = true; } else if (argv[i].equalsIgnoreCase("-optimize")) { - System.out.println("Using optimized baseline entropy coding\n"); optimize = true; xformOpt |= TJTransform.OPT_OPTIMIZE; } else if (argv[i].equalsIgnoreCase("-progressive")) { - System.out.println("Using progressive entropy coding\n"); + System.out.println("Generating progressive JPEG images\n"); progressive = true; xformOpt |= TJTransform.OPT_PROGRESSIVE; } else if (argv[i].equalsIgnoreCase("-arithmetic")) { System.out.println("Using arithmetic entropy coding\n"); arithmetic = true; xformOpt |= TJTransform.OPT_ARITHMETIC; - } else if (argv[i].equalsIgnoreCase("-lossless")) { + } else if (argv[i].equalsIgnoreCase("-lossless")) lossless = true; - subsamp = TJ.SAMP_444; - } else if (argv[i].equalsIgnoreCase("-rgb")) + else if (argv[i].equalsIgnoreCase("-rgb")) pf = TJ.PF_RGB; else if (argv[i].equalsIgnoreCase("-rgbx")) pf = TJ.PF_RGBX; @@ -1074,7 +1080,27 @@ final class TJBench { write = false; else if (argv[i].equalsIgnoreCase("-limitscans")) limitScans = true; - else if (argv[i].equalsIgnoreCase("-restart") && + else if (argv[i].equalsIgnoreCase("-maxmemory") && + i < argv.length - 1) { + int temp = -1; + + try { + temp = Integer.parseInt(argv[++i]); + } catch (NumberFormatException e) {} + if (temp < 0) + usage(); + maxMemory = temp; + } else if (argv[i].equalsIgnoreCase("-maxpixels") && + i < argv.length - 1) { + int temp = -1; + + try { + temp = Integer.parseInt(argv[++i]); + } catch (NumberFormatException e) {} + if (temp < 0) + usage(); + maxPixels = temp; + } else if (argv[i].equalsIgnoreCase("-restart") && i < argv.length - 1) { int temp = -1; String arg = argv[++i]; @@ -1096,6 +1122,13 @@ final class TJBench { } } + if (optimize && !progressive && !arithmetic && !lossless && + precision != 12) + System.out.println("Computing optimal Huffman tables\n"); + + if (lossless) + subsamp = TJ.SAMP_444; + if (precision == 16 && !lossless) throw new Exception("-lossless must be specified along with -precision 16"); if (precision != 8 && doYUV) @@ -1130,6 +1163,7 @@ final class TJBench { tjc = new TJCompressor(); tjc.set(TJ.PARAM_STOPONWARNING, stopOnWarning ? 1 : 0); tjc.set(TJ.PARAM_BOTTOMUP, bottomUp ? 1 : 0); + tjc.set(TJ.PARAM_MAXPIXELS, maxPixels); pixelFormat[0] = pf; srcBuf = tjc.loadImage(precision, argv[0], width, 1, height, diff --git a/java/TJExample.java b/java/TJExample.java index 6a2148c..96a6828 100644 --- a/java/TJExample.java +++ b/java/TJExample.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2012, 2014-2015, 2017-2018, 2022-2023 D. R. Commander. + * Copyright (C)2011-2012, 2014-2015, 2017-2018, 2022-2024 D. R. Commander. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -125,8 +125,8 @@ class TJExample implements TJCustomFilter { System.out.println("-crop WxH+X+Y = Perform lossless cropping on the input image prior to"); System.out.println(" decompressing it. X and Y specify the upper left corner of the cropping"); System.out.println(" region, and W and H specify the width and height of the cropping region."); - System.out.println(" X and Y must be evenly divible by the MCU block size (8x8 if the input"); - System.out.println(" image was compressed using no subsampling or grayscale, 16x8 if it was"); + System.out.println(" X and Y must be evenly divible by the iMCU size (8x8 if the input image"); + System.out.println(" was compressed using no subsampling or grayscale, 16x8 if it was"); System.out.println(" compressed using 4:2:2 subsampling, or 16x16 if it was compressed using"); System.out.println(" 4:2:0 subsampling.)\n"); diff --git a/java/doc/allclasses-index.html b/java/doc/allclasses-index.html index f3179c5..12f4245 100644 --- a/java/doc/allclasses-index.html +++ b/java/doc/allclasses-index.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/allclasses.html b/java/doc/allclasses.html index c87c92f..d37a6e4 100644 --- a/java/doc/allclasses.html +++ b/java/doc/allclasses.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/allpackages-index.html b/java/doc/allpackages-index.html index 8ad354d..3b4015d 100644 --- a/java/doc/allpackages-index.html +++ b/java/doc/allpackages-index.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/constant-values.html b/java/doc/constant-values.html index 1fa1fce..216171f 100644 --- a/java/doc/constant-values.html +++ b/java/doc/constant-values.html @@ -14,7 +14,7 @@ - + @@ -319,6 +319,20 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height")); 17 + + +public static final int +PARAM_MAXMEMORY +23 + + + + +public static final int +PARAM_MAXPIXELS +24 + + public static final int diff --git a/java/doc/deprecated-list.html b/java/doc/deprecated-list.html index 3f4f34a..dea2933 100644 --- a/java/doc/deprecated-list.html +++ b/java/doc/deprecated-list.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/help-doc.html b/java/doc/help-doc.html index 6d9362c..0a4110d 100644 --- a/java/doc/help-doc.html +++ b/java/doc/help-doc.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/index-all.html b/java/doc/index-all.html index 4b15305..c12d4ce 100644 --- a/java/doc/index-all.html +++ b/java/doc/index-all.html @@ -14,7 +14,7 @@ - + @@ -150,27 +150,27 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    CS_CMYK - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    CMYK colorspace.
    +
    CMYK colorspace
    CS_GRAY - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Grayscale colorspace.
    +
    Grayscale colorspace
    CS_RGB - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    RGB colorspace.
    +
    RGB colorspace
    CS_YCbCr - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    YCbCr colorspace.
    +
    YCbCr colorspace
    CS_YCCK - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    YCCK colorspace.
    +
    YCCK colorspace
    customFilter(ShortBuffer, Rectangle, Rectangle, int, int, TJTransform) - Method in interface org.libjpegturbo.turbojpeg.TJCustomFilter
    -
    A callback function that can be used to modify the DCT coefficients after +
    A callback method that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image.
    @@ -460,7 +460,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    getCompressedSize() - Method in class org.libjpegturbo.turbojpeg.TJCompressor
    Returns the size of the image (in bytes) generated by the most recent - compress operation.
    + compression operation.
    getDenom() - Method in class org.libjpegturbo.turbojpeg.TJScalingFactor
    @@ -496,13 +496,11 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    getMCUHeight(int) - Static method in class org.libjpegturbo.turbojpeg.TJ
    -
    Returns the MCU block height for the given level of chrominance - subsampling.
    +
    Returns the iMCU height for the given level of chrominance subsampling.
    getMCUWidth(int) - Static method in class org.libjpegturbo.turbojpeg.TJ
    -
    Returns the MCU block width for the given level of chrominance - subsampling.
    +
    Returns the iMCU width for the given level of chrominance subsampling.
    getNum() - Method in class org.libjpegturbo.turbojpeg.TJScalingFactor
    @@ -670,47 +668,43 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    OPT_ARITHMETIC - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will enable arithmetic entropy coding in the JPEG image - generated by this particular transform.
    +
    Enable arithmetic entropy coding in the destination image.
    OPT_COPYNONE - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will prevent TJTransformer.transform() from copying any extra markers (including EXIF - and ICC profile data) from the source image to the destination image.
    +
    Do not copy any extra markers (including Exif and ICC profile data) from + the source image to the destination image.
    OPT_CROP - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will enable lossless cropping.
    +
    Enable lossless cropping.
    OPT_GRAY - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will discard the color data in the source image and produce a - grayscale destination image.
    +
    Discard the color data in the source image, and generate a grayscale + destination image.
    OPT_NOOUTPUT - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will prevent TJTransformer.transform() from outputting a JPEG image for this - particular transform.
    +
    Do not generate a destination image.
    OPT_OPTIMIZE - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will enable optimized baseline entropy coding in the JPEG - image generated by this particular transform.
    +
    Enable Huffman table optimization for the destination image.
    OPT_PERFECT - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will cause TJTransformer.transform() to throw an exception if the transform is not +
    This option causes TJTransformer.transform() to throw an exception if the transform is not perfect.
    OPT_PROGRESSIVE - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will enable progressive entropy coding in the JPEG image - generated by this particular transform.
    +
    Generate a progressive destination image instead of a single-scan + destination image.
    OPT_TRIM - Static variable in class org.libjpegturbo.turbojpeg.TJTransform
    -
    This option will discard any partial MCU blocks that cannot be - transformed.
    +
    Discard any partial iMCUs that cannot be transformed.
    options - Variable in class org.libjpegturbo.turbojpeg.TJTransform
    @@ -769,9 +763,17 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    Lossless JPEG point transform (Pt)
    +
    PARAM_MAXMEMORY - Static variable in class org.libjpegturbo.turbojpeg.TJ
    +
    +
    Memory limit for intermediate buffers
    +
    +
    PARAM_MAXPIXELS - Static variable in class org.libjpegturbo.turbojpeg.TJ
    +
    +
    Image size limit [decompression, lossless transformation]
    +
    PARAM_OPTIMIZE - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Optimized baseline entropy coding [lossy compression only]
    +
    Huffman table optimization [lossy compression, lossless transformation]
    PARAM_PRECISION - Static variable in class org.libjpegturbo.turbojpeg.TJ
    @@ -779,7 +781,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    PARAM_PROGRESSIVE - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Progressive entropy coding
    +
    Progressive JPEG
    PARAM_QUALITY - Static variable in class org.libjpegturbo.turbojpeg.TJ
    @@ -787,13 +789,11 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    PARAM_RESTARTBLOCKS - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) - [compression only]
    +
    JPEG restart marker interval in MCUs [lossy compression only]
    PARAM_RESTARTROWS - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) - [compression only]
    +
    JPEG restart marker interval in MCU rows [compression only]
    PARAM_SCANLIMIT - Static variable in class org.libjpegturbo.turbojpeg.TJ
    @@ -818,51 +818,51 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    PF_ABGR - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    ABGR pixel format.
    +
    ABGR pixel format
    PF_ARGB - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    ARGB pixel format.
    +
    ARGB pixel format
    PF_BGR - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    BGR pixel format.
    +
    BGR pixel format
    PF_BGRA - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    BGRA pixel format.
    +
    BGRA pixel format
    PF_BGRX - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    BGRX pixel format.
    +
    BGRX pixel format
    PF_CMYK - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    CMYK pixel format.
    +
    CMYK pixel format
    PF_GRAY - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Grayscale pixel format.
    +
    Grayscale pixel format
    PF_RGB - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    RGB pixel format.
    +
    RGB pixel format
    PF_RGBA - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    RGBA pixel format.
    +
    RGBA pixel format
    PF_RGBX - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    RGBX pixel format.
    +
    RGBX pixel format
    PF_XBGR - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    XBGR pixel format.
    +
    XBGR pixel format
    PF_XRGB - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    XRGB pixel format.
    +
    XRGB pixel format
    planeHeight(int, int, int) - Static method in class org.libjpegturbo.turbojpeg.TJ
    @@ -885,35 +885,35 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    SAMP_411 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:1:1 chrominance subsampling.
    +
    4:1:1 chrominance subsampling
    SAMP_420 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:2:0 chrominance subsampling.
    +
    4:2:0 chrominance subsampling
    SAMP_422 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:2:2 chrominance subsampling.
    +
    4:2:2 chrominance subsampling
    SAMP_440 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:4:0 chrominance subsampling.
    +
    4:4:0 chrominance subsampling
    SAMP_441 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:4:1 chrominance subsampling.
    +
    4:4:1 chrominance subsampling
    SAMP_444 - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    4:4:4 chrominance subsampling (no chrominance subsampling).
    +
    4:4:4 chrominance subsampling (no chrominance subsampling)
    SAMP_GRAY - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Grayscale.
    +
    Grayscale
    SAMP_UNKNOWN - Static variable in class org.libjpegturbo.turbojpeg.TJ
    -
    Unknown subsampling.
    +
    Unknown subsampling
    set(int, int) - Method in class org.libjpegturbo.turbojpeg.TJCompressor
    @@ -960,7 +960,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height"));
    setSourceImage(BufferedImage, int, int, int, int) - Method in class org.libjpegturbo.turbojpeg.TJCompressor
    -
    Associate an 8-bit-per-pixel packed-pixel RGB or grayscale source image +
    Associate an 8-bit-per-sample packed-pixel RGB or grayscale source image with this compressor instance.
    setSourceImage(YUVImage) - Method in class org.libjpegturbo.turbojpeg.TJCompressor
    diff --git a/java/doc/jquery/jquery-3.6.0.min.js b/java/doc/jquery/jquery-3.6.0.min.js deleted file mode 100644 index c4c6022..0000000 --- a/java/doc/jquery/jquery-3.6.0.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&v(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!y||!y.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ve(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ye(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ve(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],y=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||y.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||y.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||y.push(".#.+[+~]"),e.querySelectorAll("\\\f"),y.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),y=y.length&&new RegExp(y.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),v=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&v(p,e)?-1:t==C||t.ownerDocument==p&&v(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!y||!y.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),v.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",v.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",v.option=!!ce.lastChild;var ge={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),v.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(v.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return B(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=_e(v.pixelPosition,function(e,t){if(t)return t=Be(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return B(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n
    "),i=e.children()[0];return x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,l=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
      ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
      ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("
      ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
      ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});x.ui.autocomplete}); \ No newline at end of file +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(x){"use strict";x.ui=x.ui||{};x.ui.version="1.13.2";var n,i=0,l=Array.prototype.hasOwnProperty,a=Array.prototype.slice;x.cleanData=(n=x.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=x._data(i,"events"))&&e.remove&&x(i).triggerHandler("remove");n(t)}),x.widget=function(t,i,e){var s,n,o,l={},a=t.split(".")[0],r=a+"-"+(t=t.split(".")[1]);return e||(e=i,i=x.Widget),Array.isArray(e)&&(e=x.extend.apply(null,[{}].concat(e))),x.expr.pseudos[r.toLowerCase()]=function(t){return!!x.data(t,r)},x[a]=x[a]||{},s=x[a][t],n=x[a][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},x.extend(n,s,{version:e.version,_proto:x.extend({},e),_childConstructors:[]}),(o=new i).options=x.widget.extend({},o.options),x.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}l[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=x.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},l,{constructor:n,namespace:a,widgetName:t,widgetFullName:r}),s?(x.each(s._childConstructors,function(t,e){var i=e.prototype;x.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),x.widget.bridge(t,n),n},x.widget.extend=function(t){for(var e,i,s=a.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=x(e||this.defaultElement||this)[0],this.element=x(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=x(),this.hoverable=x(),this.focusable=x(),this.classesElementLookup={},e!==this&&(x.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=x(e.style?e.ownerDocument:e.document||e),this.window=x(this.document[0].defaultView||this.document[0].parentWindow)),this.options=x.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:x.noop,_create:x.noop,_init:x.noop,destroy:function(){var i=this;this._destroy(),x.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:x.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return x.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=x.widget.extend({},this.options[t]),n=0;n
      "),i=e.children()[0];return x("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthC(E(s),E(n))?o.important="horizontal":o.important="vertical",c.using.call(this,t,o)}),l.offset(x.extend(u,{using:t}))})},x.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,l=s-o,a=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=x(t.target),i=x(x.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){x.contains(this.element[0],x.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=x(t.target).closest(".ui-menu-item"),i=x(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=x(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case x.ui.keyCode.PAGE_UP:this.previousPage(t);break;case x.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case x.ui.keyCode.HOME:this._move("first","first",t);break;case x.ui.keyCode.END:this._move("last","last",t);break;case x.ui.keyCode.UP:this.previous(t);break;case x.ui.keyCode.DOWN:this.next(t);break;case x.ui.keyCode.LEFT:this.collapse(t);break;case x.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case x.ui.keyCode.ENTER:case x.ui.keyCode.SPACE:this._activate(t);break;case x.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=x(this),e=t.prev(),i=x("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=x(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!x.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(x.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(x.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=x.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=x("
        ").appendTo(this._appendTo()).menu({role:null}).hide().attr({unselectable:"on"}).menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(t){t.preventDefault()},menufocus:function(t,e){var i,s;if(this.isNewMenu&&(this.isNewMenu=!1,t.originalEvent&&/^mouse/.test(t.originalEvent.type)))return this.menu.blur(),void this.document.one("mousemove",function(){x(t.target).trigger(t.originalEvent)});s=e.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",t,{item:s})&&t.originalEvent&&/^key/.test(t.originalEvent.type)&&this._value(s.value),(i=e.item.attr("aria-label")||s.value)&&String.prototype.trim.call(i).length&&(clearTimeout(this.liveRegionTimer),this.liveRegionTimer=this._delay(function(){this.liveRegion.html(x("
        ").text(i))},100))},menuselect:function(t,e){var i=e.item.data("ui-autocomplete-item"),s=this.previous;this.element[0]!==x.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s,this.selectedItem=i})),!1!==this._trigger("select",t,{item:i})&&this._value(i.value),this.term=this._value(),this.close(t),this.selectedItem=i}}),this.liveRegion=x("
        ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(t){var e=this.menu.element[0];return t.target===this.element[0]||t.target===e||x.contains(e,t.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var t=this.options.appendTo;return t=!(t=!(t=t&&(t.jquery||t.nodeType?x(t):this.document.find(t).eq(0)))||!t[0]?this.element.closest(".ui-front, dialog"):t).length?this.document[0].body:t},_initSource:function(){var i,s,n=this;Array.isArray(this.options.source)?(i=this.options.source,this.source=function(t,e){e(x.ui.autocomplete.filter(i,t.term))}):"string"==typeof this.options.source?(s=this.options.source,this.source=function(t,e){n.xhr&&n.xhr.abort(),n.xhr=x.ajax({url:s,data:t,dataType:"json",success:function(t){e(t)},error:function(){e([])}})}):this.source=this.options.source},_searchTimeout:function(s){clearTimeout(this.searching),this.searching=this._delay(function(){var t=this.term===this._value(),e=this.menu.element.is(":visible"),i=s.altKey||s.ctrlKey||s.metaKey||s.shiftKey;t&&(e||i)||(this.selectedItem=null,this.search(null,s))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(x("
        ").text(e.label)).appendTo(t)},_move:function(t,e){if(this.menu.element.is(":visible"))return this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),void this.menu.blur()):void this.menu[t](e);this.search(null,e)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){this.isMultiLine&&!this.menu.element.is(":visible")||(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),x.extend(x.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(t,e){var i=new RegExp(x.ui.autocomplete.escapeRegex(e),"i");return x.grep(t,function(t){return i.test(t.label||t.value||t)})}}),x.widget("ui.autocomplete",x.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(1").text(e))},100))}});x.ui.autocomplete}); \ No newline at end of file diff --git a/java/doc/legal/ADDITIONAL_LICENSE_INFO b/java/doc/legal/ADDITIONAL_LICENSE_INFO new file mode 100644 index 0000000..ff700cd --- /dev/null +++ b/java/doc/legal/ADDITIONAL_LICENSE_INFO @@ -0,0 +1,37 @@ + ADDITIONAL INFORMATION ABOUT LICENSING + +Certain files distributed by Oracle America, Inc. and/or its affiliates are +subject to the following clarification and special exception to the GPLv2, +based on the GNU Project exception for its Classpath libraries, known as the +GNU Classpath Exception. + +Note that Oracle includes multiple, independent programs in this software +package. Some of those programs are provided under licenses deemed +incompatible with the GPLv2 by the Free Software Foundation and others. +For example, the package includes programs licensed under the Apache +License, Version 2.0 and may include FreeType. Such programs are licensed +to you under their original licenses. + +Oracle facilitates your further distribution of this package by adding the +Classpath Exception to the necessary parts of its GPLv2 code, which permits +you to use that code in combination with other independent modules not +licensed under the GPLv2. However, note that this would not permit you to +commingle code under an incompatible license with Oracle's GPLv2 licensed +code by, for example, cutting and pasting such code into a file also +containing Oracle's GPLv2 licensed code and then distributing the result. + +Additionally, if you were to remove the Classpath Exception from any of the +files to which it applies and distribute the result, you would likely be +required to license some or all of the other code in that distribution under +the GPLv2 as well, and since the GPLv2 is incompatible with the license terms +of some items included in the distribution by Oracle, removing the Classpath +Exception could therefore effectively compromise your ability to further +distribute the package. + +Failing to distribute notices associated with some files may also create +unexpected legal consequences. + +Proceed with caution and we recommend that you obtain the advice of a lawyer +skilled in open source matters before removing the Classpath Exception or +making modifications to this package which may subsequently be redistributed +and/or involve the use of third party software. diff --git a/java/doc/legal/ASSEMBLY_EXCEPTION b/java/doc/legal/ASSEMBLY_EXCEPTION new file mode 100644 index 0000000..065b8d9 --- /dev/null +++ b/java/doc/legal/ASSEMBLY_EXCEPTION @@ -0,0 +1,27 @@ + +OPENJDK ASSEMBLY EXCEPTION + +The OpenJDK source code made available by Oracle America, Inc. (Oracle) at +openjdk.java.net ("OpenJDK Code") is distributed under the terms of the GNU +General Public License version 2 +only ("GPL2"), with the following clarification and special exception. + + Linking this OpenJDK Code statically or dynamically with other code + is making a combined work based on this library. Thus, the terms + and conditions of GPL2 cover the whole combination. + + As a special exception, Oracle gives you permission to link this + OpenJDK Code with certain code licensed by Oracle as indicated at + http://openjdk.java.net/legal/exception-modules-2007-05-08.html + ("Designated Exception Modules") to produce an executable, + regardless of the license terms of the Designated Exception Modules, + and to copy and distribute the resulting executable under GPL2, + provided that the Designated Exception Modules continue to be + governed by the licenses under which they were offered by Oracle. + +As such, it allows licensees and sublicensees of Oracle's GPL2 OpenJDK Code +to build an executable that includes those portions of necessary code that +Oracle could not provide under GPL2 (or that Oracle has provided under GPL2 +with the Classpath exception). If you modify or add to the OpenJDK code, +that new GPL2 code may still be combined with Designated Exception Modules +if the new code is made subject to this exception by its copyright holder. diff --git a/java/doc/legal/LICENSE b/java/doc/legal/LICENSE new file mode 100644 index 0000000..8b400c7 --- /dev/null +++ b/java/doc/legal/LICENSE @@ -0,0 +1,347 @@ +The GNU General Public License (GPL) + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom to +distribute copies of free software (and charge for this service if you wish), +that you receive source code or can get it if you want it, that you can change +the software or use pieces of it in new free programs; and that you know you +can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must +make sure that they, too, receive or can get the source code. And you must +show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program proprietary. +To prevent this, we have made it clear that any patent must be licensed for +everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or +translated into another language. (Hereinafter, translation is included +without limitation in the term "modification".) Each licensee is addressed as +"you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may +at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all of +these conditions: + + a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + c) If the modified program normally reads commands interactively when run, + you must cause it, when started running for such interactive use in the + most ordinary way, to print or display an announcement including an + appropriate copyright notice and a notice that there is no warranty (or + else, saying that you provide a warranty) and that users may redistribute + the program under these conditions, and telling the user how to view a copy + of this License. (Exception: if the Program itself is interactive but does + not normally print such an announcement, your work based on the Program is + not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, and +its terms, do not apply to those sections when you distribute them as separate +works. But when you distribute the same sections as part of a whole which is a +work based on the Program, the distribution of the whole must be on the terms +of this License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise the +right to control the distribution of derivative or collective works based on +the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and +2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 above + on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to + give any third party, for a charge no more than your cost of physically + performing source distribution, a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of Sections 1 + and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed only + for noncommercial distribution and only if you received the program in + object code or executable form with such an offer, in accord with + Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code +distributed need not include anything that is normally distributed (in either +source or binary form) with the major components (compiler, kernel, and so on) +of the operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so +long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not +accept this License. Therefore, by modifying or distributing the Program (or +any work based on the Program), you indicate your acceptance of this License to +do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to +copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance by +third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose that +choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original +copyright holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In +such case, this License incorporates the limitation as if written in the body +of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems +or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any later +version", you have the option of following the terms and conditions either of +that version or of any later version published by the Free Software Foundation. +If the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE +PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL +ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE +PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER +OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible +use to the public, the best way to achieve this is to make it free software +which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach +them to the start of each source file to most effectively convey the exclusion +of warranty; and each file should have at least the "copyright" line and a +pointer to where the full notice is found. + + One line to give the program's name and a brief idea of what it does. + + Copyright (C) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it +starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes + with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free + software, and you are welcome to redistribute it under certain conditions; + type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + 'Gnomovision' (which makes passes at compilers) written by James Hacker. + + signature of Ty Coon, 1 April 1989 + + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. + + +"CLASSPATH" EXCEPTION TO THE GPL + +Certain source files distributed by Oracle America and/or its affiliates are +subject to the following clarification and special exception to the GPL, but +only where Oracle has expressly included in the particular source file's header +the words "Oracle designates this particular file as subject to the "Classpath" +exception as provided by Oracle in the LICENSE file that accompanied this code." + + Linking this library statically or dynamically with other modules is making + a combined work based on this library. Thus, the terms and conditions of + the GNU General Public License cover the whole combination. + + As a special exception, the copyright holders of this library give you + permission to link this library with independent modules to produce an + executable, regardless of the license terms of these independent modules, + and to copy and distribute the resulting executable under terms of your + choice, provided that you also meet, for each linked independent module, + the terms and conditions of the license of that module. An independent + module is a module which is not derived from or based on this library. If + you modify this library, you may extend this exception to your version of + the library, but you are not obligated to do so. If you do not wish to do + so, delete this exception statement from your version. diff --git a/java/doc/legal/jquery.md b/java/doc/legal/jquery.md new file mode 100644 index 0000000..d468b31 --- /dev/null +++ b/java/doc/legal/jquery.md @@ -0,0 +1,72 @@ +## jQuery v3.6.1 + +### jQuery License +``` +jQuery v 3.6.1 +Copyright OpenJS Foundation and other contributors, https://openjsf.org/ + +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. + +****************************************** + +The jQuery JavaScript Library v3.6.1 also includes Sizzle.js + +Sizzle.js includes the following license: + +Copyright JS Foundation and other contributors, https://js.foundation/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/sizzle + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +********************* + +``` diff --git a/java/doc/legal/jqueryUI.md b/java/doc/legal/jqueryUI.md new file mode 100644 index 0000000..8bda9d7 --- /dev/null +++ b/java/doc/legal/jqueryUI.md @@ -0,0 +1,49 @@ +## jQuery UI v1.13.2 + +### jQuery UI License +``` +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +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. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +``` diff --git a/java/doc/legal/jszip.md b/java/doc/legal/jszip.md new file mode 100644 index 0000000..fad2cb1 --- /dev/null +++ b/java/doc/legal/jszip.md @@ -0,0 +1,653 @@ +## JSZip v3.7.1 + +JSZip is dual licensed. You may use it under the MIT license *or* the GPLv3 +license. + +### The MIT License +``` +Copyright (c) 2009-2016 Stuart Knightley, David Duponchel, Franz Buchinger, António Afonso + +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. +``` + +### GPL version 3 +``` + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS +``` diff --git a/java/doc/legal/pako.md b/java/doc/legal/pako.md new file mode 100644 index 0000000..de339d8 --- /dev/null +++ b/java/doc/legal/pako.md @@ -0,0 +1,45 @@ +## Pako v1.0 + +### Pako License +
        +Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
        +
        +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.
        +(C) 1995-2013 Jean-loup Gailly and Mark Adler
        +(C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
        +
        +This software is provided 'as-is', without any express or implied
        +warranty. In no event will the authors be held liable for any damages
        +arising from the use of this software.
        +
        +Permission is granted to anyone to use this software for any purpose,
        +including commercial applications, and to alter it and redistribute it
        +freely, 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 notice may not be removed or altered from any source distribution.
        +
        +
        + + diff --git a/java/doc/member-search-index.js b/java/doc/member-search-index.js index c1c104f..fb9feac 100644 --- a/java/doc/member-search-index.js +++ b/java/doc/member-search-index.js @@ -1 +1 @@ -memberSearchIndex = [{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"bufSize(int, int, int)","url":"bufSize(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"bufSizeYUV(int, int, int, int)","url":"bufSizeYUV(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"cf"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"close()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"close()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(byte[], int)","url":"compress(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_CMYK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_RGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_YCbCr"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_YCCK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCustomFilter","l":"customFilter(ShortBuffer, Rectangle, Rectangle, int, int, TJTransform)","url":"customFilter(java.nio.ShortBuffer,java.awt.Rectangle,java.awt.Rectangle,int,int,org.libjpegturbo.turbojpeg.TJTransform)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(BufferedImage, int)","url":"decompress(java.awt.image.BufferedImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(byte[], int, int, int, int, int, int, int)","url":"decompress(byte[],int,int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int, int, int, int, int)","url":"decompress(int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int, int, int, int)","url":"decompress(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int[], int, int, int, int, int, int, int)","url":"decompress(int[],int,int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress12(int, int)","url":"decompress12(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress12(short[], int, int, int, int)","url":"decompress12(short[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress16(int, int)","url":"decompress16(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress16(short[], int, int, int, int)","url":"decompress16(short[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(BufferedImage)","url":"decompress8(java.awt.image.BufferedImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(byte[], int, int, int, int)","url":"decompress8(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int, int)","url":"decompress8(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int[], int, int, int, int)","url":"decompress8(int[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int, int, int, int)","url":"decompressToYUV(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int, int[], int, int)","url":"decompressToYUV(int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(YUVImage, int)","url":"decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(YUVImage)","url":"decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int, int)","url":"encodeYUV(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int[], int)","url":"encodeYUV(int[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(YUVImage, int)","url":"encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(YUVImage)","url":"encodeYUV(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"equals(TJScalingFactor)","url":"equals(org.libjpegturbo.turbojpeg.TJScalingFactor)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"ERR_FATAL"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"ERR_WARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"finalize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"finalize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_ACCURATEDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_BOTTOMUP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_FASTDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_FASTUPSAMPLE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_LIMITSCANS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_STOPONWARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"get(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"get(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getAlphaOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getBlueOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getBuf()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getColorspace()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"getCompressedSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getDenom()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"getErrorCode()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getGreenOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getHeight()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getHeight()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getJPEGBuf()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getJPEGSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getMCUHeight(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getMCUWidth(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getNum()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getOffsets()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getPad()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getPixelSize(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getPlanes()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getRedOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getScaled(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getScaledHeight(int, int)","url":"getScaledHeight(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getScaledWidth(int, int)","url":"getScaledWidth(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getScalingFactors()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getStrides()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getSubsamp()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getSubsamp()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"getTransformedSizes()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getWidth()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getWidth()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"isOne()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMCS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMERR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"NUMOP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMPF"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMSAMP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"op"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_HFLIP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_NONE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT180"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT270"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT90"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_TRANSPOSE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_TRANSVERSE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_VFLIP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_ARITHMETIC"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_COPYNONE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_CROP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_NOOUTPUT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_OPTIMIZE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_PERFECT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_TRIM"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"options"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_ARITHMETIC"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_BOTTOMUP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_COLORSPACE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_DENSITYUNITS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_FASTDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_FASTUPSAMPLE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_JPEGHEIGHT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_JPEGWIDTH"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESSPSV"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESSPT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_OPTIMIZE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_PRECISION"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_QUALITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_RESTARTBLOCKS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_RESTARTROWS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_SCANLIMIT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_STOPONWARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_SUBSAMP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_XDENSITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_YDENSITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_ABGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_ARGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGRA"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGRX"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_CMYK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGBA"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGBX"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_XBGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_XRGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeHeight(int, int, int)","url":"planeHeight(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeSizeYUV(int, int, int, int, int)","url":"planeSizeYUV(int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeWidth(int, int, int)","url":"planeWidth(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_411"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_420"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_422"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_440"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_441"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_444"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_UNKNOWN"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"set(int, int)","url":"set(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"set(int, int)","url":"set(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"setBuf(byte[], int, int, int, int)","url":"setBuf(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"setBuf(byte[][], int[], int, int[], int, int)","url":"setBuf(byte[][],int[],int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setCroppingRegion(Rectangle)","url":"setCroppingRegion(java.awt.Rectangle)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setJPEGQuality(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setScalingFactor(TJScalingFactor)","url":"setScalingFactor(org.libjpegturbo.turbojpeg.TJScalingFactor)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(BufferedImage, int, int, int, int)","url":"setSourceImage(java.awt.image.BufferedImage,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(byte[], int, int, int, int, int, int)","url":"setSourceImage(byte[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setSourceImage(byte[], int)","url":"setSourceImage(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(YUVImage)","url":"setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setSourceImage(YUVImage)","url":"setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage12(short[], int, int, int, int, int, int)","url":"setSourceImage12(short[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage16(short[], int, int, int, int, int, int)","url":"setSourceImage16(short[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSubsamp(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor(BufferedImage, int, int, int, int)","url":"%3Cinit%3E(java.awt.image.BufferedImage,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor(byte[], int, int, int, int, int, int)","url":"%3Cinit%3E(byte[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(byte[], int)","url":"%3Cinit%3E(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(byte[])","url":"%3Cinit%3E(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(YUVImage)","url":"%3Cinit%3E(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String, int)","url":"%3Cinit%3E(java.lang.String,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String, Throwable)","url":"%3Cinit%3E(java.lang.String,java.lang.Throwable)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(Throwable)","url":"%3Cinit%3E(java.lang.Throwable)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"TJScalingFactor(int, int)","url":"%3Cinit%3E(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform(int, int, int, int, int, int, TJCustomFilter)","url":"%3Cinit%3E(int,int,int,int,int,int,org.libjpegturbo.turbojpeg.TJCustomFilter)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform(Rectangle, int, int, TJCustomFilter)","url":"%3Cinit%3E(java.awt.Rectangle,int,int,org.libjpegturbo.turbojpeg.TJCustomFilter)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer(byte[], int)","url":"%3Cinit%3E(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer(byte[])","url":"%3Cinit%3E(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(byte[][], TJTransform[], int)","url":"transform(byte[][],org.libjpegturbo.turbojpeg.TJTransform[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(byte[][], TJTransform[])","url":"transform(byte[][],org.libjpegturbo.turbojpeg.TJTransform[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(TJTransform[], int)","url":"transform(org.libjpegturbo.turbojpeg.TJTransform[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(TJTransform[])","url":"transform(org.libjpegturbo.turbojpeg.TJTransform[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"UNCROPPED"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"UNSCALED"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(byte[], int, int, int, int)","url":"%3Cinit%3E(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(byte[][], int[], int, int[], int, int)","url":"%3Cinit%3E(byte[][],int[],int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(int, int, int, int)","url":"%3Cinit%3E(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(int, int[], int, int)","url":"%3Cinit%3E(int,int[],int,int)"}] \ No newline at end of file +memberSearchIndex = [{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"bufSize(int, int, int)","url":"bufSize(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"bufSizeYUV(int, int, int, int)","url":"bufSizeYUV(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"cf"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"close()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"close()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(byte[], int)","url":"compress(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"compress(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_CMYK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_RGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_YCbCr"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"CS_YCCK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCustomFilter","l":"customFilter(ShortBuffer, Rectangle, Rectangle, int, int, TJTransform)","url":"customFilter(java.nio.ShortBuffer,java.awt.Rectangle,java.awt.Rectangle,int,int,org.libjpegturbo.turbojpeg.TJTransform)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(BufferedImage, int)","url":"decompress(java.awt.image.BufferedImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(byte[], int, int, int, int, int, int, int)","url":"decompress(byte[],int,int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int, int, int, int, int)","url":"decompress(int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int, int, int, int)","url":"decompress(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress(int[], int, int, int, int, int, int, int)","url":"decompress(int[],int,int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress12(int, int)","url":"decompress12(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress12(short[], int, int, int, int)","url":"decompress12(short[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress16(int, int)","url":"decompress16(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress16(short[], int, int, int, int)","url":"decompress16(short[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(BufferedImage)","url":"decompress8(java.awt.image.BufferedImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(byte[], int, int, int, int)","url":"decompress8(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int, int)","url":"decompress8(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompress8(int[], int, int, int, int)","url":"decompress8(int[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int, int, int, int)","url":"decompressToYUV(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int, int[], int, int)","url":"decompressToYUV(int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(int[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(YUVImage, int)","url":"decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"decompressToYUV(YUVImage)","url":"decompressToYUV(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int, int)","url":"encodeYUV(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int[], int)","url":"encodeYUV(int[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(int[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(YUVImage, int)","url":"encodeYUV(org.libjpegturbo.turbojpeg.YUVImage,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"encodeYUV(YUVImage)","url":"encodeYUV(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"equals(TJScalingFactor)","url":"equals(org.libjpegturbo.turbojpeg.TJScalingFactor)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"ERR_FATAL"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"ERR_WARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"finalize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"finalize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_ACCURATEDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_BOTTOMUP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_FASTDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_FASTUPSAMPLE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_LIMITSCANS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"FLAG_STOPONWARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"get(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"get(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getAlphaOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getBlueOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getBuf()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getColorspace()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"getCompressedSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getDenom()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"getErrorCode()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getGreenOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getHeight()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getHeight()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getJPEGBuf()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getJPEGSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getMCUHeight(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getMCUWidth(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getNum()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getOffsets()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getPad()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getPixelSize(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getPlanes()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getRedOffset(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"getScaled(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getScaledHeight(int, int)","url":"getScaledHeight(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getScaledWidth(int, int)","url":"getScaledWidth(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"getScalingFactors()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getSize()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getStrides()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getSubsamp()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getSubsamp()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"getTransformedSizes()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"getWidth()"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"getWidth()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"isOne()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMCS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMERR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"NUMOP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMPF"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"NUMSAMP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"op"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_HFLIP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_NONE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT180"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT270"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_ROT90"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_TRANSPOSE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_TRANSVERSE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OP_VFLIP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_ARITHMETIC"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_COPYNONE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_CROP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_NOOUTPUT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_OPTIMIZE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_PERFECT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"OPT_TRIM"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"options"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_ARITHMETIC"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_BOTTOMUP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_COLORSPACE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_DENSITYUNITS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_FASTDCT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_FASTUPSAMPLE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_JPEGHEIGHT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_JPEGWIDTH"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESSPSV"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_LOSSLESSPT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_MAXMEMORY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_MAXPIXELS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_OPTIMIZE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_PRECISION"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_PROGRESSIVE"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_QUALITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_RESTARTBLOCKS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_RESTARTROWS"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_SCANLIMIT"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_STOPONWARNING"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_SUBSAMP"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_XDENSITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PARAM_YDENSITY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_ABGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_ARGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGRA"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_BGRX"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_CMYK"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGBA"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_RGBX"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_XBGR"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"PF_XRGB"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeHeight(int, int, int)","url":"planeHeight(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeSizeYUV(int, int, int, int, int)","url":"planeSizeYUV(int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"planeWidth(int, int, int)","url":"planeWidth(int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_411"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_420"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_422"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_440"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_441"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_444"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_GRAY"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"SAMP_UNKNOWN"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"set(int, int)","url":"set(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"set(int, int)","url":"set(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"setBuf(byte[], int, int, int, int)","url":"setBuf(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"setBuf(byte[][], int[], int, int[], int, int)","url":"setBuf(byte[][],int[],int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setCroppingRegion(Rectangle)","url":"setCroppingRegion(java.awt.Rectangle)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setJPEGQuality(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setScalingFactor(TJScalingFactor)","url":"setScalingFactor(org.libjpegturbo.turbojpeg.TJScalingFactor)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(BufferedImage, int, int, int, int)","url":"setSourceImage(java.awt.image.BufferedImage,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(byte[], int, int, int, int, int, int)","url":"setSourceImage(byte[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setSourceImage(byte[], int)","url":"setSourceImage(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage(YUVImage)","url":"setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"setSourceImage(YUVImage)","url":"setSourceImage(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage12(short[], int, int, int, int, int, int)","url":"setSourceImage12(short[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSourceImage16(short[], int, int, int, int, int, int)","url":"setSourceImage16(short[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"setSubsamp(int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor(BufferedImage, int, int, int, int)","url":"%3Cinit%3E(java.awt.image.BufferedImage,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJCompressor","l":"TJCompressor(byte[], int, int, int, int, int, int)","url":"%3Cinit%3E(byte[],int,int,int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(byte[], int)","url":"%3Cinit%3E(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(byte[])","url":"%3Cinit%3E(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJDecompressor","l":"TJDecompressor(YUVImage)","url":"%3Cinit%3E(org.libjpegturbo.turbojpeg.YUVImage)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String, int)","url":"%3Cinit%3E(java.lang.String,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String, Throwable)","url":"%3Cinit%3E(java.lang.String,java.lang.Throwable)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(String)","url":"%3Cinit%3E(java.lang.String)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJException","l":"TJException(Throwable)","url":"%3Cinit%3E(java.lang.Throwable)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJScalingFactor","l":"TJScalingFactor(int, int)","url":"%3Cinit%3E(int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform(int, int, int, int, int, int, TJCustomFilter)","url":"%3Cinit%3E(int,int,int,int,int,int,org.libjpegturbo.turbojpeg.TJCustomFilter)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransform","l":"TJTransform(Rectangle, int, int, TJCustomFilter)","url":"%3Cinit%3E(java.awt.Rectangle,int,int,org.libjpegturbo.turbojpeg.TJCustomFilter)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer()","url":"%3Cinit%3E()"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer(byte[], int)","url":"%3Cinit%3E(byte[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"TJTransformer(byte[])","url":"%3Cinit%3E(byte[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(byte[][], TJTransform[], int)","url":"transform(byte[][],org.libjpegturbo.turbojpeg.TJTransform[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(byte[][], TJTransform[])","url":"transform(byte[][],org.libjpegturbo.turbojpeg.TJTransform[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(TJTransform[], int)","url":"transform(org.libjpegturbo.turbojpeg.TJTransform[],int)"},{"p":"org.libjpegturbo.turbojpeg","c":"TJTransformer","l":"transform(TJTransform[])","url":"transform(org.libjpegturbo.turbojpeg.TJTransform[])"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"UNCROPPED"},{"p":"org.libjpegturbo.turbojpeg","c":"TJ","l":"UNSCALED"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(byte[], int, int, int, int)","url":"%3Cinit%3E(byte[],int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(byte[][], int[], int, int[], int, int)","url":"%3Cinit%3E(byte[][],int[],int,int[],int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(int, int, int, int)","url":"%3Cinit%3E(int,int,int,int)"},{"p":"org.libjpegturbo.turbojpeg","c":"YUVImage","l":"YUVImage(int, int[], int, int)","url":"%3Cinit%3E(int,int[],int,int)"}] \ No newline at end of file diff --git a/java/doc/member-search-index.zip b/java/doc/member-search-index.zip index fcc0a1f..ee5589b 100644 Binary files a/java/doc/member-search-index.zip and b/java/doc/member-search-index.zip differ diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJ.html b/java/doc/org/libjpegturbo/turbojpeg/TJ.html index 2051ec2..ea04ee2 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJ.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJ.html @@ -14,7 +14,7 @@ - + @@ -157,35 +157,35 @@ extends java.lang.Object static int CS_CMYK -
        CMYK colorspace.
        +
        CMYK colorspace
        static int CS_GRAY -
        Grayscale colorspace.
        +
        Grayscale colorspace
        static int CS_RGB -
        RGB colorspace.
        +
        RGB colorspace
        static int CS_YCbCr -
        YCbCr colorspace.
        +
        YCbCr colorspace
        static int CS_YCCK -
        YCCK colorspace.
        +
        YCCK colorspace
        @@ -373,9 +373,23 @@ extends java.lang.Object static int +PARAM_MAXMEMORY + +
        Memory limit for intermediate buffers
        + + + +static int +PARAM_MAXPIXELS + +
        Image size limit [decompression, lossless transformation]
        + + + +static int PARAM_OPTIMIZE -
        Optimized baseline entropy coding [lossy compression only]
        +
        Huffman table optimization [lossy compression, lossless transformation]
        @@ -389,7 +403,7 @@ extends java.lang.Object static int PARAM_PROGRESSIVE -
        Progressive entropy coding
        +
        Progressive JPEG
        @@ -403,16 +417,14 @@ extends java.lang.Object static int PARAM_RESTARTBLOCKS -
        JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) - [compression only]
        +
        JPEG restart marker interval in MCUs [lossy compression only]
        static int PARAM_RESTARTROWS -
        JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) - [compression only]
        +
        JPEG restart marker interval in MCU rows [compression only]
        @@ -455,140 +467,140 @@ extends java.lang.Object static int PF_ABGR -
        ABGR pixel format.
        +
        ABGR pixel format
        static int PF_ARGB -
        ARGB pixel format.
        +
        ARGB pixel format
        static int PF_BGR -
        BGR pixel format.
        +
        BGR pixel format
        static int PF_BGRA -
        BGRA pixel format.
        +
        BGRA pixel format
        static int PF_BGRX -
        BGRX pixel format.
        +
        BGRX pixel format
        static int PF_CMYK -
        CMYK pixel format.
        +
        CMYK pixel format
        static int PF_GRAY -
        Grayscale pixel format.
        +
        Grayscale pixel format
        static int PF_RGB -
        RGB pixel format.
        +
        RGB pixel format
        static int PF_RGBA -
        RGBA pixel format.
        +
        RGBA pixel format
        static int PF_RGBX -
        RGBX pixel format.
        +
        RGBX pixel format
        static int PF_XBGR -
        XBGR pixel format.
        +
        XBGR pixel format
        static int PF_XRGB -
        XRGB pixel format.
        +
        XRGB pixel format
        static int SAMP_411 -
        4:1:1 chrominance subsampling.
        +
        4:1:1 chrominance subsampling
        static int SAMP_420 -
        4:2:0 chrominance subsampling.
        +
        4:2:0 chrominance subsampling
        static int SAMP_422 -
        4:2:2 chrominance subsampling.
        +
        4:2:2 chrominance subsampling
        static int SAMP_440 -
        4:4:0 chrominance subsampling.
        +
        4:4:0 chrominance subsampling
        static int SAMP_441 -
        4:4:1 chrominance subsampling.
        +
        4:4:1 chrominance subsampling
        static int SAMP_444 -
        4:4:4 chrominance subsampling (no chrominance subsampling).
        +
        4:4:4 chrominance subsampling (no chrominance subsampling)
        static int SAMP_GRAY -
        Grayscale.
        +
        Grayscale
        static int SAMP_UNKNOWN -
        Unknown subsampling.
        +
        Unknown subsampling
        @@ -674,16 +686,14 @@ extends java.lang.Object static int getMCUHeight​(int subsamp) -
        Returns the MCU block height for the given level of chrominance - subsampling.
        +
        Returns the iMCU height for the given level of chrominance subsampling.
        static int getMCUWidth​(int subsamp) -
        Returns the MCU block width for the given level of chrominance - subsampling.
        +
        Returns the iMCU width for the given level of chrominance subsampling.
        @@ -784,9 +794,10 @@ extends java.lang.Object
      • SAMP_444

        public static final int SAMP_444
        -
        4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG - or YUV image will contain one chrominance component for every pixel in the - source image.
        +
        4:4:4 chrominance subsampling (no chrominance subsampling) + +

        The JPEG or YUV image will contain one chrominance component for every + pixel in the source image.

        See Also:
        Constant Field Values
        @@ -800,8 +811,10 @@ extends java.lang.Object
      • SAMP_422

        public static final int SAMP_422
        -
        4:2:2 chrominance subsampling. The JPEG or YUV image will contain one - chrominance component for every 2x1 block of pixels in the source image.
        +
        4:2:2 chrominance subsampling + +

        The JPEG or YUV image will contain one chrominance component for every + 2x1 block of pixels in the source image.

        See Also:
        Constant Field Values
        @@ -815,8 +828,10 @@ extends java.lang.Object
      • SAMP_420

        public static final int SAMP_420
        -
        4:2:0 chrominance subsampling. The JPEG or YUV image will contain one - chrominance component for every 2x2 block of pixels in the source image.
        +
        4:2:0 chrominance subsampling + +

        The JPEG or YUV image will contain one chrominance component for every + 2x2 block of pixels in the source image.

        See Also:
        Constant Field Values
        @@ -830,7 +845,9 @@ extends java.lang.Object
      • SAMP_GRAY

        public static final int SAMP_GRAY
        -
        Grayscale. The JPEG or YUV image will contain no chrominance components.
        +
        Grayscale + +

        The JPEG or YUV image will contain no chrominance components.

        See Also:
        Constant Field Values
        @@ -844,9 +861,12 @@ extends java.lang.Object
      • SAMP_440

        public static final int SAMP_440
        -
        4:4:0 chrominance subsampling. The JPEG or YUV image will contain one - chrominance component for every 1x2 block of pixels in the source image. - Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.
        +
        4:4:0 chrominance subsampling + +

        The JPEG or YUV image will contain one chrominance component for every + 1x2 block of pixels in the source image. + +

        NOTE: 4:4:0 subsampling is not fully accelerated in libjpeg-turbo.

        See Also:
        Constant Field Values
        @@ -860,14 +880,16 @@ extends java.lang.Object
      • SAMP_411

        public static final int SAMP_411
        -
        4:1:1 chrominance subsampling. The JPEG or YUV image will contain one - chrominance component for every 4x1 block of pixels in the source image. - JPEG images compressed with 4:1:1 subsampling will be almost exactly the - same size as those compressed with 4:2:0 subsampling, and in the - aggregate, both subsampling methods produce approximately the same - perceptual quality. However, 4:1:1 is better able to reproduce sharp - horizontal features. Note that 4:1:1 subsampling is not fully accelerated - in libjpeg-turbo.
        +
        4:1:1 chrominance subsampling + +

        The JPEG or YUV image will contain one chrominance component for every + 4x1 block of pixels in the source image. All else being equal, a JPEG + image with 4:1:1 subsampling is almost exactly the same size as a JPEG + image with 4:2:0 subsampling, and in the aggregate, both subsampling + methods produce approximately the same perceptual quality. However, 4:1:1 + is better able to reproduce sharp horizontal features. + +

        NOTE: 4:1:1 subsampling is not fully accelerated in libjpeg-turbo.

        See Also:
        Constant Field Values
        @@ -881,14 +903,16 @@ extends java.lang.Object
      • SAMP_441

        public static final int SAMP_441
        -
        4:4:1 chrominance subsampling. The JPEG or YUV image will contain one - chrominance component for every 1x4 block of pixels in the source image. - JPEG images compressed with 4:4:1 subsampling will be almost exactly the - same size as those compressed with 4:2:0 subsampling, and in the - aggregate, both subsampling methods produce approximately the same - perceptual quality. However, 4:4:1 is better able to reproduce sharp - vertical features. Note that 4:4:1 subsampling is not fully accelerated - in libjpeg-turbo.
        +
        4:4:1 chrominance subsampling + +

        The JPEG or YUV image will contain one chrominance component for every + 1x4 block of pixels in the source image. All else being equal, a JPEG + image with 4:4:1 subsampling is almost exactly the same size as a JPEG + image with 4:2:0 subsampling, and in the aggregate, both subsampling + methods produce approximately the same perceptual quality. However, 4:4:1 + is better able to reproduce sharp vertical features. + +

        NOTE: 4:4:1 subsampling is not fully accelerated in libjpeg-turbo.

        See Also:
        Constant Field Values
        @@ -902,12 +926,14 @@ extends java.lang.Object
      • SAMP_UNKNOWN

        public static final int SAMP_UNKNOWN
        -
        Unknown subsampling. The JPEG image uses an unusual type of chrominance - subsampling. Such images can be decompressed into packed-pixel images, - but they cannot be +
        Unknown subsampling + +

        The JPEG image uses an unusual type of chrominance subsampling. Such + images can be decompressed into packed-pixel images, but they cannot be

        @@ -938,9 +964,11 @@ extends java.lang.Object
      • PF_RGB

        public static final int PF_RGB
        -
        RGB pixel format. The red, green, and blue components in the image are - stored in 3-sample pixels in the order R, G, B from lowest to highest - memory address within each pixel.
        +
        RGB pixel format + +

        The red, green, and blue components in the image are stored in 3-sample + pixels in the order R, G, B from lowest to highest memory address within + each pixel.

        See Also:
        Constant Field Values
        @@ -954,9 +982,11 @@ extends java.lang.Object
      • PF_BGR

        public static final int PF_BGR
        -
        BGR pixel format. The red, green, and blue components in the image are - stored in 3-sample pixels in the order B, G, R from lowest to highest - memory address within each pixel.
        +
        BGR pixel format + +

        The red, green, and blue components in the image are stored in 3-sample + pixels in the order B, G, R from lowest to highest memory address within + each pixel.

        See Also:
        Constant Field Values
        @@ -970,10 +1000,12 @@ extends java.lang.Object
      • PF_RGBX

        public static final int PF_RGBX
        -
        RGBX pixel format. The red, green, and blue components in the image are - stored in 4-sample pixels in the order R, G, B from lowest to highest - memory address within each pixel. The X component is ignored when - compressing and undefined when decompressing.
        +
        RGBX pixel format + +

        The red, green, and blue components in the image are stored in 4-sample + pixels in the order R, G, B from lowest to highest memory address within + each pixel. The X component is ignored when compressing/encoding and + undefined when decompressing/decoding.

        See Also:
        Constant Field Values
        @@ -987,10 +1019,12 @@ extends java.lang.Object
      • PF_BGRX

        public static final int PF_BGRX
        -
        BGRX pixel format. The red, green, and blue components in the image are - stored in 4-sample pixels in the order B, G, R from lowest to highest - memory address within each pixel. The X component is ignored when - compressing and undefined when decompressing.
        +
        BGRX pixel format + +

        The red, green, and blue components in the image are stored in 4-sample + pixels in the order B, G, R from lowest to highest memory address within + each pixel. The X component is ignored when compressing/encoding and + undefined when decompressing/decoding.

        See Also:
        Constant Field Values
        @@ -1004,10 +1038,12 @@ extends java.lang.Object
      • PF_XBGR

        public static final int PF_XBGR
        -
        XBGR pixel format. The red, green, and blue components in the image are - stored in 4-sample pixels in the order R, G, B from highest to lowest - memory address within each pixel. The X component is ignored when - compressing and undefined when decompressing.
        +
        XBGR pixel format + +

        The red, green, and blue components in the image are stored in 4-sample + pixels in the order R, G, B from highest to lowest memory address within + each pixel. The X component is ignored when compressing/encoding and + undefined when decompressing/decoding.

        See Also:
        Constant Field Values
        @@ -1021,10 +1057,12 @@ extends java.lang.Object
      • PF_XRGB

        public static final int PF_XRGB
        -
        XRGB pixel format. The red, green, and blue components in the image are - stored in 4-sample pixels in the order B, G, R from highest to lowest - memory address within each pixel. The X component is ignored when - compressing and undefined when decompressing.
        +
        XRGB pixel format + +

        The red, green, and blue components in the image are stored in 4-sample + pixels in the order B, G, R from highest to lowest memory address within + each pixel. The X component is ignored when compressing/encoding and + undefined when decompressing/decoding.

        See Also:
        Constant Field Values
        @@ -1038,9 +1076,11 @@ extends java.lang.Object
      • PF_GRAY

        public static final int PF_GRAY
        -
        Grayscale pixel format. Each 1-sample pixel represents a luminance - (brightness) level from 0 to the maximum sample value (255 for 8-bit - samples, 4095 for 12-bit samples, and 65535 for 16-bit samples.)
        +
        Grayscale pixel format + +

        Each 1-sample pixel represents a luminance (brightness) level from 0 to + the maximum sample value (255 for 8-bit samples, 4095 for 12-bit samples, + and 65535 for 16-bit samples.)

        See Also:
        Constant Field Values
        @@ -1054,9 +1094,11 @@ extends java.lang.Object
      • PF_RGBA

        public static final int PF_RGBA
        -
        RGBA pixel format. This is the same as PF_RGBX, except that when - decompressing, the X component is guaranteed to be equal to the maximum - sample value, which can be interpreted as an opaque alpha channel.
        +
        RGBA pixel format + +

        This is the same as PF_RGBX, except that when + decompressing/decoding, the X component is guaranteed to be equal to the + maximum sample value, which can be interpreted as an opaque alpha channel.

        See Also:
        Constant Field Values
        @@ -1070,9 +1112,11 @@ extends java.lang.Object
      • PF_BGRA

        public static final int PF_BGRA
        -
        BGRA pixel format. This is the same as PF_BGRX, except that when - decompressing, the X component is guaranteed to be equal to the maximum - sample value, which can be interpreted as an opaque alpha channel.
        +
        BGRA pixel format + +

        This is the same as PF_BGRX, except that when + decompressing/decoding, the X component is guaranteed to be equal to the + maximum sample value, which can be interpreted as an opaque alpha channel.

        See Also:
        Constant Field Values
        @@ -1086,9 +1130,11 @@ extends java.lang.Object
      • PF_ABGR

        public static final int PF_ABGR
        -
        ABGR pixel format. This is the same as PF_XBGR, except that when - decompressing, the X component is guaranteed to be equal to the maximum - sample value, which can be interpreted as an opaque alpha channel.
        +
        ABGR pixel format + +

        This is the same as PF_XBGR, except that when + decompressing/decoding, the X component is guaranteed to be equal to the + maximum sample value, which can be interpreted as an opaque alpha channel.

        See Also:
        Constant Field Values
        @@ -1102,9 +1148,11 @@ extends java.lang.Object
      • PF_ARGB

        public static final int PF_ARGB
        -
        ARGB pixel format. This is the same as PF_XRGB, except that when - decompressing, the X component is guaranteed to be equal to the maximum - sample value, which can be interpreted as an opaque alpha channel.
        +
        ARGB pixel format + +

        This is the same as PF_XRGB, except that when + decompressing/decoding, the X component is guaranteed to be equal to the + maximum sample value, which can be interpreted as an opaque alpha channel.

        See Also:
        Constant Field Values
        @@ -1118,19 +1166,21 @@ extends java.lang.Object
      • PF_CMYK

        public static final int PF_CMYK
        -
        CMYK pixel format. Unlike RGB, which is an additive color model used - primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive - color model used primarily for printing. In the CMYK color model, the - value of each color component typically corresponds to an amount of cyan, - magenta, yellow, or black ink that is applied to a white background. In - order to convert between CMYK and RGB, it is necessary to use a color - management system (CMS.) A CMS will attempt to map colors within the - printer's gamut to perceptually similar colors in the display's gamut and - vice versa, but the mapping is typically not 1:1 or reversible, nor can it - be defined with a simple formula. Thus, such a conversion is out of scope - for a codec library. However, the TurboJPEG API allows for compressing - packed-pixel CMYK images into YCCK JPEG images (see CS_YCCK) and - decompressing YCCK JPEG images into packed-pixel CMYK images.
        +
        CMYK pixel format + +

        Unlike RGB, which is an additive color model used primarily for + display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive color model used + primarily for printing. In the CMYK color model, the value of each color + component typically corresponds to an amount of cyan, magenta, yellow, or + black ink that is applied to a white background. In order to convert + between CMYK and RGB, it is necessary to use a color management system + (CMS.) A CMS will attempt to map colors within the printer's gamut to + perceptually similar colors in the display's gamut and vice versa, but the + mapping is typically not 1:1 or reversible, nor can it be defined with a + simple formula. Thus, such a conversion is out of scope for a codec + library. However, the TurboJPEG API allows for compressing packed-pixel + CMYK images into YCCK JPEG images (see CS_YCCK) and decompressing + YCCK JPEG images into packed-pixel CMYK images.

        See Also:
        Constant Field Values
        @@ -1158,12 +1208,14 @@ extends java.lang.Object
      • CS_RGB

        public static final int CS_RGB
        -
        RGB colorspace. When compressing the JPEG image, the R, G, and B - components in the source image are reordered into image planes, but no - colorspace conversion or subsampling is performed. RGB JPEG images can be - compressed from and decompressed to packed-pixel images with any of the - extended RGB or grayscale pixel formats, but they cannot be compressed - from or decompressed to planar YUV images.
        +
        RGB colorspace + +

        When generating the JPEG image, the R, G, and B components in the + source image are reordered into image planes, but no colorspace conversion + or subsampling is performed. RGB JPEG images can be generated from and + decompressed to packed-pixel images with any of the extended RGB or + grayscale pixel formats, but they cannot be generated from or + decompressed to planar YUV images.

        See Also:
        Constant Field Values
        @@ -1177,21 +1229,22 @@ extends java.lang.Object
      • CS_YCbCr

        public static final int CS_YCbCr
        -
        YCbCr colorspace. YCbCr is not an absolute colorspace but rather a - mathematical transformation of RGB designed solely for storage and - transmission. YCbCr images must be converted to RGB before they can - actually be displayed. In the YCbCr colorspace, the Y (luminance) - component represents the black & white portion of the original image, - and the Cb and Cr (chrominance) components represent the color portion of - the original image. Originally, the analog equivalent of this - transformation allowed the same signal to drive both black & white and - color televisions, but JPEG images use YCbCr primarily because it allows - the color data to be optionally subsampled for the purposes of reducing - network or disk usage. YCbCr is the most common JPEG colorspace, and - YCbCr JPEG images can be compressed from and decompressed to packed-pixel - images with any of the extended RGB or grayscale pixel formats. YCbCr - JPEG images can also be compressed from and decompressed to planar YUV - images.
        +
        YCbCr colorspace + +

        YCbCr is not an absolute colorspace but rather a mathematical + transformation of RGB designed solely for storage and transmission. YCbCr + images must be converted to RGB before they can be displayed. In the + YCbCr colorspace, the Y (luminance) component represents the black & + white portion of the original image, and the Cb and Cr (chrominance) + components represent the color portion of the original image. + Historically, the analog equivalent of this transformation allowed the + same signal to be displayed to both black & white and color + televisions, but JPEG images use YCbCr primarily because it allows the + color data to be optionally subsampled in order to reduce network and disk + usage. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images + can be generated from and decompressed to packed-pixel images with any of + the extended RGB or grayscale pixel formats. YCbCr JPEG images can also + be generated from and decompressed to planar YUV images.

        See Also:
        Constant Field Values
        @@ -1205,12 +1258,13 @@ extends java.lang.Object
      • CS_GRAY

        public static final int CS_GRAY
        -
        Grayscale colorspace. The JPEG image retains only the luminance data (Y - component), and any color data from the source image is discarded. - Grayscale JPEG images can be compressed from and decompressed to - packed-pixel images with any of the extended RGB or grayscale pixel - formats, or they can be compressed from and decompressed to planar YUV - images.
        +
        Grayscale colorspace + +

        The JPEG image retains only the luminance data (Y component), and any + color data from the source image is discarded. Grayscale JPEG images can + be generated from and decompressed to packed-pixel images with any of the + extended RGB or grayscale pixel formats, or they can be generated from and + decompressed to planar YUV images.

        See Also:
        Constant Field Values
        @@ -1224,11 +1278,12 @@ extends java.lang.Object
      • CS_CMYK

        public static final int CS_CMYK
        -
        CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K - components in the source image are reordered into image planes, but no - colorspace conversion or subsampling is performed. CMYK JPEG images can - only be compressed from and decompressed to packed-pixel images with the - CMYK pixel format.
        +
        CMYK colorspace + +

        When generating the JPEG image, the C, M, Y, and K components in the + source image are reordered into image planes, but no colorspace conversion + or subsampling is performed. CMYK JPEG images can only be generated from + and decompressed to packed-pixel images with the CMYK pixel format.

        See Also:
        Constant Field Values
        @@ -1242,12 +1297,14 @@ extends java.lang.Object
      • CS_YCCK

        public static final int CS_YCCK
        -
        YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but - rather a mathematical transformation of CMYK designed solely for storage - and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be +
        YCCK colorspace + +

        YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a + mathematical transformation of CMYK designed solely for storage and + transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be reversibly transformed into YCCK, and as with YCbCr, the chrominance components in the YCCK pixels can be subsampled without incurring major - perceptual loss. YCCK JPEG images can only be compressed from and + perceptual loss. YCCK JPEG images can only be generated from and decompressed to packed-pixel images with the CMYK pixel format.

        See Also:
        @@ -1336,14 +1393,14 @@ extends java.lang.Object from CMYK to YCCK (see CS_YCCK) as part of the JPEG compression process, some of the Cb and Cr (chrominance) components can be discarded or averaged together to produce a smaller image with little perceptible - loss of image clarity. (The human eye is more sensitive to small changes + loss of image quality. (The human eye is more sensitive to small changes in brightness than to small changes in color.) This is called "chrominance subsampling".

        Value

          -
        • One of TJ.SAMP_* [no default; must be - explicitly specified for lossy compression, encoding, and decoding] +
        • One of TJ.SAMP_* [no default; must be explicitly + specified for lossy compression, encoding, and decoding]
        See Also:
        @@ -1439,7 +1496,7 @@ extends java.lang.Object

        Value

        • 0 [default] Use smooth upsampling when - decompressing a JPEG image that was compressed using chrominance + decompressing a JPEG image that was generated using chrominance subsampling. This creates a smooth transition between neighboring chrominance components in order to reduce upsampling artifacts in the decompressed image. @@ -1481,9 +1538,8 @@ extends java.lang.Object
        • The difference in accuracy between the "fast" and "accurate" algorithms is the most pronounced at JPEG quality levels above 90 and tends to be more pronounced with decompression than with compression. -
        • The "fast" algorithm degrades and is not fully accelerated for JPEG - quality levels above 97, so it will be slower than the "accurate" - algorithm. +
        • For JPEG quality levels above 97, the "fast" algorithm degrades and + is not fully accelerated, so it is slower than the "accurate" algorithm.
      • See Also:
        @@ -1498,7 +1554,7 @@ extends java.lang.Object
      • PARAM_OPTIMIZE

        public static final int PARAM_OPTIMIZE
        -
        Optimized baseline entropy coding [lossy compression only] +
        Huffman table optimization [lossy compression, lossless transformation]

        Value

        -

        Optimized baseline entropy coding will improve compression slightly - (generally 5% or less), but it will reduce compression performance - considerably.

        +

        Huffman table optimization improves compression slightly (generally 5% + or less), but it reduces compression performance considerably.

        See Also:
        Constant Field Values
        @@ -1525,24 +1580,34 @@ extends java.lang.Object
      • PARAM_PROGRESSIVE

        public static final int PARAM_PROGRESSIVE
        -
        Progressive entropy coding +
        Progressive JPEG + +

        In a progressive JPEG image, the DCT coefficients are split across + multiple "scans" of increasing quality. Thus, a low-quality scan + containing the lowest-frequency DCT coefficients can be transmitted first + and refined with subsequent higher-quality scans containing + higher-frequency DCT coefficients. When using Huffman entropy coding, the + progressive JPEG format also provides an "end-of-bands (EOB) run" feature + that allows large groups of zeroes, potentially spanning multiple MCUs, to + be represented using only a few bytes.

        Value

        • 0 [default for compression, lossless - transformation] The lossy JPEG image uses (decompression) or will use - (compression, lossless transformation) baseline entropy coding. -
        • 1 The lossy JPEG image uses (decompression) or will use - (compression, lossless transformation) progressive entropy coding. For - lossless transformation, this can also be specified using + transformation] The lossy JPEG image is (decompression) or will be + (compression, lossless transformation) single-scan. +
        • 1 The lossy JPEG image is (decompression) or will be + (compression, lossless transformation) progressive. For lossless + transformation, this can also be specified using TJTransform.OPT_PROGRESSIVE.
        -

        Progressive entropy coding will generally improve compression relative - to baseline entropy coding, but it will reduce compression and - decompression performance considerably. Can be combined with - PARAM_ARITHMETIC. Implies PARAM_OPTIMIZE unless - PARAM_ARITHMETIC is also set.

        +

        Progressive JPEG images generally have better compression ratios than + single-scan JPEG images (much better if the image has large areas of solid + color), but progressive JPEG compression and decompression is considerably + slower than single-scan JPEG compression and decompression. Can be + combined with PARAM_ARITHMETIC. Implies PARAM_OPTIMIZE + unless PARAM_ARITHMETIC is also set.

        See Also:
        Constant Field Values
        @@ -1559,8 +1624,8 @@ extends java.lang.Object
        Progressive JPEG scan limit for lossy JPEG images [decompression, lossless transformation] -

        Setting this parameter will cause the decompression and transform - functions to return an error if the number of scans in a progressive JPEG +

        Setting this parameter causes the decompression and transform + operations to throw an error if the number of scans in a progressive JPEG image exceeds the specified limit. The primary purpose of this is to allow security-critical applications to guard against an exploit of the progressive JPEG format described in @@ -1569,7 +1634,7 @@ extends java.lang.Object

        Value

        • maximum number of progressive JPEG scans that the decompression and - transform functions will process [default: 0 (no + transform operations will process [default: 0 (no limit)]
        @@ -1599,9 +1664,9 @@ extends java.lang.Object TJTransform.OPT_ARITHMETIC.
      -

      Arithmetic entropy coding will generally improve compression relative - to Huffman entropy coding, but it will reduce compression and - decompression performance considerably. Can be combined with +

      Arithmetic entropy coding generally improves compression relative to + Huffman entropy coding, but it reduces compression and decompression + performance considerably. Can be combined with PARAM_PROGRESSIVE.

      See Also:
      @@ -1626,10 +1691,12 @@ extends java.lang.Object (compression) lossless/predictive.
    -

    In most cases, compressing and decompressing lossless JPEG images is - considerably slower than compressing and decompressing lossy JPEG images. - Also note that the following features are not available with lossless JPEG - images: +

    In most cases, lossless JPEG compression and decompression is + considerably slower than lossy JPEG compression and decompression, and + lossless JPEG images are much larger than lossy JPEG images. Thus, + lossless JPEG images are typically used only for applications that require + mathematically lossless compression. Also note that the following + features are not available with lossless JPEG images:

    • Colorspace conversion (lossless JPEG images always use CS_RGB, CS_GRAY, or CS_CMYK, depending on the @@ -1638,7 +1705,7 @@ extends java.lang.Object SAMP_444)
    • JPEG quality selection
    • DCT/IDCT algorithm selection -
    • Progressive entropy coding +
    • Progressive JPEG
    • Arithmetic entropy coding
    • Compression from/decompression to planar YUV images
    • Decompression scaling @@ -1665,7 +1732,33 @@ extends java.lang.Object
      • 1-7 [default for compression: 1] -
      +
    + +

    Lossless JPEG compression shares no algorithms with lossy JPEG + compression. Instead, it uses differential pulse-code modulation (DPCM), + an algorithm whereby each sample is encoded as the difference between the + sample's value and a "predictor", which is based on the values of + neighboring samples. If Ra is the sample immediately to the left of the + current sample, Rb is the sample immediately above the current sample, and + Rc is the sample diagonally to the left and above the current sample, then + the relationship between the predictor selection value and the predictor + is as follows: + + + + + + + + + + + +
    PSV Predictor
    1 Ra
    2 Rb
    3 Rc
    4 Ra + Rb – Rc
    5 Ra + (Rb – Rc) / 2
    6 Rb + (Ra – Rc) / 2
    7 (Ra + Rb) / 2
    + +

    Predictors 1-3 are 1-dimensional predictors, whereas Predictors 4-7 are + 2-dimensional predictors. The best predictor for a particular image + depends on the image.

    See Also:
    PARAM_LOSSLESS, @@ -1708,8 +1801,7 @@ extends java.lang.Object
  • PARAM_RESTARTBLOCKS

    public static final int PARAM_RESTARTBLOCKS
    -
    JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) - [compression only] +
    JPEG restart marker interval in MCUs [lossy compression only]

    The nature of entropy coding is such that a corrupt JPEG image cannot be decompressed beyond the point of corruption unless it contains restart @@ -1719,10 +1811,19 @@ extends java.lang.Object tolerance of the JPEG image, but adding too many restart markers can adversely affect the compression ratio and performance. +

    In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set + of interleaved "data units" (8x8 DCT blocks if the image is lossy or + samples if the image is lossless) necessary to represent at least one data + unit per component. (For example, an MCU in an interleaved lossy JPEG + image that uses 4:2:2 subsampling consists of two luminance blocks + followed by one block for each chrominance component.) In + single-component or non-interleaved JPEG images, an MCU is the same as a + data unit. +

    Value

      -
    • the number of MCU blocks or samples between each restart marker - [default: 0 (no restart markers)] +
    • the number of MCUs between each restart marker [default: + 0 (no restart markers)]

    Setting this parameter to a non-zero value sets @@ -1740,15 +1841,16 @@ extends java.lang.Object

  • PARAM_RESTARTROWS

    public static final int PARAM_RESTARTROWS
    -
    JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) - [compression only] +
    JPEG restart marker interval in MCU rows [compression only] -

    See PARAM_RESTARTBLOCKS for a description of restart markers. +

    See PARAM_RESTARTBLOCKS for a description of restart markers + and MCUs. An MCU row is a row of MCUs spanning the entire width of the + image.

    Value

      -
    • the number of MCU rows or sample rows between each restart marker - [default: 0 (no restart markers)] +
    • the number of MCU rows between each restart marker [default: + 0 (no restart markers)]

    Setting this parameter to a non-zero value sets @@ -1840,6 +1942,53 @@ extends java.lang.Object

  • + + + +
      +
    • +

      PARAM_MAXMEMORY

      +
      public static final int PARAM_MAXMEMORY
      +
      Memory limit for intermediate buffers + +

      Value +

        +
      • the maximum amount of memory (in megabytes) that will be allocated + for intermediate buffers, which are used with progressive JPEG compression + and decompression, Huffman table optimization, lossless JPEG compression, + and lossless transformation [default: 0 (no limit)] +
      +
      +
      See Also:
      +
      Constant Field Values
      +
      +
    • +
    + + + +
      +
    • +

      PARAM_MAXPIXELS

      +
      public static final int PARAM_MAXPIXELS
      +
      Image size limit [decompression, lossless transformation] + +

      Setting this parameter causes the decompression and transform + operations to throw an error if the number of pixels in the JPEG source + image exceeds the specified limit. This allows security-critical + applications to guard against excessive memory consumption. + +

      Value +

        +
      • maximum number of pixels that the decompression and transform + operations will process [default: 0 (no limit)] +
      +
      +
      See Also:
      +
      Constant Field Values
      +
      +
    • +
    @@ -1982,8 +2131,8 @@ public static final int FLAG_LIMITSCANS
    public static final int ERR_WARNING
    The error was non-fatal and recoverable, but the destination image may still be corrupt. -

    - NOTE: due to the design of the TurboJPEG Java API, only certain methods + +

    NOTE: Due to the design of the TurboJPEG Java API, only certain methods (specifically, TJDecompressor.decompress*() methods with a void return type) will complete and leave the destination image in a fully recoverable state after a non-fatal error occurs.

    @@ -2045,15 +2194,28 @@ public static final int FLAG_LIMITSCANS
  • getMCUWidth

    public static int getMCUWidth​(int subsamp)
    -
    Returns the MCU block width for the given level of chrominance - subsampling.
    +
    Returns the iMCU width for the given level of chrominance subsampling. + +

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + component are interleaved in a single scan. If the image uses chrominance + subsampling, then multiple luminance blocks are stored together, followed + by a single block for each chrominance component. The minimum set of + full-resolution luminance block(s) and corresponding (possibly subsampled) + chrominance blocks necessary to represent at least one DCT block per + component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + two luminance blocks followed by one block for each chrominance + component.) In a non-interleaved lossy JPEG image, each component is + stored in a separate scan, and an MCU is a single DCT block, so we use the + term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an + interleaved JPEG image. For the common case of interleaved JPEG images, + an iMCU is the same as an MCU.

    Parameters:
    subsamp - the level of chrominance subsampling (one of SAMP_*)
    Returns:
    -
    the MCU block width for the given level of chrominance - subsampling.
    +
    the iMCU width for the given level of chrominance subsampling.
  • @@ -2064,15 +2226,28 @@ public static final int FLAG_LIMITSCANS
  • getMCUHeight

    public static int getMCUHeight​(int subsamp)
    -
    Returns the MCU block height for the given level of chrominance - subsampling.
    +
    Returns the iMCU height for the given level of chrominance subsampling. + +

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + component are interleaved in a single scan. If the image uses chrominance + subsampling, then multiple luminance blocks are stored together, followed + by a single block for each chrominance component. The minimum set of + full-resolution luminance block(s) and corresponding (possibly subsampled) + chrominance blocks necessary to represent at least one DCT block per + component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + two luminance blocks followed by one block for each chrominance + component.) In a non-interleaved lossy JPEG image, each component is + stored in a separate scan, and an MCU is a single DCT block, so we use the + term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an + interleaved JPEG image. For the common case of interleaved JPEG images, + an iMCU is the same as an MCU.

    Parameters:
    subsamp - the level of chrominance subsampling (one of SAMP_*)
    Returns:
    -
    the MCU block height for the given level of chrominance - subsampling.
    +
    the iMCU height for the given level of chrominance subsampling.
  • @@ -2102,7 +2277,7 @@ public static final int FLAG_LIMITSCANS
    For the given pixel format, returns the number of samples that the red component is offset from the start of the pixel. For instance, if an 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - char pixel[], then the red component will be + char pixel[], then the red component is pixel[TJ.getRedOffset(TJ.PF_BGRX)].
    Parameters:
    @@ -2123,7 +2298,7 @@ public static final int FLAG_LIMITSCANS
    For the given pixel format, returns the number of samples that the green component is offset from the start of the pixel. For instance, if an 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - char pixel[], then the green component will be + char pixel[], then the green component is pixel[TJ.getGreenOffset(TJ.PF_BGRX)].
    Parameters:
    @@ -2144,7 +2319,7 @@ public static final int FLAG_LIMITSCANS
    For the given pixel format, returns the number of samples that the blue component is offset from the start of the pixel. For instance, if an 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - char pixel[], then the blue component will be + char pixel[], then the blue component is pixel[TJ.getBlueOffset(TJ.PF_BGRX)].
    Parameters:
    @@ -2165,7 +2340,7 @@ public static final int FLAG_LIMITSCANS
    For the given pixel format, returns the number of samples that the alpha component is offset from the start of the pixel. For instance, if an 8-bit-per-sample pixel of format TJ.PF_BGRA is stored in - char pixel[], then the alpha component will be + char pixel[], then the alpha component is pixel[TJ.getAlphaOffset(TJ.PF_BGRA)].
    Parameters:
    @@ -2250,10 +2425,10 @@ public static final int FLAG_LIMITSCANS
    Parameters:
    componentID - ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr)
    -
    width - width (in pixels) of the YUV image. NOTE: this is the width +
    width - width (in pixels) of the YUV image. NOTE: This is the width of the whole image, not the plane width.
    stride - bytes per row in the image plane.
    -
    height - height (in pixels) of the YUV image. NOTE: this is the +
    height - height (in pixels) of the YUV image. NOTE: This is the height of the whole image, not the plane height.
    subsamp - the level of chrominance subsampling used in the YUV image (one of TJ.SAMP_*)
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html index a6e6dfc..168ab1f 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJCompressor.html @@ -14,7 +14,7 @@ - + @@ -326,7 +326,7 @@ implements java.io.Closeable getCompressedSize()
    Returns the size of the image (in bytes) generated by the most recent - compress operation.
    + compression operation. @@ -369,7 +369,7 @@ implements java.io.Closeable int width, int height) -
    Associate an 8-bit-per-pixel packed-pixel RGB or grayscale source image +
    Associate an 8-bit-per-sample packed-pixel RGB or grayscale source image with this compressor instance.
    @@ -677,7 +677,7 @@ implements java.io.Closeable int width, int height) throws TJException -
    Associate an 8-bit-per-pixel packed-pixel RGB or grayscale source image +
    Associate an 8-bit-per-sample packed-pixel RGB or grayscale source image with this compressor instance.
    Parameters:
    @@ -1010,11 +1010,11 @@ public 

    getCompressedSize

    public int getCompressedSize()
    Returns the size of the image (in bytes) generated by the most recent - compress operation.
    + compression operation.
    Returns:
    the size of the image (in bytes) generated by the most recent - compress operation.
    + compression operation.
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html index 536f400..68d26d9 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJCustomFilter.html @@ -14,7 +14,7 @@ - + @@ -153,7 +153,7 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height")); int transformID,
    TJTransform transform) -
    A callback function that can be used to modify the DCT coefficients after +
    A callback method that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image.
    @@ -188,21 +188,21 @@ $('.navPadding').css('padding-top', $('.fixedNav').css("height")); int transformID, TJTransform transform) throws TJException -
    A callback function that can be used to modify the DCT coefficients after +
    A callback method that can be used to modify the DCT coefficients after they are losslessly transformed but before they are transcoded to a new JPEG image. This allows for custom filters or other transformations to be applied in the frequency domain.
    Parameters:
    coeffBuffer - a buffer containing transformed DCT coefficients. - (NOTE: this buffer is not guaranteed to be valid once the callback + (NOTE: This buffer is not guaranteed to be valid once the callback returns, so applications wishing to hand off the DCT coefficients to - another function or library should make a copy of them within the body of - the callback.)
    + another method should make a copy of them within the body of the + callback.)
    bufferRegion - rectangle containing the width and height of coeffBuffer as well as its offset relative to the component plane. TurboJPEG implementations may choose to split each component plane - into multiple DCT coefficient buffers and call the callback function once + into multiple DCT coefficient buffers and call the callback method once for each buffer.
    planeRegion - rectangle containing the width and height of the component plane to which coeffBuffer belongs
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html index 06de168..7a66c20 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJDecompressor.html @@ -14,7 +14,7 @@ - + @@ -838,8 +838,8 @@ implements java.io.Closeable with the JPEG image width and height (see getWidth() and getHeight().) When decompressing into a planar YUV image, an intermediate buffer copy will be performed if the width or height of the - scaled destination image is not an even multiple of the MCU block size - (see TJ.getMCUWidth() and TJ.getMCUHeight().) Note that decompression scaling is not available + scaled destination image is not an even multiple of the iMCU size (see + TJ.getMCUWidth() and TJ.getMCUHeight().) Note that decompression scaling is not available (and the specified scaling factor is ignored) when decompressing lossless JPEG images (see TJ.PARAM_LOSSLESS), since the IDCT algorithm is not used with those images. Note also that TJ.PARAM_FASTDCT is @@ -862,14 +862,14 @@ implements java.io.Closeable
    croppingRegion - java.awt.Rectangle instance that specifies a subregion of the JPEG image to decompress, or TJ.UNCROPPED for no cropping. The left boundary of the cropping - region must be evenly divisible by the scaled MCU block width, which can - be determined by calling TJScalingFactor.getScaled() with the specified scaling factor (see - setScalingFactor()) and the MCU block width - (see TJ.getMCUWidth()) for the level of chrominance + region must be evenly divisible by the scaled iMCU width, which can be + determined by calling TJScalingFactor.getScaled() with the specified scaling factor (see + setScalingFactor()) and the iMCU width (see + TJ.getMCUWidth()) for the level of chrominance subsampling in the JPEG image (see TJ.PARAM_SUBSAMP.) The cropping region should be specified relative to the scaled image dimensions. Unless croppingRegion is TJ.UNCROPPED, - the JPEG header must be read (see setSourceImage(byte[], int) + the JPEG header must be read (see setSourceImage(byte[], int)) prior to calling this method.
    Throws:
    TJException
    @@ -980,9 +980,9 @@ public int getScaledHeight​(int desiredWidth, source image associated with this decompressor instance and output an 8-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given destination buffer. -

    - NOTE: The destination image is fully recoverable if this method throws a - non-fatal TJException (unless TJ.PARAM_STOPONWARNING is + +

    NOTE: The destination image is fully recoverable if this method throws + a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    @@ -1011,7 +1011,7 @@ public int getScaledHeight​(int desiredWidth, TJ.getPixelSize(pixelFormat).) However, you can also use this parameter to specify the row alignment/padding of the destination image, to skip rows, or to decompress/decode into a - specific region of a larger image. NOTE: if the source image is a lossy + specific region of a larger image. NOTE: If the source image is a lossy JPEG image, then destinationWidth is either the scaled JPEG width (see setScalingFactor(), TJScalingFactor.getScaled(), and @@ -1118,9 +1118,9 @@ public byte[] decompress​(int desiredWidth,
    Decompress the 12-bit-per-sample JPEG source image associated with this decompressor instance and output a 12-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given destination buffer. -

    - NOTE: The destination image is fully recoverable if this method throws a - non-fatal TJException (unless TJ.PARAM_STOPONWARNING is + +

    NOTE: The destination image is fully recoverable if this method throws + a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    @@ -1150,7 +1150,7 @@ public byte[] decompress​(int desiredWidth, TJ.getPixelSize(pixelFormat).) However, you can also use this parameter to specify the row alignment/padding of the destination image, to skip rows, or to decompress into a specific - region of a larger image. NOTE: if the source image is a lossy JPEG + region of a larger image. NOTE: If the source image is a lossy JPEG image, then destinationWidth is either the scaled JPEG width (see setScalingFactor(), TJScalingFactor.getScaled(), and @@ -1184,7 +1184,7 @@ public byte[] decompress​(int desiredWidth,
    pixelFormat - pixel format of the decompressed image (one of TJ.PF_*)
    Returns:
    -
    a buffer containing an 8-bit-per-sample packed-pixel decompressed +
    a buffer containing a 12-bit-per-sample packed-pixel decompressed image.
    Throws:
    TJException
    @@ -1207,9 +1207,9 @@ public byte[] decompress​(int desiredWidth, with this decompressor instance and output a 16-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given destination buffer. -

    - NOTE: The destination image is fully recoverable if this method throws a - non-fatal TJException (unless TJ.PARAM_STOPONWARNING is + +

    NOTE: The destination image is fully recoverable if this method throws + a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    @@ -1258,7 +1258,7 @@ public byte[] decompress​(int desiredWidth,
    pixelFormat - pixel format of the decompressed image (one of TJ.PF_*)
    Returns:
    -
    a buffer containing an 8-bit-per-sample packed-pixel decompressed +
    a buffer containing a 16-bit-per-sample packed-pixel decompressed image.
    Throws:
    TJException
    @@ -1279,9 +1279,9 @@ public byte[] decompress​(int desiredWidth, decompression but leaves out the color conversion step, so a planar YUV image is generated instead of a packed-pixel image. This method cannot be used to decompress JPEG source images with the CMYK or YCCK colorspace. -

    - NOTE: The planar YUV destination image is fully recoverable if this method - throws a non-fatal TJException (unless + +

    NOTE: The planar YUV destination image is fully recoverable if this + method throws a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    @@ -1432,9 +1432,9 @@ public  source image associated with this decompressor instance and output an 8-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given destination buffer. -

    - NOTE: The destination image is fully recoverable if this method throws a - non-fatal TJException (unless TJ.PARAM_STOPONWARNING + +

    NOTE: The destination image is fully recoverable if this method throws + a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    @@ -1460,7 +1460,7 @@ public  should be set to destinationWidth. (Setting this parameter to 0 is the equivalent of setting it to destinationWidth.) However, you can also use this parameter to skip rows or to - decompress/decode into a specific region of a larger image. NOTE: if the + decompress/decode into a specific region of a larger image. NOTE: If the source image is a lossy JPEG image, then destinationWidth is either the scaled JPEG width (see setScalingFactor(), TJScalingFactor.getScaled(), and getWidth()) or the width of the cropping region (see setCroppingRegion().) If @@ -1511,9 +1511,9 @@ public void decompress​(int[] dstBuf, source image associated with this decompressor instance and output an 8-bit-per-sample packed-pixel decompressed/decoded image to the given BufferedImage instance. -

    - NOTE: The destination image is fully recoverable if this method throws a - non-fatal TJException (unless TJ.PARAM_STOPONWARNING + +

    NOTE: The destination image is fully recoverable if this method throws + a non-fatal TJException (unless TJ.PARAM_STOPONWARNING is set.)

    Parameters:
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJException.html b/java/doc/org/libjpegturbo/turbojpeg/TJException.html index 5c2905d..a5e9841 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJException.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJException.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html index caa5c58..6fe0a36 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJScalingFactor.html @@ -14,7 +14,7 @@ - + @@ -299,9 +299,9 @@ extends java.lang.Object
  • getScaled

    public int getScaled​(int dimension)
    -
    Returns the scaled value of dimension. This function - performs the integer equivalent of - ceil(dimension * scalingFactor).
    +
    Returns the scaled value of dimension. This method performs + the integer equivalent of + Math.ceil(dimension * scalingFactor).
    Parameters:
    dimension - width or height to multiply by this scaling factor
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html b/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html index 0c2f5cc..0c4cf15 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJTransform.html @@ -14,7 +14,7 @@ - + @@ -269,54 +269,51 @@ extends java.awt.Rectangle static int OPT_ARITHMETIC -
    This option will enable arithmetic entropy coding in the JPEG image - generated by this particular transform.
    +
    Enable arithmetic entropy coding in the destination image.
    static int OPT_COPYNONE -
    This option will prevent TJTransformer.transform() from copying any extra markers (including EXIF - and ICC profile data) from the source image to the destination image.
    +
    Do not copy any extra markers (including Exif and ICC profile data) from + the source image to the destination image.
    static int OPT_CROP -
    This option will enable lossless cropping.
    +
    Enable lossless cropping.
    static int OPT_GRAY -
    This option will discard the color data in the source image and produce a - grayscale destination image.
    +
    Discard the color data in the source image, and generate a grayscale + destination image.
    static int OPT_NOOUTPUT -
    This option will prevent TJTransformer.transform() from outputting a JPEG image for this - particular transform.
    +
    Do not generate a destination image.
    static int OPT_OPTIMIZE -
    This option will enable optimized baseline entropy coding in the JPEG - image generated by this particular transform.
    +
    Enable Huffman table optimization for the destination image.
    static int OPT_PERFECT -
    This option will cause TJTransformer.transform() to throw an exception if the transform is not +
    This option causes TJTransformer.transform() to throw an exception if the transform is not perfect.
    @@ -324,16 +321,15 @@ extends java.awt.Rectangle static int OPT_PROGRESSIVE -
    This option will enable progressive entropy coding in the JPEG image - generated by this particular transform.
    +
    Generate a progressive destination image instead of a single-scan + destination image.
    static int OPT_TRIM -
    This option will discard any partial MCU blocks that cannot be - transformed.
    +
    Discard any partial iMCUs that cannot be transformed.
    @@ -500,7 +496,7 @@ extends java.awt.Rectangle

    OP_HFLIP

    public static final int OP_HFLIP
    Flip (mirror) image horizontally. This transform is imperfect if there - are any partial MCU blocks on the right edge.
    + are any partial iMCUs on the right edge.
    See Also:
    OPT_PERFECT, @@ -516,7 +512,7 @@ extends java.awt.Rectangle

    OP_VFLIP

    public static final int OP_VFLIP
    Flip (mirror) image vertically. This transform is imperfect if there are - any partial MCU blocks on the bottom edge.
    + any partial iMCUs on the bottom edge.
    See Also:
    OPT_PERFECT, @@ -548,8 +544,8 @@ extends java.awt.Rectangle

    OP_TRANSVERSE

    public static final int OP_TRANSVERSE
    Transverse transpose image (flip/mirror along upper right to lower left - axis). This transform is imperfect if there are any partial MCU blocks in - the image.
    + axis). This transform is imperfect if there are any partial iMCUs in the + image.
    See Also:
    OPT_PERFECT, @@ -565,7 +561,7 @@ extends java.awt.Rectangle

    OP_ROT90

    public static final int OP_ROT90
    Rotate image clockwise by 90 degrees. This transform is imperfect if - there are any partial MCU blocks on the bottom edge.
    + there are any partial iMCUs on the bottom edge.
    See Also:
    OPT_PERFECT, @@ -581,7 +577,7 @@ extends java.awt.Rectangle

    OP_ROT180

    public static final int OP_ROT180
    Rotate image 180 degrees. This transform is imperfect if there are any - partial MCU blocks in the image.
    + partial iMCUs in the image.
    See Also:
    OPT_PERFECT, @@ -597,7 +593,7 @@ extends java.awt.Rectangle

    OP_ROT270

    public static final int OP_ROT270
    Rotate image counter-clockwise by 90 degrees. This transform is imperfect - if there are any partial MCU blocks on the right edge.
    + if there are any partial iMCUs on the right edge.
    See Also:
    OPT_PERFECT, @@ -612,16 +608,16 @@ extends java.awt.Rectangle
  • OPT_PERFECT

    public static final int OPT_PERFECT
    -
    This option will cause TJTransformer.transform() to throw an exception if the transform is not - perfect. Lossless transforms operate on MCU blocks, whose size depends on - the level of chrominance subsampling used. If the image's width or height - is not evenly divisible by the MCU block size (see TJ.getMCUWidth() and TJ.getMCUHeight()), then - there will be partial MCU blocks on the right and/or bottom edges. It is - not possible to move these partial MCU blocks to the top or left of the - image, so any transform that would require that is "imperfect." If this - option is not specified, then any partial MCU blocks that cannot be - transformed will be left in place, which will create odd-looking strips on - the right or bottom edge of the image.
    +
    This option causes TJTransformer.transform() to throw an exception if the transform is not + perfect. Lossless transforms operate on iMCUs, the size of which depends + on the level of chrominance subsampling used. If the image's width or + height is not evenly divisible by the iMCU size (see TJ.getMCUWidth() and TJ.getMCUHeight()), then + there will be partial iMCUs on the right and/or bottom edges. It is not + possible to move these partial iMCUs to the top or left of the image, so + any transform that would require that is "imperfect." If this option is + not specified, then any partial iMCUs that cannot be transformed will be + left in place, which will create odd-looking strips on the right or bottom + edge of the image.
    See Also:
    Constant Field Values
    @@ -635,8 +631,7 @@ extends java.awt.Rectangle
  • OPT_TRIM

    public static final int OPT_TRIM
    -
    This option will discard any partial MCU blocks that cannot be - transformed.
    +
    Discard any partial iMCUs that cannot be transformed.
    See Also:
    Constant Field Values
    @@ -650,7 +645,7 @@ extends java.awt.Rectangle
  • OPT_CROP

    public static final int OPT_CROP
    -
    This option will enable lossless cropping.
    +
    Enable lossless cropping.
    See Also:
    Constant Field Values
    @@ -664,8 +659,8 @@ extends java.awt.Rectangle
  • OPT_GRAY

    public static final int OPT_GRAY
    -
    This option will discard the color data in the source image and produce a - grayscale destination image.
    +
    Discard the color data in the source image, and generate a grayscale + destination image.
    See Also:
    Constant Field Values
    @@ -679,10 +674,9 @@ extends java.awt.Rectangle
  • OPT_NOOUTPUT

    public static final int OPT_NOOUTPUT
    -
    This option will prevent TJTransformer.transform() from outputting a JPEG image for this - particular transform. This can be used in conjunction with a custom - filter to capture the transformed DCT coefficients without transcoding - them.
    +
    Do not generate a destination image. This can be used in conjunction with + a custom filter to capture the transformed DCT coefficients without + transcoding them.
    See Also:
    Constant Field Values
    @@ -696,12 +690,13 @@ extends java.awt.Rectangle
  • OPT_PROGRESSIVE

    public static final int OPT_PROGRESSIVE
    -
    This option will enable progressive entropy coding in the JPEG image - generated by this particular transform. Progressive entropy coding will - generally improve compression relative to baseline entropy coding (the - default), but it will reduce decompression performance considerably. - Can be combined with OPT_ARITHMETIC. Implies - OPT_OPTIMIZE unless OPT_ARITHMETIC is also specified.
    +
    Generate a progressive destination image instead of a single-scan + destination image. Progressive JPEG images generally have better + compression ratios than single-scan JPEG images (much better if the image + has large areas of solid color), but progressive JPEG decompression is + considerably slower than single-scan JPEG decompression. Can be combined + with OPT_ARITHMETIC. Implies OPT_OPTIMIZE unless + OPT_ARITHMETIC is also specified.
    See Also:
    Constant Field Values
    @@ -715,8 +710,8 @@ extends java.awt.Rectangle
  • OPT_COPYNONE

    public static final int OPT_COPYNONE
    -
    This option will prevent TJTransformer.transform() from copying any extra markers (including EXIF - and ICC profile data) from the source image to the destination image.
    +
    Do not copy any extra markers (including Exif and ICC profile data) from + the source image to the destination image.
    See Also:
    Constant Field Values
    @@ -730,11 +725,10 @@ extends java.awt.Rectangle
  • OPT_ARITHMETIC

    public static final int OPT_ARITHMETIC
    -
    This option will enable arithmetic entropy coding in the JPEG image - generated by this particular transform. Arithmetic entropy coding will - generally improve compression relative to Huffman entropy coding (the - default), but it will reduce decompression performance considerably. Can - be combined with OPT_PROGRESSIVE.
    +
    Enable arithmetic entropy coding in the destination image. Arithmetic + entropy coding generally improves compression relative to Huffman entropy + coding (the default), but it reduces decompression performance + considerably. Can be combined with OPT_PROGRESSIVE.
    See Also:
    Constant Field Values
    @@ -748,9 +742,8 @@ extends java.awt.Rectangle
  • OPT_OPTIMIZE

    public static final int OPT_OPTIMIZE
    -
    This option will enable optimized baseline entropy coding in the JPEG - image generated by this particular transform. Optimized baseline entropy - coding will improve compression slightly (generally 5% or less.)
    +
    Enable Huffman table optimization for the destination image. Huffman + table optimization improves compression slightly (generally 5% or less.)
    See Also:
    Constant Field Values
    @@ -825,9 +818,10 @@ extends java.awt.Rectangle
    Parameters:
    x - the left boundary of the cropping region. This must be evenly - divisible by the MCU block width (see TJ.getMCUWidth())
    + divisible by the iMCU width (see TJ.getMCUWidth()) + of the destination image.
  • y - the upper boundary of the cropping region. This must be evenly - divisible by the MCU block height (see TJ.getMCUHeight())
    + divisible by the iMCU height (see TJ.getMCUHeight()) of the destination image.
    w - the width of the cropping region. Setting this to 0 is the equivalent of setting it to (width of the source JPEG image - x).
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html b/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html index 83836ea..0ae19bf 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html +++ b/java/doc/org/libjpegturbo/turbojpeg/TJTransformer.html @@ -14,7 +14,7 @@ - + @@ -379,7 +379,8 @@ extends TJ.bufSize() to determine the maximum size for each buffer based on the transformed or cropped width and height and the level - of subsampling used in the source image.
    + of subsampling used in the destination image (taking into account + grayscale conversion and transposition of the width and height.)
    transforms - an array of TJTransform instances, each of which specifies the transform parameters and/or cropping region for the corresponding transformed JPEG image
    diff --git a/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html b/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html index 2654c21..8c3a3d4 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html +++ b/java/doc/org/libjpegturbo/turbojpeg/YUVImage.html @@ -14,7 +14,7 @@ - + @@ -139,15 +139,15 @@ extends java.lang.Object serves as the destination image for YUV encode and decompress-to-YUV operations and as the source image for compress-from-YUV and YUV decode operations. -

    - Technically, the JPEG format uses the YCbCr colorspace (which is technically - not a colorspace but a color transform), but per the convention of the - digital video community, the TurboJPEG API uses "YUV" to refer to an image - format consisting of Y, Cb, and Cr image planes. -

    - Each plane is simply a 2D array of bytes, each byte representing the value - of one of the components (Y, Cb, or Cr) at a particular location in the - image. The width and height of each plane are determined by the image + +

    Technically, the JPEG format uses the YCbCr colorspace (which is + technically not a colorspace but a color transform), but per the convention + of the digital video community, the TurboJPEG API uses "YUV" to refer to an + image format consisting of Y, Cb, and Cr image planes. + +

    Each plane is simply a 2D array of bytes, each byte representing the + value of one of the components (Y, Cb, or Cr) at a particular location in + the image. The width and height of each plane are determined by the image width, height, and level of chrominance subsampling. The luminance plane width is the image width padded to the nearest multiple of the horizontal subsampling factor (1 in the case of 4:4:4, grayscale, 4:4:0, or 4:4:1; 2 in @@ -160,9 +160,9 @@ extends java.lang.Object the luminance plane width divided by the horizontal subsampling factor, and the chrominance plane height is equal to the luminance plane height divided by the vertical subsampling factor. -

    - For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is - used, then the luminance plane would be 36 x 35 bytes, and each of the + +

    For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling + is used, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 18 x 35 bytes. If you specify a row alignment of 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, and each of the chrominance planes would be 20 x 35 bytes. diff --git a/java/doc/org/libjpegturbo/turbojpeg/package-summary.html b/java/doc/org/libjpegturbo/turbojpeg/package-summary.html index 0a027c3..6dd636b 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/package-summary.html +++ b/java/doc/org/libjpegturbo/turbojpeg/package-summary.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/org/libjpegturbo/turbojpeg/package-tree.html b/java/doc/org/libjpegturbo/turbojpeg/package-tree.html index ca8d36a..b6af5f3 100644 --- a/java/doc/org/libjpegturbo/turbojpeg/package-tree.html +++ b/java/doc/org/libjpegturbo/turbojpeg/package-tree.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/overview-tree.html b/java/doc/overview-tree.html index d2d6d53..7da8bce 100644 --- a/java/doc/overview-tree.html +++ b/java/doc/overview-tree.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/package-search-index.zip b/java/doc/package-search-index.zip index b55d555..3fae6c9 100644 Binary files a/java/doc/package-search-index.zip and b/java/doc/package-search-index.zip differ diff --git a/java/doc/serialized-form.html b/java/doc/serialized-form.html index 33cde53..58e94ab 100644 --- a/java/doc/serialized-form.html +++ b/java/doc/serialized-form.html @@ -14,7 +14,7 @@ - + diff --git a/java/doc/type-search-index.zip b/java/doc/type-search-index.zip index 3f8aad1..e6b014e 100644 Binary files a/java/doc/type-search-index.zip and b/java/doc/type-search-index.zip differ diff --git a/java/org/libjpegturbo/turbojpeg/TJ.java b/java/org/libjpegturbo/turbojpeg/TJ.java index 65f7ad3..cb60c29 100644 --- a/java/org/libjpegturbo/turbojpeg/TJ.java +++ b/java/org/libjpegturbo/turbojpeg/TJ.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2013, 2017-2018, 2020-2023 D. R. Commander. + * Copyright (C)2011-2013, 2017-2018, 2020-2024 D. R. Commander. * All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * @@ -44,60 +44,76 @@ public final class TJ { */ public static final int NUMSAMP = 7; /** - * 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG - * or YUV image will contain one chrominance component for every pixel in the - * source image. + * 4:4:4 chrominance subsampling (no chrominance subsampling) + * + *

    The JPEG or YUV image will contain one chrominance component for every + * pixel in the source image. */ public static final int SAMP_444 = 0; /** - * 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 2x1 block of pixels in the source image. + * 4:2:2 chrominance subsampling + * + *

    The JPEG or YUV image will contain one chrominance component for every + * 2x1 block of pixels in the source image. */ public static final int SAMP_422 = 1; /** - * 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 2x2 block of pixels in the source image. + * 4:2:0 chrominance subsampling + * + *

    The JPEG or YUV image will contain one chrominance component for every + * 2x2 block of pixels in the source image. */ public static final int SAMP_420 = 2; /** - * Grayscale. The JPEG or YUV image will contain no chrominance components. + * Grayscale + * + *

    The JPEG or YUV image will contain no chrominance components. */ public static final int SAMP_GRAY = 3; /** - * 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 1x2 block of pixels in the source image. - * Note that 4:4:0 subsampling is not fully accelerated in libjpeg-turbo. + * 4:4:0 chrominance subsampling + * + *

    The JPEG or YUV image will contain one chrominance component for every + * 1x2 block of pixels in the source image. + * + *

    NOTE: 4:4:0 subsampling is not fully accelerated in libjpeg-turbo. */ public static final int SAMP_440 = 4; /** - * 4:1:1 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 4x1 block of pixels in the source image. - * JPEG images compressed with 4:1:1 subsampling will be almost exactly the - * same size as those compressed with 4:2:0 subsampling, and in the - * aggregate, both subsampling methods produce approximately the same - * perceptual quality. However, 4:1:1 is better able to reproduce sharp - * horizontal features. Note that 4:1:1 subsampling is not fully accelerated - * in libjpeg-turbo. + * 4:1:1 chrominance subsampling + * + *

    The JPEG or YUV image will contain one chrominance component for every + * 4x1 block of pixels in the source image. All else being equal, a JPEG + * image with 4:1:1 subsampling is almost exactly the same size as a JPEG + * image with 4:2:0 subsampling, and in the aggregate, both subsampling + * methods produce approximately the same perceptual quality. However, 4:1:1 + * is better able to reproduce sharp horizontal features. + * + *

    NOTE: 4:1:1 subsampling is not fully accelerated in libjpeg-turbo. */ public static final int SAMP_411 = 5; /** - * 4:4:1 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 1x4 block of pixels in the source image. - * JPEG images compressed with 4:4:1 subsampling will be almost exactly the - * same size as those compressed with 4:2:0 subsampling, and in the - * aggregate, both subsampling methods produce approximately the same - * perceptual quality. However, 4:4:1 is better able to reproduce sharp - * vertical features. Note that 4:4:1 subsampling is not fully accelerated - * in libjpeg-turbo. + * 4:4:1 chrominance subsampling + * + *

    The JPEG or YUV image will contain one chrominance component for every + * 1x4 block of pixels in the source image. All else being equal, a JPEG + * image with 4:4:1 subsampling is almost exactly the same size as a JPEG + * image with 4:2:0 subsampling, and in the aggregate, both subsampling + * methods produce approximately the same perceptual quality. However, 4:4:1 + * is better able to reproduce sharp vertical features. + * + *

    NOTE: 4:4:1 subsampling is not fully accelerated in libjpeg-turbo. */ public static final int SAMP_441 = 6; /** - * Unknown subsampling. The JPEG image uses an unusual type of chrominance - * subsampling. Such images can be decompressed into packed-pixel images, - * but they cannot be + * Unknown subsampling + * + *

    The JPEG image uses an unusual type of chrominance subsampling. Such + * images can be decompressed into packed-pixel images, but they cannot be *

      *
    • decompressed into planar YUV images, - *
    • losslessly transformed if {@link TJTransform#OPT_CROP} is specified, + *
    • losslessly transformed if {@link TJTransform#OPT_CROP} is specified + * and {@link TJTransform#OPT_GRAY} is not specified, * or *
    • partially decompressed using a cropping region. *
    @@ -105,14 +121,27 @@ public final class TJ { public static final int SAMP_UNKNOWN = -1; /** - * Returns the MCU block width for the given level of chrominance - * subsampling. + * Returns the iMCU width for the given level of chrominance subsampling. + * + *

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + * component are interleaved in a single scan. If the image uses chrominance + * subsampling, then multiple luminance blocks are stored together, followed + * by a single block for each chrominance component. The minimum set of + * full-resolution luminance block(s) and corresponding (possibly subsampled) + * chrominance blocks necessary to represent at least one DCT block per + * component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + * in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + * two luminance blocks followed by one block for each chrominance + * component.) In a non-interleaved lossy JPEG image, each component is + * stored in a separate scan, and an MCU is a single DCT block, so we use the + * term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an + * interleaved JPEG image. For the common case of interleaved JPEG images, + * an iMCU is the same as an MCU. * * @param subsamp the level of chrominance subsampling (one of * {@link #SAMP_444 SAMP_*}) * - * @return the MCU block width for the given level of chrominance - * subsampling. + * @return the iMCU width for the given level of chrominance subsampling. */ public static int getMCUWidth(int subsamp) { checkSubsampling(subsamp); @@ -125,14 +154,27 @@ public final class TJ { /** - * Returns the MCU block height for the given level of chrominance - * subsampling. + * Returns the iMCU height for the given level of chrominance subsampling. + * + *

    In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + * component are interleaved in a single scan. If the image uses chrominance + * subsampling, then multiple luminance blocks are stored together, followed + * by a single block for each chrominance component. The minimum set of + * full-resolution luminance block(s) and corresponding (possibly subsampled) + * chrominance blocks necessary to represent at least one DCT block per + * component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + * in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + * two luminance blocks followed by one block for each chrominance + * component.) In a non-interleaved lossy JPEG image, each component is + * stored in a separate scan, and an MCU is a single DCT block, so we use the + * term "iMCU" (interleaved MCU) to refer to the equivalent of an MCU in an + * interleaved JPEG image. For the common case of interleaved JPEG images, + * an iMCU is the same as an MCU. * * @param subsamp the level of chrominance subsampling (one of * {@link #SAMP_444 SAMP_*}) * - * @return the MCU block height for the given level of chrominance - * subsampling. + * @return the iMCU height for the given level of chrominance subsampling. */ public static int getMCUHeight(int subsamp) { checkSubsampling(subsamp); @@ -149,89 +191,113 @@ public final class TJ { */ public static final int NUMPF = 12; /** - * RGB pixel format. The red, green, and blue components in the image are - * stored in 3-sample pixels in the order R, G, B from lowest to highest - * memory address within each pixel. + * RGB pixel format + * + *

    The red, green, and blue components in the image are stored in 3-sample + * pixels in the order R, G, B from lowest to highest memory address within + * each pixel. */ public static final int PF_RGB = 0; /** - * BGR pixel format. The red, green, and blue components in the image are - * stored in 3-sample pixels in the order B, G, R from lowest to highest - * memory address within each pixel. + * BGR pixel format + * + *

    The red, green, and blue components in the image are stored in 3-sample + * pixels in the order B, G, R from lowest to highest memory address within + * each pixel. */ public static final int PF_BGR = 1; /** - * RGBX pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order R, G, B from lowest to highest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * RGBX pixel format + * + *

    The red, green, and blue components in the image are stored in 4-sample + * pixels in the order R, G, B from lowest to highest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ public static final int PF_RGBX = 2; /** - * BGRX pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order B, G, R from lowest to highest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * BGRX pixel format + * + *

    The red, green, and blue components in the image are stored in 4-sample + * pixels in the order B, G, R from lowest to highest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ public static final int PF_BGRX = 3; /** - * XBGR pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order R, G, B from highest to lowest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * XBGR pixel format + * + *

    The red, green, and blue components in the image are stored in 4-sample + * pixels in the order R, G, B from highest to lowest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ public static final int PF_XBGR = 4; /** - * XRGB pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order B, G, R from highest to lowest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * XRGB pixel format + * + *

    The red, green, and blue components in the image are stored in 4-sample + * pixels in the order B, G, R from highest to lowest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ public static final int PF_XRGB = 5; /** - * Grayscale pixel format. Each 1-sample pixel represents a luminance - * (brightness) level from 0 to the maximum sample value (255 for 8-bit - * samples, 4095 for 12-bit samples, and 65535 for 16-bit samples.) + * Grayscale pixel format + * + *

    Each 1-sample pixel represents a luminance (brightness) level from 0 to + * the maximum sample value (255 for 8-bit samples, 4095 for 12-bit samples, + * and 65535 for 16-bit samples.) */ public static final int PF_GRAY = 6; /** - * RGBA pixel format. This is the same as {@link #PF_RGBX}, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * RGBA pixel format + * + *

    This is the same as {@link #PF_RGBX}, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ public static final int PF_RGBA = 7; /** - * BGRA pixel format. This is the same as {@link #PF_BGRX}, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * BGRA pixel format + * + *

    This is the same as {@link #PF_BGRX}, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ public static final int PF_BGRA = 8; /** - * ABGR pixel format. This is the same as {@link #PF_XBGR}, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * ABGR pixel format + * + *

    This is the same as {@link #PF_XBGR}, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ public static final int PF_ABGR = 9; /** - * ARGB pixel format. This is the same as {@link #PF_XRGB}, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * ARGB pixel format + * + *

    This is the same as {@link #PF_XRGB}, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ public static final int PF_ARGB = 10; /** - * CMYK pixel format. Unlike RGB, which is an additive color model used - * primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive - * color model used primarily for printing. In the CMYK color model, the - * value of each color component typically corresponds to an amount of cyan, - * magenta, yellow, or black ink that is applied to a white background. In - * order to convert between CMYK and RGB, it is necessary to use a color - * management system (CMS.) A CMS will attempt to map colors within the - * printer's gamut to perceptually similar colors in the display's gamut and - * vice versa, but the mapping is typically not 1:1 or reversible, nor can it - * be defined with a simple formula. Thus, such a conversion is out of scope - * for a codec library. However, the TurboJPEG API allows for compressing - * packed-pixel CMYK images into YCCK JPEG images (see {@link #CS_YCCK}) and - * decompressing YCCK JPEG images into packed-pixel CMYK images. + * CMYK pixel format + * + *

    Unlike RGB, which is an additive color model used primarily for + * display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive color model used + * primarily for printing. In the CMYK color model, the value of each color + * component typically corresponds to an amount of cyan, magenta, yellow, or + * black ink that is applied to a white background. In order to convert + * between CMYK and RGB, it is necessary to use a color management system + * (CMS.) A CMS will attempt to map colors within the printer's gamut to + * perceptually similar colors in the display's gamut and vice versa, but the + * mapping is typically not 1:1 or reversible, nor can it be defined with a + * simple formula. Thus, such a conversion is out of scope for a codec + * library. However, the TurboJPEG API allows for compressing packed-pixel + * CMYK images into YCCK JPEG images (see {@link #CS_YCCK}) and decompressing + * YCCK JPEG images into packed-pixel CMYK images. */ public static final int PF_CMYK = 11; @@ -257,7 +323,7 @@ public final class TJ { * For the given pixel format, returns the number of samples that the red * component is offset from the start of the pixel. For instance, if an * 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - * char pixel[], then the red component will be + * char pixel[], then the red component is * pixel[TJ.getRedOffset(TJ.PF_BGRX)]. * * @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*}) @@ -279,7 +345,7 @@ public final class TJ { * For the given pixel format, returns the number of samples that the green * component is offset from the start of the pixel. For instance, if an * 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - * char pixel[], then the green component will be + * char pixel[], then the green component is * pixel[TJ.getGreenOffset(TJ.PF_BGRX)]. * * @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*}) @@ -301,7 +367,7 @@ public final class TJ { * For the given pixel format, returns the number of samples that the blue * component is offset from the start of the pixel. For instance, if an * 8-bit-per-sample pixel of format TJ.PF_BGRX is stored in - * char pixel[], then the blue component will be + * char pixel[], then the blue component is * pixel[TJ.getBlueOffset(TJ.PF_BGRX)]. * * @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*}) @@ -323,7 +389,7 @@ public final class TJ { * For the given pixel format, returns the number of samples that the alpha * component is offset from the start of the pixel. For instance, if an * 8-bit-per-sample pixel of format TJ.PF_BGRA is stored in - * char pixel[], then the alpha component will be + * char pixel[], then the alpha component is * pixel[TJ.getAlphaOffset(TJ.PF_BGRA)]. * * @param pixelFormat the pixel format (one of {@link #PF_RGB PF_*}) @@ -346,57 +412,64 @@ public final class TJ { */ public static final int NUMCS = 5; /** - * RGB colorspace. When compressing the JPEG image, the R, G, and B - * components in the source image are reordered into image planes, but no - * colorspace conversion or subsampling is performed. RGB JPEG images can be - * compressed from and decompressed to packed-pixel images with any of the - * extended RGB or grayscale pixel formats, but they cannot be compressed - * from or decompressed to planar YUV images. + * RGB colorspace + * + *

    When generating the JPEG image, the R, G, and B components in the + * source image are reordered into image planes, but no colorspace conversion + * or subsampling is performed. RGB JPEG images can be generated from and + * decompressed to packed-pixel images with any of the extended RGB or + * grayscale pixel formats, but they cannot be generated from or + * decompressed to planar YUV images. */ public static final int CS_RGB = 0; /** - * YCbCr colorspace. YCbCr is not an absolute colorspace but rather a - * mathematical transformation of RGB designed solely for storage and - * transmission. YCbCr images must be converted to RGB before they can - * actually be displayed. In the YCbCr colorspace, the Y (luminance) - * component represents the black & white portion of the original image, - * and the Cb and Cr (chrominance) components represent the color portion of - * the original image. Originally, the analog equivalent of this - * transformation allowed the same signal to drive both black & white and - * color televisions, but JPEG images use YCbCr primarily because it allows - * the color data to be optionally subsampled for the purposes of reducing - * network or disk usage. YCbCr is the most common JPEG colorspace, and - * YCbCr JPEG images can be compressed from and decompressed to packed-pixel - * images with any of the extended RGB or grayscale pixel formats. YCbCr - * JPEG images can also be compressed from and decompressed to planar YUV - * images. + * YCbCr colorspace + * + *

    YCbCr is not an absolute colorspace but rather a mathematical + * transformation of RGB designed solely for storage and transmission. YCbCr + * images must be converted to RGB before they can be displayed. In the + * YCbCr colorspace, the Y (luminance) component represents the black & + * white portion of the original image, and the Cb and Cr (chrominance) + * components represent the color portion of the original image. + * Historically, the analog equivalent of this transformation allowed the + * same signal to be displayed to both black & white and color + * televisions, but JPEG images use YCbCr primarily because it allows the + * color data to be optionally subsampled in order to reduce network and disk + * usage. YCbCr is the most common JPEG colorspace, and YCbCr JPEG images + * can be generated from and decompressed to packed-pixel images with any of + * the extended RGB or grayscale pixel formats. YCbCr JPEG images can also + * be generated from and decompressed to planar YUV images. */ @SuppressWarnings("checkstyle:ConstantName") public static final int CS_YCbCr = 1; /** - * Grayscale colorspace. The JPEG image retains only the luminance data (Y - * component), and any color data from the source image is discarded. - * Grayscale JPEG images can be compressed from and decompressed to - * packed-pixel images with any of the extended RGB or grayscale pixel - * formats, or they can be compressed from and decompressed to planar YUV - * images. + * Grayscale colorspace + * + *

    The JPEG image retains only the luminance data (Y component), and any + * color data from the source image is discarded. Grayscale JPEG images can + * be generated from and decompressed to packed-pixel images with any of the + * extended RGB or grayscale pixel formats, or they can be generated from and + * decompressed to planar YUV images. */ public static final int CS_GRAY = 2; /** - * CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K - * components in the source image are reordered into image planes, but no - * colorspace conversion or subsampling is performed. CMYK JPEG images can - * only be compressed from and decompressed to packed-pixel images with the - * CMYK pixel format. + * CMYK colorspace + * + *

    When generating the JPEG image, the C, M, Y, and K components in the + * source image are reordered into image planes, but no colorspace conversion + * or subsampling is performed. CMYK JPEG images can only be generated from + * and decompressed to packed-pixel images with the CMYK pixel format. */ public static final int CS_CMYK = 3; /** - * YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but - * rather a mathematical transformation of CMYK designed solely for storage - * and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be + * YCCK colorspace + * + *

    YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a + * mathematical transformation of CMYK designed solely for storage and + * transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be * reversibly transformed into YCCK, and as with YCbCr, the chrominance * components in the YCCK pixels can be subsampled without incurring major - * perceptual loss. YCCK JPEG images can only be compressed from and + * perceptual loss. YCCK JPEG images can only be generated from and * decompressed to packed-pixel images with the CMYK pixel format. */ public static final int CS_YCCK = 4; @@ -447,14 +520,14 @@ public final class TJ { * from CMYK to YCCK (see {@link #CS_YCCK}) as part of the JPEG compression * process, some of the Cb and Cr (chrominance) components can be discarded * or averaged together to produce a smaller image with little perceptible - * loss of image clarity. (The human eye is more sensitive to small changes + * loss of image quality. (The human eye is more sensitive to small changes * in brightness than to small changes in color.) This is called * "chrominance subsampling". * *

    Value *

      - *
    • One of {@link TJ#SAMP_444 TJ.SAMP_*} [no default; must be - * explicitly specified for lossy compression, encoding, and decoding] + *
    • One of {@link #SAMP_444 TJ.SAMP_*} [no default; must be explicitly + * specified for lossy compression, encoding, and decoding] *
    */ public static final int PARAM_SUBSAMP = 4; @@ -488,7 +561,7 @@ public final class TJ { * *

    Value *

      - *
    • One of {@link TJ#CS_RGB TJ.CS_*} [default for lossy compression: + *
    • One of {@link #CS_RGB TJ.CS_*} [default for lossy compression: * automatically selected based on the subsampling level and pixel * format] *
    @@ -500,7 +573,7 @@ public final class TJ { *

    Value *

      *
    • 0 [default] Use smooth upsampling when - * decompressing a JPEG image that was compressed using chrominance + * decompressing a JPEG image that was generated using chrominance * subsampling. This creates a smooth transition between neighboring * chrominance components in order to reduce upsampling artifacts in the * decompressed image. @@ -532,14 +605,13 @@ public final class TJ { *
    • The difference in accuracy between the "fast" and "accurate" * algorithms is the most pronounced at JPEG quality levels above 90 and * tends to be more pronounced with decompression than with compression. - *
    • The "fast" algorithm degrades and is not fully accelerated for JPEG - * quality levels above 97, so it will be slower than the "accurate" - * algorithm. + *
    • For JPEG quality levels above 97, the "fast" algorithm degrades and + * is not fully accelerated, so it is slower than the "accurate" algorithm. *
    */ public static final int PARAM_FASTDCT = 10; /** - * Optimized baseline entropy coding [lossy compression only] + * Huffman table optimization [lossy compression, lossless transformation] * *

    Value *

      @@ -550,38 +622,47 @@ public final class TJ { * {@link TJTransform#OPT_OPTIMIZE}. *
    * - *

    Optimized baseline entropy coding will improve compression slightly - * (generally 5% or less), but it will reduce compression performance - * considerably. + *

    Huffman table optimization improves compression slightly (generally 5% + * or less), but it reduces compression performance considerably. */ public static final int PARAM_OPTIMIZE = 11; /** - * Progressive entropy coding + * Progressive JPEG + * + *

    In a progressive JPEG image, the DCT coefficients are split across + * multiple "scans" of increasing quality. Thus, a low-quality scan + * containing the lowest-frequency DCT coefficients can be transmitted first + * and refined with subsequent higher-quality scans containing + * higher-frequency DCT coefficients. When using Huffman entropy coding, the + * progressive JPEG format also provides an "end-of-bands (EOB) run" feature + * that allows large groups of zeroes, potentially spanning multiple MCUs, to + * be represented using only a few bytes. * *

    Value *

      *
    • 0 [default for compression, lossless - * transformation] The lossy JPEG image uses (decompression) or will use - * (compression, lossless transformation) baseline entropy coding. - *
    • 1 The lossy JPEG image uses (decompression) or will use - * (compression, lossless transformation) progressive entropy coding. For - * lossless transformation, this can also be specified using + * transformation] The lossy JPEG image is (decompression) or will be + * (compression, lossless transformation) single-scan. + *
    • 1 The lossy JPEG image is (decompression) or will be + * (compression, lossless transformation) progressive. For lossless + * transformation, this can also be specified using * {@link TJTransform#OPT_PROGRESSIVE}. *
    * - *

    Progressive entropy coding will generally improve compression relative - * to baseline entropy coding, but it will reduce compression and - * decompression performance considerably. Can be combined with - * {@link #PARAM_ARITHMETIC}. Implies {@link #PARAM_OPTIMIZE} unless - * {@link #PARAM_ARITHMETIC} is also set. + *

    Progressive JPEG images generally have better compression ratios than + * single-scan JPEG images (much better if the image has large areas of solid + * color), but progressive JPEG compression and decompression is considerably + * slower than single-scan JPEG compression and decompression. Can be + * combined with {@link #PARAM_ARITHMETIC}. Implies {@link #PARAM_OPTIMIZE} + * unless {@link #PARAM_ARITHMETIC} is also set. */ public static final int PARAM_PROGRESSIVE = 12; /** * Progressive JPEG scan limit for lossy JPEG images [decompression, lossless * transformation] * - *

    Setting this parameter will cause the decompression and transform - * functions to return an error if the number of scans in a progressive JPEG + *

    Setting this parameter causes the decompression and transform + * operations to throw an error if the number of scans in a progressive JPEG * image exceeds the specified limit. The primary purpose of this is to * allow security-critical applications to guard against an exploit of the * progressive JPEG format described in @@ -590,7 +671,7 @@ public final class TJ { *

    Value *

      *
    • maximum number of progressive JPEG scans that the decompression and - * transform functions will process [default: 0 (no + * transform operations will process [default: 0 (no * limit)] *
    * @@ -611,9 +692,9 @@ public final class TJ { * {@link TJTransform#OPT_ARITHMETIC}. * * - *

    Arithmetic entropy coding will generally improve compression relative - * to Huffman entropy coding, but it will reduce compression and - * decompression performance considerably. Can be combined with + *

    Arithmetic entropy coding generally improves compression relative to + * Huffman entropy coding, but it reduces compression and decompression + * performance considerably. Can be combined with * {@link #PARAM_PROGRESSIVE}. */ public static final int PARAM_ARITHMETIC = 14; @@ -628,10 +709,12 @@ public final class TJ { * (compression) lossless/predictive. * * - *

    In most cases, compressing and decompressing lossless JPEG images is - * considerably slower than compressing and decompressing lossy JPEG images. - * Also note that the following features are not available with lossless JPEG - * images: + *

    In most cases, lossless JPEG compression and decompression is + * considerably slower than lossy JPEG compression and decompression, and + * lossless JPEG images are much larger than lossy JPEG images. Thus, + * lossless JPEG images are typically used only for applications that require + * mathematically lossless compression. Also note that the following + * features are not available with lossless JPEG images: *

      *
    • Colorspace conversion (lossless JPEG images always use * {@link #CS_RGB}, {@link #CS_GRAY}, or {@link #CS_CMYK}, depending on the @@ -640,7 +723,7 @@ public final class TJ { * {@link #SAMP_444}) *
    • JPEG quality selection *
    • DCT/IDCT algorithm selection - *
    • Progressive entropy coding + *
    • Progressive JPEG *
    • Arithmetic entropy coding *
    • Compression from/decompression to planar YUV images *
    • Decompression scaling @@ -660,6 +743,32 @@ public final class TJ { * 1] *
    * + *

    Lossless JPEG compression shares no algorithms with lossy JPEG + * compression. Instead, it uses differential pulse-code modulation (DPCM), + * an algorithm whereby each sample is encoded as the difference between the + * sample's value and a "predictor", which is based on the values of + * neighboring samples. If Ra is the sample immediately to the left of the + * current sample, Rb is the sample immediately above the current sample, and + * Rc is the sample diagonally to the left and above the current sample, then + * the relationship between the predictor selection value and the predictor + * is as follows: + * + * + * + * + * + * + * + * + * + * + * + *
    PSV Predictor
    1 Ra
    2 Rb
    3 Rc
    4 Ra + Rb – Rc
    5 Ra + (Rb – Rc) / 2
    6 Rb + (Ra – Rc) / 2
    7 (Ra + Rb) / 2
    + * + *

    Predictors 1-3 are 1-dimensional predictors, whereas Predictors 4-7 are + * 2-dimensional predictors. The best predictor for a particular image + * depends on the image. + * * @see #PARAM_LOSSLESS */ public static final int PARAM_LOSSLESSPSV = 16; @@ -683,8 +792,7 @@ public final class TJ { */ public static final int PARAM_LOSSLESSPT = 17; /** - * JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) - * [compression only] + * JPEG restart marker interval in MCUs [lossy compression only] * *

    The nature of entropy coding is such that a corrupt JPEG image cannot * be decompressed beyond the point of corruption unless it contains restart @@ -694,10 +802,19 @@ public final class TJ { * tolerance of the JPEG image, but adding too many restart markers can * adversely affect the compression ratio and performance. * + *

    In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set + * of interleaved "data units" (8x8 DCT blocks if the image is lossy or + * samples if the image is lossless) necessary to represent at least one data + * unit per component. (For example, an MCU in an interleaved lossy JPEG + * image that uses 4:2:2 subsampling consists of two luminance blocks + * followed by one block for each chrominance component.) In + * single-component or non-interleaved JPEG images, an MCU is the same as a + * data unit. + * *

    Value *

      - *
    • the number of MCU blocks or samples between each restart marker - * [default: 0 (no restart markers)] + *
    • the number of MCUs between each restart marker [default: + * 0 (no restart markers)] *
    * *

    Setting this parameter to a non-zero value sets @@ -705,15 +822,16 @@ public final class TJ { */ public static final int PARAM_RESTARTBLOCKS = 18; /** - * JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) - * [compression only] + * JPEG restart marker interval in MCU rows [compression only] * - *

    See {@link #PARAM_RESTARTBLOCKS} for a description of restart markers. + *

    See {@link #PARAM_RESTARTBLOCKS} for a description of restart markers + * and MCUs. An MCU row is a row of MCUs spanning the entire width of the + * image. * *

    Value *

      - *
    • the number of MCU rows or sample rows between each restart marker - * [default: 0 (no restart markers)] + *
    • the number of MCU rows between each restart marker [default: + * 0 (no restart markers)] *
    * *

    Setting this parameter to a non-zero value sets @@ -774,6 +892,33 @@ public final class TJ { * @see #PARAM_YDENSITY */ public static final int PARAM_DENSITYUNITS = 22; + /** + * Memory limit for intermediate buffers + * + *

    Value + *

      + *
    • the maximum amount of memory (in megabytes) that will be allocated + * for intermediate buffers, which are used with progressive JPEG compression + * and decompression, Huffman table optimization, lossless JPEG compression, + * and lossless transformation [default: 0 (no limit)] + *
    + */ + public static final int PARAM_MAXMEMORY = 23; + /** + * Image size limit [decompression, lossless transformation] + * + *

    Setting this parameter causes the decompression and transform + * operations to throw an error if the number of pixels in the JPEG source + * image exceeds the specified limit. This allows security-critical + * applications to guard against excessive memory consumption. + * + *

    Value + *

      + *
    • maximum number of pixels that the decompression and transform + * operations will process [default: 0 (no limit)] + *
    + */ + public static final int PARAM_MAXPIXELS = 24; /** @@ -820,8 +965,8 @@ public final class TJ { /** * The error was non-fatal and recoverable, but the destination image may * still be corrupt. - *

    - * NOTE: due to the design of the TurboJPEG Java API, only certain methods + * + *

    NOTE: Due to the design of the TurboJPEG Java API, only certain methods * (specifically, {@link TJDecompressor TJDecompressor.decompress*()} methods * with a void return type) will complete and leave the destination image in * a fully recoverable state after a non-fatal error occurs. @@ -884,12 +1029,12 @@ public final class TJ { * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, * 2 = V/Cr) * - * @param width width (in pixels) of the YUV image. NOTE: this is the width + * @param width width (in pixels) of the YUV image. NOTE: This is the width * of the whole image, not the plane width. * * @param stride bytes per row in the image plane. * - * @param height height (in pixels) of the YUV image. NOTE: this is the + * @param height height (in pixels) of the YUV image. NOTE: This is the * height of the whole image, not the plane height. * * @param subsamp the level of chrominance subsampling used in the YUV diff --git a/java/org/libjpegturbo/turbojpeg/TJCompressor.java b/java/org/libjpegturbo/turbojpeg/TJCompressor.java index fed47de..9704de6 100644 --- a/java/org/libjpegturbo/turbojpeg/TJCompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJCompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2015, 2018, 2020, 2022-2023 D. R. Commander. + * Copyright (C)2011-2015, 2018, 2020, 2022-2024 D. R. Commander. * All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * @@ -263,7 +263,7 @@ public class TJCompressor implements Closeable { } /** - * Associate an 8-bit-per-pixel packed-pixel RGB or grayscale source image + * Associate an 8-bit-per-sample packed-pixel RGB or grayscale source image * with this compressor instance. * * @param srcImage a BufferedImage instance containing a @@ -335,6 +335,8 @@ public class TJCompressor implements Closeable { DataBufferInt db = (DataBufferInt)wr.getDataBuffer(); srcBufInt = db.getData(); srcBuf8 = null; + srcBuf12 = null; + srcBuf16 = null; } else { ComponentSampleModel sm = (ComponentSampleModel)srcImage.getSampleModel(); @@ -344,6 +346,8 @@ public class TJCompressor implements Closeable { srcPitch = sm.getScanlineStride(); DataBufferByte db = (DataBufferByte)wr.getDataBuffer(); srcBuf8 = db.getData(); + srcBuf12 = null; + srcBuf16 = null; srcBufInt = null; } srcYUVImage = null; @@ -364,6 +368,8 @@ public class TJCompressor implements Closeable { srcYUVImage = srcImage; set(TJ.PARAM_SUBSAMP, srcImage.getSubsamp()); srcBuf8 = null; + srcBuf12 = null; + srcBuf16 = null; srcBufInt = null; } @@ -479,6 +485,8 @@ public class TJCompressor implements Closeable { } else { checkSubsampling(); int subsamp = get(TJ.PARAM_SUBSAMP); + if (get(TJ.PARAM_LOSSLESS) == 1 && subsamp != TJ.SAMP_GRAY) + subsamp = TJ.SAMP_444; buf = new byte[TJ.bufSize(srcWidth, srcHeight, subsamp)]; } compress(buf); @@ -624,10 +632,10 @@ public class TJCompressor implements Closeable { /** * Returns the size of the image (in bytes) generated by the most recent - * compress operation. + * compression operation. * * @return the size of the image (in bytes) generated by the most recent - * compress operation. + * compression operation. */ public int getCompressedSize() { return compressedSize; diff --git a/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java index 78e6e4e..0818aa7 100644 --- a/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java +++ b/java/org/libjpegturbo/turbojpeg/TJCustomFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011, 2013, 2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2011, 2013, 2023-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,21 +37,21 @@ import java.nio.*; public interface TJCustomFilter { /** - * A callback function that can be used to modify the DCT coefficients after + * A callback method that can be used to modify the DCT coefficients after * they are losslessly transformed but before they are transcoded to a new * JPEG image. This allows for custom filters or other transformations to be * applied in the frequency domain. * * @param coeffBuffer a buffer containing transformed DCT coefficients. - * (NOTE: this buffer is not guaranteed to be valid once the callback + * (NOTE: This buffer is not guaranteed to be valid once the callback * returns, so applications wishing to hand off the DCT coefficients to - * another function or library should make a copy of them within the body of - * the callback.) + * another method should make a copy of them within the body of the + * callback.) * * @param bufferRegion rectangle containing the width and height of * coeffBuffer as well as its offset relative to the component * plane. TurboJPEG implementations may choose to split each component plane - * into multiple DCT coefficient buffers and call the callback function once + * into multiple DCT coefficient buffers and call the callback method once * for each buffer. * * @param planeRegion rectangle containing the width and height of the diff --git a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java index d8c0545..58a6d9b 100644 --- a/java/org/libjpegturbo/turbojpeg/TJDecompressor.java +++ b/java/org/libjpegturbo/turbojpeg/TJDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2015, 2018, 2022-2023 D. R. Commander. + * Copyright (C)2011-2015, 2018, 2022-2024 D. R. Commander. * All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * @@ -222,8 +222,8 @@ public class TJDecompressor implements Closeable { * with the JPEG image width and height (see {@link #getWidth} and * {@link #getHeight}.) When decompressing into a planar YUV image, an * intermediate buffer copy will be performed if the width or height of the - * scaled destination image is not an even multiple of the MCU block size - * (see {@link TJ#getMCUWidth TJ.getMCUWidth()} and {@link TJ#getMCUHeight + * scaled destination image is not an even multiple of the iMCU size (see + * {@link TJ#getMCUWidth TJ.getMCUWidth()} and {@link TJ#getMCUHeight * TJ.getMCUHeight()}.) Note that decompression scaling is not available * (and the specified scaling factor is ignored) when decompressing lossless * JPEG images (see {@link TJ#PARAM_LOSSLESS}), since the IDCT algorithm is @@ -255,15 +255,15 @@ public class TJDecompressor implements Closeable { * @param croppingRegion java.awt.Rectangle instance that * specifies a subregion of the JPEG image to decompress, or * {@link TJ#UNCROPPED} for no cropping. The left boundary of the cropping - * region must be evenly divisible by the scaled MCU block width, which can - * be determined by calling {@link TJScalingFactor#getScaled + * region must be evenly divisible by the scaled iMCU width, which can be + * determined by calling {@link TJScalingFactor#getScaled * TJScalingFactor.getScaled()} with the specified scaling factor (see - * {@link #setScalingFactor setScalingFactor()}) and the MCU block width - * (see {@link TJ#getMCUWidth TJ.getMCUWidth()}) for the level of chrominance + * {@link #setScalingFactor setScalingFactor()}) and the iMCU width (see + * {@link TJ#getMCUWidth TJ.getMCUWidth()}) for the level of chrominance * subsampling in the JPEG image (see {@link TJ#PARAM_SUBSAMP}.) The * cropping region should be specified relative to the scaled image * dimensions. Unless croppingRegion is {@link TJ#UNCROPPED}, - * the JPEG header must be read (see {@link #setSourceImage(byte[], int)} + * the JPEG header must be read (see {@link #setSourceImage(byte[], int)}) * prior to calling this method. */ @SuppressWarnings("checkstyle:HiddenField") @@ -380,9 +380,9 @@ public class TJDecompressor implements Closeable { * source image associated with this decompressor instance and output an * 8-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given * destination buffer. - *

    - * NOTE: The destination image is fully recoverable if this method throws a - * non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is + * + *

    NOTE: The destination image is fully recoverable if this method throws + * a non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is * set.) * * @param dstBuf buffer that will receive the packed-pixel @@ -413,7 +413,7 @@ public class TJDecompressor implements Closeable { * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat).) However, * you can also use this parameter to specify the row alignment/padding of * the destination image, to skip rows, or to decompress/decode into a - * specific region of a larger image. NOTE: if the source image is a lossy + * specific region of a larger image. NOTE: If the source image is a lossy * JPEG image, then destinationWidth is either the scaled JPEG * width (see {@link #setScalingFactor setScalingFactor()}, * {@link TJScalingFactor#getScaled TJScalingFactor.getScaled()}, and @@ -515,9 +515,9 @@ public class TJDecompressor implements Closeable { * Decompress the 12-bit-per-sample JPEG source image associated with this * decompressor instance and output a 12-bit-per-sample packed-pixel * grayscale, RGB, or CMYK image to the given destination buffer. - *

    - * NOTE: The destination image is fully recoverable if this method throws a - * non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is + * + *

    NOTE: The destination image is fully recoverable if this method throws + * a non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is * set.) * * @param dstBuf buffer that will receive the packed-pixel @@ -549,7 +549,7 @@ public class TJDecompressor implements Closeable { * {@link TJ#getPixelSize TJ.getPixelSize}(pixelFormat).) However, * you can also use this parameter to specify the row alignment/padding of * the destination image, to skip rows, or to decompress into a specific - * region of a larger image. NOTE: if the source image is a lossy JPEG + * region of a larger image. NOTE: If the source image is a lossy JPEG * image, then destinationWidth is either the scaled JPEG width * (see {@link #setScalingFactor setScalingFactor()}, * {@link TJScalingFactor#getScaled TJScalingFactor.getScaled()}, and @@ -582,7 +582,7 @@ public class TJDecompressor implements Closeable { * @param pixelFormat pixel format of the decompressed image (one of * {@link TJ#PF_RGB TJ.PF_*}) * - * @return a buffer containing an 8-bit-per-sample packed-pixel decompressed + * @return a buffer containing a 12-bit-per-sample packed-pixel decompressed * image. */ public short[] decompress12(int pitch, int pixelFormat) throws TJException { @@ -603,9 +603,9 @@ public class TJDecompressor implements Closeable { * with this decompressor instance and output a 16-bit-per-sample * packed-pixel grayscale, RGB, or CMYK image to the given destination * buffer. - *

    - * NOTE: The destination image is fully recoverable if this method throws a - * non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is + * + *

    NOTE: The destination image is fully recoverable if this method throws + * a non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} is * set.) * * @param dstBuf buffer that will receive the packed-pixel @@ -655,7 +655,7 @@ public class TJDecompressor implements Closeable { * @param pixelFormat pixel format of the decompressed image (one of * {@link TJ#PF_RGB TJ.PF_*}) * - * @return a buffer containing an 8-bit-per-sample packed-pixel decompressed + * @return a buffer containing a 16-bit-per-sample packed-pixel decompressed * image. */ public short[] decompress16(int pitch, int pixelFormat) throws TJException { @@ -678,9 +678,9 @@ public class TJDecompressor implements Closeable { * decompression but leaves out the color conversion step, so a planar YUV * image is generated instead of a packed-pixel image. This method cannot be * used to decompress JPEG source images with the CMYK or YCCK colorspace. - *

    - * NOTE: The planar YUV destination image is fully recoverable if this method - * throws a non-fatal {@link TJException} (unless + * + *

    NOTE: The planar YUV destination image is fully recoverable if this + * method throws a non-fatal {@link TJException} (unless * {@link TJ#PARAM_STOPONWARNING} is set.) * * @param dstImage {@link YUVImage} instance that will receive the planar YUV @@ -836,9 +836,9 @@ public class TJDecompressor implements Closeable { * source image associated with this decompressor instance and output an * 8-bit-per-sample packed-pixel grayscale, RGB, or CMYK image to the given * destination buffer. - *

    - * NOTE: The destination image is fully recoverable if this method throws a - * non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} + * + *

    NOTE: The destination image is fully recoverable if this method throws + * a non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} * is set.) * * @param dstBuf buffer that will receive the packed-pixel @@ -866,7 +866,7 @@ public class TJDecompressor implements Closeable { * should be set to destinationWidth. (Setting this parameter * to 0 is the equivalent of setting it to destinationWidth.) * However, you can also use this parameter to skip rows or to - * decompress/decode into a specific region of a larger image. NOTE: if the + * decompress/decode into a specific region of a larger image. NOTE: If the * source image is a lossy JPEG image, then destinationWidth is * either the scaled JPEG width (see {@link #setScalingFactor * setScalingFactor()}, {@link TJScalingFactor#getScaled @@ -921,9 +921,9 @@ public class TJDecompressor implements Closeable { * source image associated with this decompressor instance and output an * 8-bit-per-sample packed-pixel decompressed/decoded image to the given * BufferedImage instance. - *

    - * NOTE: The destination image is fully recoverable if this method throws a - * non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} + * + *

    NOTE: The destination image is fully recoverable if this method throws + * a non-fatal {@link TJException} (unless {@link TJ#PARAM_STOPONWARNING} * is set.) * * @param dstImage a BufferedImage instance that will receive diff --git a/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java b/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java index ccf9179..294c5c1 100644 --- a/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java +++ b/java/org/libjpegturbo/turbojpeg/TJScalingFactor.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011, 2018 D. R. Commander. All Rights Reserved. + * Copyright (C)2011, 2018, 2023 D. R. Commander. All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -67,9 +67,9 @@ public class TJScalingFactor { } /** - * Returns the scaled value of dimension. This function - * performs the integer equivalent of - * ceil(dimension * scalingFactor). + * Returns the scaled value of dimension. This method performs + * the integer equivalent of + * Math.ceil(dimension * scalingFactor). * * @param dimension width or height to multiply by this scaling factor * diff --git a/java/org/libjpegturbo/turbojpeg/TJTransform.java b/java/org/libjpegturbo/turbojpeg/TJTransform.java index 7c32cce..c1eb009 100644 --- a/java/org/libjpegturbo/turbojpeg/TJTransform.java +++ b/java/org/libjpegturbo/turbojpeg/TJTransform.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2011, 2013, 2018, 2022-2023 D. R. Commander. + * Copyright (C)2011, 2013, 2018, 2022-2024 D. R. Commander. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,13 +48,13 @@ public class TJTransform extends Rectangle { public static final int OP_NONE = 0; /** * Flip (mirror) image horizontally. This transform is imperfect if there - * are any partial MCU blocks on the right edge. + * are any partial iMCUs on the right edge. * @see #OPT_PERFECT */ public static final int OP_HFLIP = 1; /** * Flip (mirror) image vertically. This transform is imperfect if there are - * any partial MCU blocks on the bottom edge. + * any partial iMCUs on the bottom edge. * @see #OPT_PERFECT */ public static final int OP_VFLIP = 2; @@ -66,95 +66,90 @@ public class TJTransform extends Rectangle { public static final int OP_TRANSPOSE = 3; /** * Transverse transpose image (flip/mirror along upper right to lower left - * axis). This transform is imperfect if there are any partial MCU blocks in - * the image. + * axis). This transform is imperfect if there are any partial iMCUs in the + * image. * @see #OPT_PERFECT */ public static final int OP_TRANSVERSE = 4; /** * Rotate image clockwise by 90 degrees. This transform is imperfect if - * there are any partial MCU blocks on the bottom edge. + * there are any partial iMCUs on the bottom edge. * @see #OPT_PERFECT */ public static final int OP_ROT90 = 5; /** * Rotate image 180 degrees. This transform is imperfect if there are any - * partial MCU blocks in the image. + * partial iMCUs in the image. * @see #OPT_PERFECT */ public static final int OP_ROT180 = 6; /** * Rotate image counter-clockwise by 90 degrees. This transform is imperfect - * if there are any partial MCU blocks on the right edge. + * if there are any partial iMCUs on the right edge. * @see #OPT_PERFECT */ public static final int OP_ROT270 = 7; /** - * This option will cause {@link TJTransformer#transform + * This option causes {@link TJTransformer#transform * TJTransformer.transform()} to throw an exception if the transform is not - * perfect. Lossless transforms operate on MCU blocks, whose size depends on - * the level of chrominance subsampling used. If the image's width or height - * is not evenly divisible by the MCU block size (see {@link TJ#getMCUWidth + * perfect. Lossless transforms operate on iMCUs, the size of which depends + * on the level of chrominance subsampling used. If the image's width or + * height is not evenly divisible by the iMCU size (see {@link TJ#getMCUWidth * TJ.getMCUWidth()} and {@link TJ#getMCUHeight TJ.getMCUHeight()}), then - * there will be partial MCU blocks on the right and/or bottom edges. It is - * not possible to move these partial MCU blocks to the top or left of the - * image, so any transform that would require that is "imperfect." If this - * option is not specified, then any partial MCU blocks that cannot be - * transformed will be left in place, which will create odd-looking strips on - * the right or bottom edge of the image. + * there will be partial iMCUs on the right and/or bottom edges. It is not + * possible to move these partial iMCUs to the top or left of the image, so + * any transform that would require that is "imperfect." If this option is + * not specified, then any partial iMCUs that cannot be transformed will be + * left in place, which will create odd-looking strips on the right or bottom + * edge of the image. */ public static final int OPT_PERFECT = (1 << 0); /** - * This option will discard any partial MCU blocks that cannot be - * transformed. + * Discard any partial iMCUs that cannot be transformed. */ public static final int OPT_TRIM = (1 << 1); /** - * This option will enable lossless cropping. + * Enable lossless cropping. */ public static final int OPT_CROP = (1 << 2); /** - * This option will discard the color data in the source image and produce a - * grayscale destination image. + * Discard the color data in the source image, and generate a grayscale + * destination image. */ public static final int OPT_GRAY = (1 << 3); /** - * This option will prevent {@link TJTransformer#transform - * TJTransformer.transform()} from outputting a JPEG image for this - * particular transform. This can be used in conjunction with a custom - * filter to capture the transformed DCT coefficients without transcoding - * them. + * Do not generate a destination image. This can be used in conjunction with + * a custom filter to capture the transformed DCT coefficients without + * transcoding them. */ public static final int OPT_NOOUTPUT = (1 << 4); /** - * This option will enable progressive entropy coding in the JPEG image - * generated by this particular transform. Progressive entropy coding will - * generally improve compression relative to baseline entropy coding (the - * default), but it will reduce decompression performance considerably. - * Can be combined with {@link #OPT_ARITHMETIC}. Implies - * {@link #OPT_OPTIMIZE} unless {@link #OPT_ARITHMETIC} is also specified. + * Generate a progressive destination image instead of a single-scan + * destination image. Progressive JPEG images generally have better + * compression ratios than single-scan JPEG images (much better if the image + * has large areas of solid color), but progressive JPEG decompression is + * considerably slower than single-scan JPEG decompression. Can be combined + * with {@link #OPT_ARITHMETIC}. Implies {@link #OPT_OPTIMIZE} unless + * {@link #OPT_ARITHMETIC} is also specified. */ public static final int OPT_PROGRESSIVE = (1 << 5); /** - * This option will prevent {@link TJTransformer#transform - * TJTransformer.transform()} from copying any extra markers (including EXIF - * and ICC profile data) from the source image to the destination image. + * Do not copy any extra markers (including Exif and ICC profile data) from + * the source image to the destination image. */ public static final int OPT_COPYNONE = (1 << 6); /** - * This option will enable arithmetic entropy coding in the JPEG image - * generated by this particular transform. Arithmetic entropy coding will - * generally improve compression relative to Huffman entropy coding (the - * default), but it will reduce decompression performance considerably. Can - * be combined with {@link #OPT_PROGRESSIVE}. + * Enable arithmetic entropy coding in the destination image. Arithmetic + * entropy coding generally improves compression relative to Huffman entropy + * coding (the default), but it reduces decompression performance + * considerably. Can be combined with {@link #OPT_PROGRESSIVE}. */ public static final int OPT_ARITHMETIC = (1 << 7); /** - * This option will enable optimized baseline entropy coding in the JPEG - * image generated by this particular transform. Optimized baseline entropy - * coding will improve compression slightly (generally 5% or less.) + * Enable Huffman table optimization for the destination image. Huffman + * table optimization improves compression slightly (generally 5% or less.) */ public static final int OPT_OPTIMIZE = (1 << 8); @@ -169,12 +164,12 @@ public class TJTransform extends Rectangle { * Create a new lossless transform instance with the given parameters. * * @param x the left boundary of the cropping region. This must be evenly - * divisible by the MCU block width (see {@link TJ#getMCUWidth - * TJ.getMCUWidth()}) + * divisible by the iMCU width (see {@link TJ#getMCUWidth TJ.getMCUWidth()}) + * of the destination image. * * @param y the upper boundary of the cropping region. This must be evenly - * divisible by the MCU block height (see {@link TJ#getMCUHeight - * TJ.getMCUHeight()}) + * divisible by the iMCU height (see {@link TJ#getMCUHeight + * TJ.getMCUHeight()}) of the destination image. * * @param w the width of the cropping region. Setting this to 0 is the * equivalent of setting it to (width of the source JPEG image - diff --git a/java/org/libjpegturbo/turbojpeg/TJTransformer.java b/java/org/libjpegturbo/turbojpeg/TJTransformer.java index 4d46b5a..6884881 100644 --- a/java/org/libjpegturbo/turbojpeg/TJTransformer.java +++ b/java/org/libjpegturbo/turbojpeg/TJTransformer.java @@ -89,7 +89,8 @@ public class TJTransformer extends TJDecompressor { * transformed using the parameters in transforms[i]. Use * {@link TJ#bufSize TJ.bufSize()} to determine the maximum size for each * buffer based on the transformed or cropped width and height and the level - * of subsampling used in the source image. + * of subsampling used in the destination image (taking into account + * grayscale conversion and transposition of the width and height.) * * @param transforms an array of {@link TJTransform} instances, each of * which specifies the transform parameters and/or cropping region for the @@ -130,14 +131,33 @@ public class TJTransformer extends TJDecompressor { byte[][] dstBufs = new byte[transforms.length][]; if (getWidth() < 1 || getHeight() < 1) throw new IllegalStateException("JPEG buffer not initialized"); - checkSubsampling(); + int srcSubsamp = get(TJ.PARAM_SUBSAMP); for (int i = 0; i < transforms.length; i++) { int w = getWidth(), h = getHeight(); + int dstSubsamp = srcSubsamp; + + if ((transforms[i].options & TJTransform.OPT_GRAY) != 0) + dstSubsamp = TJ.SAMP_GRAY; + if (transforms[i].op == TJTransform.OP_TRANSPOSE || + transforms[i].op == TJTransform.OP_TRANSVERSE || + transforms[i].op == TJTransform.OP_ROT90 || + transforms[i].op == TJTransform.OP_ROT270) { + w = getHeight(); h = getWidth(); + if (dstSubsamp == TJ.SAMP_422) + dstSubsamp = TJ.SAMP_440; + else if (dstSubsamp == TJ.SAMP_440) + dstSubsamp = TJ.SAMP_422; + else if (dstSubsamp == TJ.SAMP_411) + dstSubsamp = TJ.SAMP_441; + else if (dstSubsamp == TJ.SAMP_441) + dstSubsamp = TJ.SAMP_411; + } + if ((transforms[i].options & TJTransform.OPT_CROP) != 0) { if (transforms[i].width != 0) w = transforms[i].width; if (transforms[i].height != 0) h = transforms[i].height; } - dstBufs[i] = new byte[TJ.bufSize(w, h, get(TJ.PARAM_SUBSAMP))]; + dstBufs[i] = new byte[TJ.bufSize(w, h, dstSubsamp)]; } TJDecompressor[] tjd = new TJDecompressor[transforms.length]; transform(dstBufs, transforms); diff --git a/java/org/libjpegturbo/turbojpeg/YUVImage.java b/java/org/libjpegturbo/turbojpeg/YUVImage.java index c2a43fd..e66a5d1 100644 --- a/java/org/libjpegturbo/turbojpeg/YUVImage.java +++ b/java/org/libjpegturbo/turbojpeg/YUVImage.java @@ -1,5 +1,5 @@ /* - * Copyright (C)2014, 2017, 2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2014, 2017, 2023-2024 D. R. Commander. All Rights Reserved. * Copyright (C)2015 Viktor Szathmáry. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,15 +37,15 @@ package org.libjpegturbo.turbojpeg; * serves as the destination image for YUV encode and decompress-to-YUV * operations and as the source image for compress-from-YUV and YUV decode * operations. - *

    - * Technically, the JPEG format uses the YCbCr colorspace (which is technically - * not a colorspace but a color transform), but per the convention of the - * digital video community, the TurboJPEG API uses "YUV" to refer to an image - * format consisting of Y, Cb, and Cr image planes. - *

    - * Each plane is simply a 2D array of bytes, each byte representing the value - * of one of the components (Y, Cb, or Cr) at a particular location in the - * image. The width and height of each plane are determined by the image + * + *

    Technically, the JPEG format uses the YCbCr colorspace (which is + * technically not a colorspace but a color transform), but per the convention + * of the digital video community, the TurboJPEG API uses "YUV" to refer to an + * image format consisting of Y, Cb, and Cr image planes. + * + *

    Each plane is simply a 2D array of bytes, each byte representing the + * value of one of the components (Y, Cb, or Cr) at a particular location in + * the image. The width and height of each plane are determined by the image * width, height, and level of chrominance subsampling. The luminance plane * width is the image width padded to the nearest multiple of the horizontal * subsampling factor (1 in the case of 4:4:4, grayscale, 4:4:0, or 4:4:1; 2 in @@ -58,9 +58,9 @@ package org.libjpegturbo.turbojpeg; * the luminance plane width divided by the horizontal subsampling factor, and * the chrominance plane height is equal to the luminance plane height divided * by the vertical subsampling factor. - *

    - * For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling is - * used, then the luminance plane would be 36 x 35 bytes, and each of the + * + *

    For example, if the source image is 35 x 35 pixels and 4:2:2 subsampling + * is used, then the luminance plane would be 36 x 35 bytes, and each of the * chrominance planes would be 18 x 35 bytes. If you specify a row alignment * of 4 bytes on top of this, then the luminance plane would be 36 x 35 bytes, * and each of the chrominance planes would be 20 x 35 bytes. @@ -222,13 +222,13 @@ public class YUVImage { int height, int subsamp, boolean alloc) { if ((planes == null && !alloc) || width < 1 || height < 1 || subsamp < 0 || subsamp >= TJ.NUMSAMP) - throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()"); + throw new IllegalArgumentException("Invalid argument in YUVImage.setBuf()"); int nc = (subsamp == TJ.SAMP_GRAY ? 1 : 3); if ((planes != null && planes.length != nc) || (offsets != null && offsets.length != nc) || (strides != null && strides.length != nc)) - throw new IllegalArgumentException("YUVImage::setBuf(): planes, offsets, or strides array is the wrong size"); + throw new IllegalArgumentException("YUVImage.setBuf(): planes, offsets, or strides array is the wrong size"); if (planes == null) planes = new byte[nc][]; @@ -250,7 +250,7 @@ public class YUVImage { planes[i] = new byte[strides[i] * ph]; } if (planes[i] == null || offsets[i] < 0) - throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()"); + throw new IllegalArgumentException("Invalid argument in YUVImage.setBuf()"); if (strides[i] < 0 && offsets[i] - planeSize + pw < 0) throw new IllegalArgumentException("Stride for plane " + i + " would cause memory to be accessed below plane boundary"); @@ -293,7 +293,7 @@ public class YUVImage { if (yuvImage == null || width < 1 || align < 1 || ((align & (align - 1)) != 0) || height < 1 || subsamp < 0 || subsamp >= TJ.NUMSAMP) - throw new IllegalArgumentException("Invalid argument in YUVImage::setBuf()"); + throw new IllegalArgumentException("Invalid argument in YUVImage.setBuf()"); if (yuvImage.length < TJ.bufSizeYUV(width, align, height, subsamp)) throw new IllegalArgumentException("YUV buffer is not large enough"); diff --git a/java/org_libjpegturbo_turbojpeg_TJ.h b/java/org_libjpegturbo_turbojpeg_TJ.h index e27c3b5..38505f7 100644 --- a/java/org_libjpegturbo_turbojpeg_TJ.h +++ b/java/org_libjpegturbo_turbojpeg_TJ.h @@ -107,6 +107,10 @@ extern "C" { #define org_libjpegturbo_turbojpeg_TJ_PARAM_YDENSITY 21L #undef org_libjpegturbo_turbojpeg_TJ_PARAM_DENSITYUNITS #define org_libjpegturbo_turbojpeg_TJ_PARAM_DENSITYUNITS 22L +#undef org_libjpegturbo_turbojpeg_TJ_PARAM_MAXMEMORY +#define org_libjpegturbo_turbojpeg_TJ_PARAM_MAXMEMORY 23L +#undef org_libjpegturbo_turbojpeg_TJ_PARAM_MAXPIXELS +#define org_libjpegturbo_turbojpeg_TJ_PARAM_MAXPIXELS 24L #undef org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP #define org_libjpegturbo_turbojpeg_TJ_FLAG_BOTTOMUP 2L #undef org_libjpegturbo_turbojpeg_TJ_FLAG_FASTUPSAMPLE diff --git a/jcdctmgr.c b/jcdctmgr.c index 7191ee7..dbdbad6 100644 --- a/jcdctmgr.c +++ b/jcdctmgr.c @@ -6,7 +6,7 @@ * libjpeg-turbo Modifications: * Copyright (C) 1999-2006, MIYASAKA Masaru. * Copyright 2009 Pierre Ossman for Cendio AB - * Copyright (C) 2011, 2014-2015, 2022, D. R. Commander. + * Copyright (C) 2011, 2014-2015, 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -114,8 +114,8 @@ flss(UINT16 val) * Compute values to do a division using reciprocal. * * This implementation is based on an algorithm described in - * "How to optimize for the Pentium family of microprocessors" - * (http://www.agner.org/assem/). + * "Optimizing subroutines in assembly language: + * An optimization guide for x86 platforms" (https://agner.org/optimize). * More information about the basic algorithm can be found in * the paper "Integer Division Using Reciprocals" by Robert Alverson. * diff --git a/jchuff.c b/jchuff.c index 3fede05..8cdd5bd 100644 --- a/jchuff.c +++ b/jchuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2014-2016, 2018-2023, D. R. Commander. + * Copyright (C) 2009-2011, 2014-2016, 2018-2024, D. R. Commander. * Copyright (C) 2015, Matthieu Darbois. * Copyright (C) 2018, Matthias Räncker. * Copyright (C) 2020, Arm Limited. @@ -35,41 +35,7 @@ #include "jchuff.h" /* Declarations shared with jc*huff.c */ #endif #include - -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for Huffman encoding. @@ -576,6 +542,10 @@ encode_one_block_simd(working_state *state, JCOEFPTR block, int last_dc_val, JOCTET _buffer[BUFSIZE], *buffer; int localbuf = 0; +#ifdef ZERO_BUFFERS + memset(_buffer, 0, sizeof(_buffer)); +#endif + LOAD_BUFFER() buffer = jsimd_huff_encode_one_block(state, buffer, block, last_dc_val, diff --git a/jcmaster.c b/jcmaster.c index 7e1408f..5d89178 100644 --- a/jcmaster.c +++ b/jcmaster.c @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2016, 2018, 2022-2023, D. R. Commander. + * Copyright (C) 2010, 2016, 2018, 2022-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -50,6 +50,113 @@ jpeg_calc_jpeg_dimensions(j_compress_ptr cinfo) #endif +LOCAL(boolean) +using_std_huff_tables(j_compress_ptr cinfo) +{ + int i; + + static const UINT8 bits_dc_luminance[17] = { + /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 + }; + static const UINT8 val_dc_luminance[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + }; + + static const UINT8 bits_dc_chrominance[17] = { + /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 + }; + static const UINT8 val_dc_chrominance[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 + }; + + static const UINT8 bits_ac_luminance[17] = { + /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d + }; + static const UINT8 val_ac_luminance[] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + }; + + static const UINT8 bits_ac_chrominance[17] = { + /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 + }; + static const UINT8 val_ac_chrominance[] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + }; + + if (cinfo->dc_huff_tbl_ptrs[0] == NULL || + cinfo->ac_huff_tbl_ptrs[0] == NULL || + cinfo->dc_huff_tbl_ptrs[1] == NULL || + cinfo->ac_huff_tbl_ptrs[1] == NULL) + return FALSE; + + for (i = 2; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL || + cinfo->ac_huff_tbl_ptrs[i] != NULL) + return FALSE; + } + + if (memcmp(cinfo->dc_huff_tbl_ptrs[0]->bits, bits_dc_luminance, + sizeof(bits_dc_luminance)) || + memcmp(cinfo->dc_huff_tbl_ptrs[0]->huffval, val_dc_luminance, + sizeof(val_dc_luminance)) || + memcmp(cinfo->ac_huff_tbl_ptrs[0]->bits, bits_ac_luminance, + sizeof(bits_ac_luminance)) || + memcmp(cinfo->ac_huff_tbl_ptrs[0]->huffval, val_ac_luminance, + sizeof(val_ac_luminance)) || + memcmp(cinfo->dc_huff_tbl_ptrs[1]->bits, bits_dc_chrominance, + sizeof(bits_dc_chrominance)) || + memcmp(cinfo->dc_huff_tbl_ptrs[1]->huffval, val_dc_chrominance, + sizeof(val_dc_chrominance)) || + memcmp(cinfo->ac_huff_tbl_ptrs[1]->bits, bits_ac_chrominance, + sizeof(bits_ac_chrominance)) || + memcmp(cinfo->ac_huff_tbl_ptrs[1]->huffval, val_ac_chrominance, + sizeof(val_ac_chrominance))) + return FALSE; + + return TRUE; +} + + LOCAL(void) initial_setup(j_compress_ptr cinfo, boolean transcode_only) /* Do computations that are needed before master selection phase */ @@ -605,6 +712,8 @@ GLOBAL(void) jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only) { my_master_ptr master = (my_master_ptr)cinfo->master; + boolean empty_huff_tables = TRUE; + int i; master->pub.prepare_for_pass = prepare_for_pass; master->pub.pass_startup = pass_startup; @@ -642,13 +751,25 @@ jinit_c_master_control(j_compress_ptr cinfo, boolean transcode_only) /* Validate parameters, determine derived values */ initial_setup(cinfo, transcode_only); - if (cinfo->master->lossless || /* TEMPORARY HACK ??? */ - (cinfo->progressive_mode && !cinfo->arith_code)) - cinfo->optimize_coding = TRUE; /* assume default tables no good for - progressive mode or lossless mode */ - if (cinfo->data_precision == 12 && !cinfo->arith_code) - cinfo->optimize_coding = TRUE; /* assume default tables no good for 12-bit - data precision */ + if (cinfo->arith_code) + cinfo->optimize_coding = FALSE; + else { + if (cinfo->master->lossless || /* TEMPORARY HACK ??? */ + cinfo->progressive_mode) + cinfo->optimize_coding = TRUE; /* assume default tables no good for + progressive mode or lossless mode */ + for (i = 0; i < NUM_HUFF_TBLS; i++) { + if (cinfo->dc_huff_tbl_ptrs[i] != NULL || + cinfo->ac_huff_tbl_ptrs[i] != NULL) { + empty_huff_tables = FALSE; + break; + } + } + if (cinfo->data_precision == 12 && !cinfo->optimize_coding && + (empty_huff_tables || using_std_huff_tables(cinfo))) + cinfo->optimize_coding = TRUE; /* assume default tables no good for + 12-bit data precision */ + } /* Initialize my private state */ if (transcode_only) { diff --git a/jcomapi.c b/jcomapi.c index efbb835..84f37e1 100644 --- a/jcomapi.c +++ b/jcomapi.c @@ -3,8 +3,8 @@ * * This file was part of the Independent JPEG Group's software: * Copyright (C) 1994-1997, Thomas G. Lane. - * It was modified by The libjpeg-turbo Project to include only code relevant - * to libjpeg-turbo. + * libjpeg-turbo Modifications: + * Copyright (C) 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -51,6 +51,7 @@ jpeg_abort(j_common_ptr cinfo) * A bit kludgy to do it here, but this is the most central place. */ ((j_decompress_ptr)cinfo)->marker_list = NULL; + ((j_decompress_ptr)cinfo)->master->marker_list_end = NULL; } else { cinfo->global_state = CSTATE_START; } diff --git a/jconfigint.h.in b/jconfigint.h.in index e7e66e7..5c14e32 100644 --- a/jconfigint.h.in +++ b/jconfigint.h.in @@ -1,6 +1,9 @@ /* libjpeg-turbo build number */ #define BUILD "@BUILD@" +/* How to hide global symbols. */ +#define HIDDEN @HIDDEN@ + /* Compiler's inline keyword */ #undef inline diff --git a/jcparam.c b/jcparam.c index d1dee4d..1d6e225 100644 --- a/jcparam.c +++ b/jcparam.c @@ -233,7 +233,7 @@ jpeg_set_defaults(j_compress_ptr cinfo) * tables will be computed. This test can be removed if default tables * are supplied that are valid for the desired precision. */ - if (cinfo->data_precision == 12 && !cinfo->arith_code) + if (cinfo->data_precision == 12) cinfo->optimize_coding = TRUE; /* By default, use the simpler non-cosited sampling alignment */ diff --git a/jcphuff.c b/jcphuff.c index 56e63bd..5828732 100644 --- a/jcphuff.c +++ b/jcphuff.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2011, 2015, 2018, 2021-2022, D. R. Commander. + * Copyright (C) 2011, 2015, 2018, 2021-2022, 2024, D. R. Commander. * Copyright (C) 2016, 2018, 2022, Matthieu Darbois. * Copyright (C) 2020, Arm Limited. * Copyright (C) 2021, Alex Richardson. @@ -44,40 +44,7 @@ #ifdef C_PROGRESSIVE_SUPPORTED -/* - * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be - * used for bit counting rather than the lookup table. This will reduce the - * memory footprint by 64k, which is important for some mobile applications - * that create many isolated instances of libjpeg-turbo (web browsers, for - * instance.) This may improve performance on some mobile platforms as well. - * This feature is enabled by default only on Arm processors, because some x86 - * chips have a slow implementation of bsr, and the use of clz/bsr cannot be - * shown to have a significant performance impact even on the x86 chips that - * have a fast implementation of it. When building for Armv6, you can - * explicitly disable the use of clz/bsr by adding -mthumb to the compiler - * flags (this defines __thumb__). - */ - -/* NOTE: Both GCC and Clang define __GNUC__ */ -#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ - defined(_M_ARM) || defined(_M_ARM64) -#if !defined(__thumb__) || defined(__thumb2__) -#define USE_CLZ_INTRINSIC -#endif -#endif - -#ifdef USE_CLZ_INTRINSIC -#if defined(_MSC_VER) && !defined(__clang__) -#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) -#else -#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) -#endif -#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) -#else -#include "jpeg_nbits_table.h" -#define JPEG_NBITS(x) (jpeg_nbits_table[x]) -#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) -#endif +#include "jpeg_nbits.h" /* Expanded entropy encoder object for progressive Huffman encoding. */ @@ -683,6 +650,11 @@ encode_mcu_AC_first(j_compress_ptr cinfo, JBLOCKROW *MCU_data) size_t bits[8 / SIZEOF_SIZE_T]; int max_coef_bits = cinfo->data_precision + 2; +#ifdef ZERO_BUFFERS + memset(values_unaligned, 0, sizeof(values_unaligned)); + memset(bits, 0, sizeof(bits)); +#endif + entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; @@ -948,6 +920,11 @@ encode_mcu_AC_refine(j_compress_ptr cinfo, JBLOCKROW *MCU_data) size_t zerobits, signbits; size_t bits[16 / SIZEOF_SIZE_T]; +#ifdef ZERO_BUFFERS + memset(absvalues_unaligned, 0, sizeof(absvalues_unaligned)); + memset(bits, 0, sizeof(bits)); +#endif + entropy->next_output_byte = cinfo->dest->next_output_byte; entropy->free_in_buffer = cinfo->dest->free_in_buffer; diff --git a/jdapimin.c b/jdapimin.c index 51ca552..30d9284 100644 --- a/jdapimin.c +++ b/jdapimin.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2016, 2022, D. R. Commander. + * Copyright (C) 2016, 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -160,9 +160,12 @@ default_decompress_parms(j_decompress_ptr cinfo) int cid1 = cinfo->comp_info[1].component_id; int cid2 = cinfo->comp_info[2].component_id; - if (cid0 == 1 && cid1 == 2 && cid2 == 3) - cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ - else if (cid0 == 82 && cid1 == 71 && cid2 == 66) + if (cid0 == 1 && cid1 == 2 && cid2 == 3) { + if (cinfo->master->lossless) + cinfo->jpeg_color_space = JCS_RGB; /* assume RGB w/out marker */ + else + cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */ + } else if (cid0 == 82 && cid1 == 71 && cid2 == 66) cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */ else { TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2); diff --git a/jdapistd.c b/jdapistd.c index 1f44927..38da36b 100644 --- a/jdapistd.c +++ b/jdapistd.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1994-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2015-2020, 2022-2023, D. R. Commander. + * Copyright (C) 2010, 2015-2020, 2022-2024, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg * file. @@ -200,7 +200,8 @@ _jpeg_crop_scanline(j_decompress_ptr cinfo, JDIMENSION *xoffset, ERREXIT(cinfo, JERR_BAD_CROP_SPEC); /* xoffset and width must fall within the output image dimensions. */ - if (*width == 0 || *xoffset + *width > cinfo->output_width) + if (*width == 0 || + (unsigned long long)(*xoffset) + *width > cinfo->output_width) ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); /* No need to do anything if the caller wants the entire width. */ @@ -482,7 +483,8 @@ _jpeg_skip_scanlines(j_decompress_ptr cinfo, JDIMENSION num_lines) ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); /* Do not skip past the bottom of the image. */ - if (cinfo->output_scanline + num_lines >= cinfo->output_height) { + if ((unsigned long long)cinfo->output_scanline + num_lines >= + cinfo->output_height) { num_lines = cinfo->output_height - cinfo->output_scanline; cinfo->output_scanline = cinfo->output_height; (*cinfo->inputctl->finish_input_pass) (cinfo); diff --git a/jdatadst-tj.c b/jdatadst-tj.c index cce263a..270b2c2 100644 --- a/jdatadst-tj.c +++ b/jdatadst-tj.c @@ -19,6 +19,7 @@ */ /* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#define JPEG_INTERNALS #include "jinclude.h" #include "jpeglib.h" #include "jerror.h" @@ -92,7 +93,7 @@ empty_mem_output_buffer(j_compress_ptr cinfo) /* Try to allocate new buffer with double size */ nextsize = dest->bufsize * 2; - nextbuffer = (JOCTET *)malloc(nextsize); + nextbuffer = (JOCTET *)MALLOC(nextsize); if (nextbuffer == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); @@ -183,7 +184,7 @@ jpeg_mem_dest_tj(j_compress_ptr cinfo, unsigned char **outbuffer, if (*outbuffer == NULL || *outsize == 0) { if (alloc) { /* Allocate initial buffer */ - dest->newbuffer = *outbuffer = (unsigned char *)malloc(OUTPUT_BUF_SIZE); + dest->newbuffer = *outbuffer = (unsigned char *)MALLOC(OUTPUT_BUF_SIZE); if (dest->newbuffer == NULL) ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 10); *outsize = OUTPUT_BUF_SIZE; diff --git a/jdmarker.c b/jdmarker.c index acd28ce..f918ee4 100644 --- a/jdmarker.c +++ b/jdmarker.c @@ -6,7 +6,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2012, 2015, 2022, D. R. Commander. + * Copyright (C) 2012, 2015, 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -248,6 +248,9 @@ get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_lossless, jpeg_component_info *compptr; INPUT_VARS(cinfo); + if (cinfo->marker->saw_SOF) + ERREXIT(cinfo, JERR_SOF_DUPLICATE); + cinfo->progressive_mode = is_prog; cinfo->master->lossless = is_lossless; cinfo->arith_code = is_arith; @@ -265,9 +268,6 @@ get_sof(j_decompress_ptr cinfo, boolean is_prog, boolean is_lossless, (int)cinfo->image_width, (int)cinfo->image_height, cinfo->num_components); - if (cinfo->marker->saw_SOF) - ERREXIT(cinfo, JERR_SOF_DUPLICATE); - /* We don't support files in which the image height is initially specified */ /* as 0 and is later redefined by DNL. As long as we have to check that, */ /* might as well have a general sanity check. */ @@ -819,13 +819,11 @@ save_marker(j_decompress_ptr cinfo) /* Done reading what we want to read */ if (cur_marker != NULL) { /* will be NULL if bogus length word */ /* Add new marker to end of list */ - if (cinfo->marker_list == NULL) { - cinfo->marker_list = cur_marker; + if (cinfo->marker_list == NULL || cinfo->master->marker_list_end == NULL) { + cinfo->marker_list = cinfo->master->marker_list_end = cur_marker; } else { - jpeg_saved_marker_ptr prev = cinfo->marker_list; - while (prev->next != NULL) - prev = prev->next; - prev->next = cur_marker; + cinfo->master->marker_list_end->next = cur_marker; + cinfo->master->marker_list_end = cur_marker; } /* Reset pointer & calc remaining data length */ data = cur_marker->data; diff --git a/jerror.c b/jerror.c index d0ab5b8..2133244 100644 --- a/jerror.c +++ b/jerror.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-1998, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2022, D. R. Commander. + * Copyright (C) 2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -40,13 +40,11 @@ * Create the message string table. * We do this from the master message list in jerror.h by re-reading * jerror.h with a suitable definition for macro JMESSAGE. - * The message table is made an external symbol just in case any applications - * want to refer to it directly. */ #define JMESSAGE(code, string) string, -const char * const jpeg_std_message_table[] = { +static const char * const jpeg_std_message_table[] = { #include "jerror.h" NULL }; @@ -229,23 +227,17 @@ reset_error_mgr(j_common_ptr cinfo) GLOBAL(struct jpeg_error_mgr *) jpeg_std_error(struct jpeg_error_mgr *err) { + memset(err, 0, sizeof(struct jpeg_error_mgr)); + err->error_exit = error_exit; err->emit_message = emit_message; err->output_message = output_message; err->format_message = format_message; err->reset_error_mgr = reset_error_mgr; - err->trace_level = 0; /* default = no tracing */ - err->num_warnings = 0; /* no warnings emitted yet */ - err->msg_code = 0; /* may be useful as a flag for "no error" */ - /* Initialize message table pointers */ err->jpeg_message_table = jpeg_std_message_table; err->last_jpeg_message = (int)JMSG_LASTMSGCODE - 1; - err->addon_message_table = NULL; - err->first_addon_message = 0; /* for safety */ - err->last_addon_message = 0; - return err; } diff --git a/jerror.h b/jerror.h index 39362fd..71ba03e 100644 --- a/jerror.h +++ b/jerror.h @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2014, 2017, 2021-2022, D. R. Commander. + * Copyright (C) 2014, 2017, 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -111,7 +111,7 @@ JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time") #if JPEG_LIB_VERSION >= 70 JMESSAGE(JERR_NO_ARITH_TABLE, "Arithmetic table 0x%02x was not defined") #endif -JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported") +JMESSAGE(JERR_NO_BACKING_STORE, "Memory limit exceeded") JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined") JMESSAGE(JERR_NO_IMAGE, "JPEG datastream contains no image") JMESSAGE(JERR_NO_QUANT_TABLE, "Quantization table 0x%02x was not defined") diff --git a/jmemnobs.c b/jmemnobs.c index cd6571b..692775f 100644 --- a/jmemnobs.c +++ b/jmemnobs.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1992-1996, Thomas G. Lane. * libjpeg-turbo Modifications: - * Copyright (C) 2017-2018, D. R. Commander. + * Copyright (C) 2017-2018, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -31,7 +31,7 @@ GLOBAL(void *) jpeg_get_small(j_common_ptr cinfo, size_t sizeofobject) { - return (void *)malloc(sizeofobject); + return (void *)MALLOC(sizeofobject); } GLOBAL(void) @@ -48,7 +48,7 @@ jpeg_free_small(j_common_ptr cinfo, void *object, size_t sizeofobject) GLOBAL(void *) jpeg_get_large(j_common_ptr cinfo, size_t sizeofobject) { - return (void *)malloc(sizeofobject); + return (void *)MALLOC(sizeofobject); } GLOBAL(void) diff --git a/jmemsys.h b/jmemsys.h index 9229550..ac09ef4 100644 --- a/jmemsys.h +++ b/jmemsys.h @@ -99,24 +99,6 @@ EXTERN(size_t) jpeg_mem_available(j_common_ptr cinfo, size_t min_bytes_needed, #define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */ -#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */ - -typedef unsigned short XMSH; /* type of extended-memory handles */ -typedef unsigned short EMSH; /* type of expanded-memory handles */ - -typedef union { - short file_handle; /* DOS file handle if it's a temp file */ - XMSH xms_handle; /* handle if it's a chunk of XMS */ - EMSH ems_handle; /* handle if it's a chunk of EMS */ -} handle_union; - -#endif /* USE_MSDOS_MEMMGR */ - -#ifdef USE_MAC_MEMMGR /* Mac-specific junk */ -#include -#endif /* USE_MAC_MEMMGR */ - - typedef struct backing_store_struct *backing_store_ptr; typedef struct backing_store_struct { @@ -130,22 +112,9 @@ typedef struct backing_store_struct { void (*close_backing_store) (j_common_ptr cinfo, backing_store_ptr info); /* Private fields for system-dependent backing-store management */ -#ifdef USE_MSDOS_MEMMGR - /* For the MS-DOS manager (jmemdos.c), we need: */ - handle_union handle; /* reference to backing-store storage object */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else -#ifdef USE_MAC_MEMMGR - /* For the Mac manager (jmemmac.c), we need: */ - short temp_file; /* file reference number to temp file */ - FSSpec tempSpec; /* the FSSpec for the temp file */ - char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */ -#else /* For a typical implementation with temp files, we need: */ FILE *temp_file; /* stdio reference to temp file */ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */ -#endif -#endif } backing_store_info; diff --git a/jpeg_nbits.c b/jpeg_nbits.c new file mode 100644 index 0000000..c8ee6b0 --- /dev/null +++ b/jpeg_nbits.c @@ -0,0 +1,4134 @@ +/* + * Copyright (C) 2024, D. R. Commander. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +#include "jpeg_nbits.h" +#include "jconfigint.h" + + +#ifndef USE_CLZ_INTRINSIC + +#define INCLUDE_JPEG_NBITS_TABLE + +/* When building for x86[-64] with the SIMD extensions enabled, the C Huffman + * encoders can reuse jpeg_nbits_table from the SSE2 baseline Huffman encoder. + */ +#if (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_X64)) && defined(WITH_SIMD) +#undef INCLUDE_JPEG_NBITS_TABLE +#endif + +#endif + + +#ifdef INCLUDE_JPEG_NBITS_TABLE + +const unsigned char HIDDEN jpeg_nbits_table[65536] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 +}; + +#else + +/* Suppress compiler warnings about empty translation unit. */ + +typedef int dummy_jpeg_nbits_table; + +#endif diff --git a/jpeg_nbits.h b/jpeg_nbits.h new file mode 100644 index 0000000..6481a12 --- /dev/null +++ b/jpeg_nbits.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014, 2021, 2024, D. R. Commander. + * Copyright (C) 2014, Olle Liljenzin. + * Copyright (C) 2020, Arm Limited. + * + * For conditions of distribution and use, see the accompanying README.ijg + * file. + */ + +/* + * NOTE: If USE_CLZ_INTRINSIC is defined, then clz/bsr instructions will be + * used for bit counting rather than the lookup table. This will reduce the + * memory footprint by 64k, which is important for some mobile applications + * that create many isolated instances of libjpeg-turbo (web browsers, for + * instance.) This may improve performance on some mobile platforms as well. + * This feature is enabled by default only on Arm processors, because some x86 + * chips have a slow implementation of bsr, and the use of clz/bsr cannot be + * shown to have a significant performance impact even on the x86 chips that + * have a fast implementation of it. When building for Armv6, you can + * explicitly disable the use of clz/bsr by adding -mthumb to the compiler + * flags (this defines __thumb__). + */ + +/* NOTE: Both GCC and Clang define __GNUC__ */ +#if (defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))) || \ + defined(_M_ARM) || defined(_M_ARM64) +#if !defined(__thumb__) || defined(__thumb2__) +#define USE_CLZ_INTRINSIC +#endif +#endif + +#ifdef USE_CLZ_INTRINSIC +#if defined(_MSC_VER) && !defined(__clang__) +#define JPEG_NBITS_NONZERO(x) (32 - _CountLeadingZeros(x)) +#else +#define JPEG_NBITS_NONZERO(x) (32 - __builtin_clz(x)) +#endif +#define JPEG_NBITS(x) (x ? JPEG_NBITS_NONZERO(x) : 0) +#else +extern const unsigned char jpeg_nbits_table[65536]; +#define JPEG_NBITS(x) (jpeg_nbits_table[x]) +#define JPEG_NBITS_NONZERO(x) JPEG_NBITS(x) +#endif diff --git a/jpeg_nbits_table.h b/jpeg_nbits_table.h deleted file mode 100644 index fcf7387..0000000 --- a/jpeg_nbits_table.h +++ /dev/null @@ -1,4098 +0,0 @@ -static const unsigned char jpeg_nbits_table[65536] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 -}; diff --git a/jpegint.h b/jpegint.h index 6541420..a90493f 100644 --- a/jpegint.h +++ b/jpegint.h @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2015-2017, 2019, 2021-2022, D. R. Commander. + * Copyright (C) 2015-2017, 2019, 2021-2022, 2024, D. R. Commander. * Copyright (C) 2015, Google, Inc. * Copyright (C) 2021, Alex Richardson. * For conditions of distribution and use, see the accompanying README.ijg @@ -249,6 +249,9 @@ struct jpeg_decomp_master { /* Last iMCU row that was successfully decoded */ JDIMENSION last_good_iMCU_row; + + /* Tail of list of saved markers */ + jpeg_saved_marker_ptr marker_list_end; }; /* Input control module */ @@ -443,6 +446,12 @@ struct jpeg_color_quantizer { #undef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) +#ifdef ZERO_BUFFERS +#define MALLOC(size) calloc(1, size) +#else +#define MALLOC(size) malloc(size) +#endif + /* We assume that right shift corresponds to signed division by 2 with * rounding towards minus infinity. This is correct for typical "arithmetic diff --git a/jpeglib.h b/jpeglib.h index a59e98c..17e7833 100644 --- a/jpeglib.h +++ b/jpeglib.h @@ -7,7 +7,7 @@ * Lossless JPEG Modifications: * Copyright (C) 1999, Ken Murchison. * libjpeg-turbo Modifications: - * Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, 2022-2023, + * Copyright (C) 2009-2011, 2013-2014, 2016-2017, 2020, 2022-2024, D. R. Commander. * Copyright (C) 2015, Google, Inc. * For conditions of distribution and use, see the accompanying README.ijg @@ -18,6 +18,16 @@ * and perhaps jerror.h if they want to know the exact error codes. */ +/* NOTE: This header file does not include stdio.h, despite the fact that it + * uses FILE and size_t. That is by design, since the libjpeg API predates the + * widespread adoption of ANSI/ISO C. Referring to libjpeg.txt, it is a + * documented requirement that calling programs "include system headers that + * define at least the typedefs FILE and size_t" before including jpeglib.h. + * Technically speaking, changing that requirement by including stdio.h here + * would break backward API compatibility. Please do not file bug reports, + * feature requests, or pull requests regarding this. + */ + #ifndef JPEGLIB_H #define JPEGLIB_H @@ -575,11 +585,10 @@ struct jpeg_decompress_struct { */ int actual_number_of_colors; /* number of entries in use */ JSAMPARRAY colormap; /* The color map as a 2-D pixel array - If data_precision is 12 or 16, then this is - actually a J12SAMPARRAY or a J16SAMPARRAY, - so callers must type-cast it in order to - read/write 12-bit or 16-bit samples from/to - the array. */ + If data_precision is 12, then this is + actually a J12SAMPARRAY, so callers must + type-cast it in order to read/write 12-bit + samples from/to the array. */ /* State variables: these variables indicate the progress of decompression. * The application may examine these but must not modify them. diff --git a/jpegtran.1 b/jpegtran.1 index 5b1ded2..a4ba383 100644 --- a/jpegtran.1 +++ b/jpegtran.1 @@ -1,4 +1,4 @@ -.TH JPEGTRAN 1 "13 July 2021" +.TH JPEGTRAN 1 "30 August 2024" .SH NAME jpegtran \- lossless transformation of JPEG files .SH SYNOPSIS @@ -13,7 +13,7 @@ jpegtran \- lossless transformation of JPEG files .SH DESCRIPTION .LP .B jpegtran -performs various useful transformations of JPEG files. +performs various useful transformations of lossy (DCT-based) JPEG files. It can translate the coded representation from one variant of JPEG to another, for example from baseline JPEG to progressive JPEG or vice versa. It can also perform some rearrangements of the image data, for example turning an image @@ -64,13 +64,13 @@ Perform optimization of entropy encoding parameters. .B \-progressive Create progressive JPEG file. .TP -.BI \-restart " N" -Emit a JPEG restart marker every N MCU rows, or every N MCU blocks if "B" is -attached to the number. -.TP .B \-arithmetic Use arithmetic coding. .TP +.BI \-restart " N" +Emit a JPEG restart marker every N MCU rows, or every N MCUs if "B" is attached +to the number. +.TP .BI \-scans " file" Use the scan script given in the specified text file. .PP @@ -166,8 +166,8 @@ the current JPEG format; the upper left corner of the selected region must fall on an iMCU boundary. If it doesn't, then it is silently moved up and/or left to the nearest iMCU boundary (the lower right corner is unchanged.) Thus, the output image covers at least the requested region, but it may cover more. The -adjustment of the region dimensions may be optionally disabled by attaching an -'f' character ("force") to the width or height number. +adjustment of the region dimensions may be optionally disabled by attaching +an 'f' character ("force") to the width or height number. The image can be losslessly cropped by giving the switch: .TP diff --git a/jpegtran.c b/jpegtran.c index d1552ec..b7d7ebb 100644 --- a/jpegtran.c +++ b/jpegtran.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1995-2019, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2014, 2017, 2019-2022, D. R. Commander. + * Copyright (C) 2010, 2014, 2017, 2019-2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -35,11 +35,11 @@ static const char *progname; /* program name for error messages */ static char *icc_filename; /* for -icc switch */ -JDIMENSION max_scans; /* for -maxscans switch */ +static JDIMENSION max_scans; /* for -maxscans switch */ static char *outfilename; /* for -outfile switch */ static char *dropfilename; /* for -drop switch */ -boolean report; /* for -report switch */ -boolean strict; /* for -strict switch */ +static boolean report; /* for -report switch */ +static boolean strict; /* for -strict switch */ static JCOPY_OPTION copyoption; /* -copy switch */ static jpeg_transform_info transformoption; /* image transformation options */ @@ -183,7 +183,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, exit(EXIT_FAILURE); #endif - } else if (keymatch(arg, "copy", 2)) { + } else if (keymatch(arg, "copy", 1)) { /* Select which extra markers to copy. */ if (++argn >= argc) /* advance to next argument */ usage(); @@ -241,7 +241,8 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, if (!printed_version) { fprintf(stderr, "%s version %s (build %s)\n", PACKAGE_NAME, VERSION, BUILD); - fprintf(stderr, "%s\n\n", JCOPYRIGHT); + fprintf(stderr, JCOPYRIGHT1); + fprintf(stderr, JCOPYRIGHT2 "\n"); fprintf(stderr, "Emulating The Independent JPEG Group's software, version %s\n\n", JVERSION); printed_version = TRUE; @@ -319,7 +320,7 @@ parse_switches(j_compress_ptr cinfo, int argc, char **argv, * handle. */ transformoption.perfect = TRUE; - } else if (keymatch(arg, "progressive", 2)) { + } else if (keymatch(arg, "progressive", 1)) { /* Select simple progressive mode. */ #ifdef C_PROGRESSIVE_SUPPORTED simple_progressive = TRUE; diff --git a/jquant1.c b/jquant1.c index 2e914b9..bd68dcb 100644 --- a/jquant1.c +++ b/jquant1.c @@ -86,22 +86,22 @@ static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = { * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I. * The values in this array must range from 0 to ODITHER_CELLS-1. */ - { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 }, - { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 }, - { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 }, - { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 }, - { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 }, - { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 }, - { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 }, - { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 }, - { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 }, - { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 }, - { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 }, - { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 }, - { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 }, - { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 }, - { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 }, - { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 } + { 0, 192, 48, 240, 12, 204, 60, 252, 3, 195, 51, 243, 15, 207, 63, 255 }, + { 128, 64, 176, 112, 140, 76, 188, 124, 131, 67, 179, 115, 143, 79, 191, 127 }, + { 32, 224, 16, 208, 44, 236, 28, 220, 35, 227, 19, 211, 47, 239, 31, 223 }, + { 160, 96, 144, 80, 172, 108, 156, 92, 163, 99, 147, 83, 175, 111, 159, 95 }, + { 8, 200, 56, 248, 4, 196, 52, 244, 11, 203, 59, 251, 7, 199, 55, 247 }, + { 136, 72, 184, 120, 132, 68, 180, 116, 139, 75, 187, 123, 135, 71, 183, 119 }, + { 40, 232, 24, 216, 36, 228, 20, 212, 43, 235, 27, 219, 39, 231, 23, 215 }, + { 168, 104, 152, 88, 164, 100, 148, 84, 171, 107, 155, 91, 167, 103, 151, 87 }, + { 2, 194, 50, 242, 14, 206, 62, 254, 1, 193, 49, 241, 13, 205, 61, 253 }, + { 130, 66, 178, 114, 142, 78, 190, 126, 129, 65, 177, 113, 141, 77, 189, 125 }, + { 34, 226, 18, 210, 46, 238, 30, 222, 33, 225, 17, 209, 45, 237, 29, 221 }, + { 162, 98, 146, 82, 174, 110, 158, 94, 161, 97, 145, 81, 173, 109, 157, 93 }, + { 10, 202, 58, 250, 6, 198, 54, 246, 9, 201, 57, 249, 5, 197, 53, 245 }, + { 138, 74, 186, 122, 134, 70, 182, 118, 137, 73, 185, 121, 133, 69, 181, 117 }, + { 42, 234, 26, 218, 38, 230, 22, 214, 41, 233, 25, 217, 37, 229, 21, 213 }, + { 170, 106, 154, 90, 166, 102, 150, 86, 169, 105, 153, 89, 165, 101, 149, 85 } }; diff --git a/jversion.h.in b/jversion.h.in index 42a4e73..fc0ce3e 100644 --- a/jversion.h.in +++ b/jversion.h.in @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2012-2023, D. R. Commander. + * Copyright (C) 2010, 2012-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -36,20 +36,21 @@ * their code */ -#define JCOPYRIGHT \ - "Copyright (C) 2009-2023 D. R. Commander\n" \ +#define JCOPYRIGHT1 \ + "Copyright (C) 2009-2024 D. R. Commander\n" \ "Copyright (C) 2015, 2020 Google, Inc.\n" \ "Copyright (C) 2019-2020 Arm Limited\n" \ "Copyright (C) 2015-2016, 2018 Matthieu Darbois\n" \ "Copyright (C) 2011-2016 Siarhei Siamashka\n" \ - "Copyright (C) 2015 Intel Corporation\n" \ + "Copyright (C) 2015 Intel Corporation\n" +#define JCOPYRIGHT2 \ "Copyright (C) 2013-2014 Linaro Limited\n" \ "Copyright (C) 2013-2014 MIPS Technologies, Inc.\n" \ "Copyright (C) 2009, 2012 Pierre Ossman for Cendio AB\n" \ "Copyright (C) 2009-2011 Nokia Corporation and/or its subsidiary(-ies)\n" \ "Copyright (C) 1999-2006 MIYASAKA Masaru\n" \ "Copyright (C) 1999 Ken Murchison\n" \ - "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding" + "Copyright (C) 1991-2020 Thomas G. Lane, Guido Vollbeding\n" #define JCOPYRIGHT_SHORT \ "Copyright (C) @COPYRIGHT_YEAR@ The libjpeg-turbo Project and many others" diff --git a/libjpeg.txt b/libjpeg.txt index 2dae2d2..cca5739 100644 --- a/libjpeg.txt +++ b/libjpeg.txt @@ -5,7 +5,7 @@ Copyright (C) 1994-2013, Thomas G. Lane, Guido Vollbeding. Lossless JPEG Modifications: Copyright (C) 1999, Ken Murchison. libjpeg-turbo Modifications: -Copyright (C) 2010, 2014-2018, 2020, 2022-2023, D. R. Commander. +Copyright (C) 2010, 2014-2018, 2020, 2022-2024, D. R. Commander. Copyright (C) 2015, Google, Inc. For conditions of distribution and use, see the accompanying README.ijg file. @@ -114,22 +114,24 @@ used by the free LIBTIFF library to support JPEG compression in TIFF.) 12-bit and 16-bit Data Precision -------------------------------- -The JPEG standard provides for baseline 8-bit and 12-bit DCT processes as well -as 8-bit, 12-bit, and 16-bit lossless (predictive) processes. This code -supports 12-bit-per-component lossy or lossless JPEG if you set -cinfo->data_precision to 12 and 16-bit-per-component lossless JPEG if you set -cinfo->data_precision to 16. Note that this causes the sample size to be -larger than a char, so it affects the surrounding application's image data. -The sample applications cjpeg and djpeg can support 12-bit mode only for PPM, -PGM, and GIF file formats and 16-bit mode only for PPM and PGM file formats. - -Note that, when 12-bit data precision is enabled, the library always compresses -in Huffman optimization mode, in order to generate valid Huffman tables. This -is necessary because our default Huffman tables only cover 8-bit data. If you -need to output 12-bit files in one pass, you'll have to supply suitable default -Huffman tables. You may also want to supply your own DCT quantization tables; -the existing quality-scaling code has been developed for 8-bit use, and -probably doesn't generate especially good tables for 12-bit. +The JPEG standard provides for baseline (8-bit-per-sample) and +12-bit-per-sample DCT processes as well as 8-bit-per-sample, 12-bit-per-sample, +and 16-bit-per-sample lossless (predictive) processes. This code supports +12-bit-per-sample lossy or lossless JPEG if you set cinfo->data_precision to 12 +and 16-bit-per-sample lossless JPEG if you set cinfo->data_precision to 16. +Note that this causes the sample size to be larger than a char, so it affects +the surrounding application's image data. The sample applications cjpeg and +djpeg can support 12-bit data precision only for PPM, PGM, and GIF file formats +and 16-bit data precision only for 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 +Huffman tables. This is necessary because our default Huffman tables only +cover 8-bit data. If you need to output 12-bit-per-sample JPEG files in one +pass, you'll have to supply suitable default Huffman tables. You may also want +to supply your own DCT quantization tables; the existing quality-scaling code +has been developed for 8-bit data precision and probably doesn't generate +especially good tables for 12-bit data precision. Functions that are specific to 12-bit data precision have a prefix of "jpeg12_" instead of "jpeg_" and use the following data types and macros: @@ -160,7 +162,8 @@ Refer to the descriptions of the data_precision compression and decompression parameters below for further information. This documentation uses "J*SAMPLE", "J*SAMPROW", "J*SAMPARRAY", and -"J*SAMPIMAGE" to generically refer to the 8-bit, 12-bit, or 16-bit data types. +"J*SAMPIMAGE" to generically refer to the 8-bit-per-sample, 12-bit-per-sample, +or 16-bit-per-sample data types. Outline of typical usage @@ -267,10 +270,9 @@ and the other references mentioned in the README.ijg file. Pixels are stored by scanlines, with each scanline running from left to right. The component values for each pixel are adjacent in the row; for example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color. Each scanline is an -array of data type JSAMPLE or J12SAMPLE --- which is typically "unsigned char" -or "short" (respectively), unless you've changed jmorecfg.h. (You can also -change the RGB pixel layout, say to B,G,R order, by modifying jmorecfg.h. But -see the restrictions listed in that file before doing so.) +array of data type JSAMPLE, J12SAMPLE, or J16SAMPLE --- which is typically +"unsigned char", "short", or "unsigned short" (respectively) unless you've +changed jmorecfg.h. A 2-D array of pixels is formed by making a list of pointers to the starts of scanlines; so the scanlines need not be physically adjacent in memory. Even @@ -285,10 +287,11 @@ have it all in memory, but usually it's simplest to process one scanline at a time. For best results, source data values should have the precision specified by -cinfo->data_precision (normally 8 bits). For instance, if you choose to -compress data that's only 6 bits/channel, you should left-justify each value in -a byte before passing it to the compressor. If you need to compress data -that has more than 8 bits/channel, set cinfo->data_precision = 12 or 16. +cinfo->data_precision (normally 8 bits per sample). For instance, if you +choose to compress data that's only 6 bits/channel, you should left-justify +each value in a byte before passing it to the compressor. If you need to +compress data that has more than 8 bits/channel, set cinfo->data_precision = 12 +or 16. The data format returned by the decompressor is the same in all details, @@ -301,8 +304,8 @@ a 2-D J*SAMPARRAY in which each row holds the values of one color component, that is, colormap[i][j] is the value of the i'th color component for pixel value (map index) j. Note that since the colormap indexes are stored in J*SAMPLEs, the maximum number of colors is limited by the size of J*SAMPLE -(ie, at most 256 colors for 8-bit data precision, 4096 colors for 12-bit data -precision, and 65536 colors for 16-bit data precision). +(ie, at most 256 colors for 8-bit data precision and 4096 colors for 12-bit +data precision). Compression details @@ -972,7 +975,7 @@ jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline) entries are constrained to the range 1..255 for full JPEG baseline compatibility. In the current implementation, this only makes a difference for quality settings below 25, and it effectively prevents - very small/low quality files from being generated. The IJG decoder + very small/low-quality files from being generated. The IJG decoder is capable of reading the non-baseline files generated at low quality settings when force_baseline is FALSE, but other decoders may not be. @@ -1028,8 +1031,11 @@ jpeg_enable_lossless (j_compress_ptr cinfo, int predictor_selection_value, is necessary in order to create a fully lossless JPEG image. (A non-zero point transform value right-shifts the input samples by the specified number of bits, which is effectively a form of lossy color - quantization.) Note that the following features will be unavailable - when compressing or decompressing lossless JPEG images: + quantization.) In most cases, lossless mode is considerably slower + than, and does not compress as effectively as, lossy mode. Thus, it is + typically used only for applications that require mathematically + lossless compression. Note that the following features will be + unavailable when compressing or decompressing lossless JPEG images: * Partial image decompression * Quality/quantization table selection * DCT/IDCT algorithm selection @@ -1044,6 +1050,30 @@ jpeg_enable_lossless (j_compress_ptr cinfo, int predictor_selection_value, Any parameters used to enable or configure those features will be ignored. + Lossless mode shares no algorithms with lossy mode. Instead, it uses + differential pulse-code modulation (DPCM), an algorithm whereby each + sample is encoded as the difference between the sample's value and a + "predictor", which is based on the values of neighboring samples. If + Ra is the sample immediately to the left of the current sample, Rb is + the sample immediately above the current sample, and Rc is the sample + diagonally to the left and above the current sample, then the + relationship between the predictor selection value and the predictor is + as follows: + + PSV Predictor + -------------- + 1 Ra + 2 Rb + 3 Rc + 4 Ra + Rb – Rc + 5 Ra + (Rb – Rc) / 2 + 6 Rb + (Ra – Rc) / 2 + 7 (Ra + Rb) / 2 + + Predictors 1-3 are 1-dimensional predictors, whereas Predictors 4-7 are + 2-dimensional predictors. The best predictor for a particular image + depends on the image. + Compression parameters (cinfo fields) include: @@ -1052,13 +1082,15 @@ boolean arith_code If FALSE, use Huffman coding. int data_precision - To create a 12-bit-per-component JPEG file, set data_precision to 12 - prior to calling jpeg_start_compress() or using the memory manager, - then use jpeg12_write_scanlines() or jpeg12_write_raw_data() instead of - jpeg_write_scanlines() or jpeg_write_raw_data(). To create a - 16-bit-per-component lossless JPEG file, set data_precision to 16 prior + To create a 12-bit-per-sample JPEG file, set data_precision to 12 prior to calling jpeg_start_compress() or using the memory manager, then use - jpeg16_write_scanlines() instead of jpeg_write_scanlines(). + jpeg12_write_scanlines() or jpeg12_write_raw_data() instead of + jpeg_write_scanlines() or jpeg_write_raw_data(). To create a + 16-bit-per-sample lossless JPEG file, set data_precision to 16 prior to + calling jpeg_start_compress() or using the memory manager, then use + jpeg16_write_scanlines() instead of jpeg_write_scanlines(). Note that + 16-bit data precision requires lossless mode. (See + jpeg_enable_lossless().) J_DCT_METHOD dct_method Selects the algorithm used for the DCT step. Choices are: @@ -1109,20 +1141,23 @@ boolean optimize_coding Huffman tables. In most cases optimal tables save only a few percent of file size compared to the default tables. Note that when this is TRUE, you need not supply Huffman tables at all, and any you do - supply will be overwritten. + supply will be overwritten. Optimal Huffman tables are always + computed, and this parameter has no effect, in progressive mode or + lossless mode or with 12-bit data precision (unless Huffman tables have + been supplied.) This parameter also has no effect when using + arithmetic coding. unsigned int restart_interval int restart_in_rows To emit restart markers in the JPEG file, set one of these nonzero. - Set restart_interval to specify the exact interval in MCU blocks - (samples in lossless mode). Set restart_in_rows to specify the - interval in MCU rows. (If restart_in_rows is not 0, then - restart_interval is set after the image width in MCUs is computed.) - Defaults are zero (no restarts). One restart marker per MCU row is - often a good choice. NOTE: the overhead of restart markers is higher - in grayscale JPEG files than in color files, and MUCH higher in - progressive JPEGs. If you use restarts, you may want to use larger - intervals in those cases. + Set restart_interval to specify the exact interval in MCUs. Set + restart_in_rows to specify the interval in MCU rows. (If + restart_in_rows is not 0, then restart_interval is set after the image + width in MCUs is computed.) Defaults are zero (no restarts). One + restart marker per MCU row is often a good choice. NOTE: the overhead + of restart markers is higher in grayscale JPEG files than in color + files, and MUCH higher in progressive JPEGs. If you use restarts, you + may want to use larger intervals in those cases. const jpeg_scan_info *scan_info int num_scans @@ -1274,13 +1309,13 @@ recorded in the source file and need not be supplied by the application. the postprocessing done on the image to deliver it in a format suitable for the application's use. Many of the parameters control speed/quality tradeoffs, in which faster decompression may be obtained at the price of -a poorer-quality image. The defaults select the highest quality (slowest) +a poorer-quality image. The defaults select the highest-quality (slowest) processing. The following fields in the JPEG object are set by jpeg_read_header() and may be useful to the application in choosing decompression parameters: -int data_precision Data precision (bits per component) +int data_precision Data precision (bits per sample) If data_precision is 12, then use jpeg12_read_scanlines(), jpeg12_skip_scanlines(), jpeg12_crop_scanline(), and/or jpeg12_read_raw_data() instead of jpeg_read_scanlines(), @@ -1315,11 +1350,8 @@ J_COLOR_SPACE out_color_space based on jpeg_color_space; typically it will be RGB or grayscale. The application can change this field to request output in a different colorspace. For example, set it to JCS_GRAYSCALE to get grayscale - output from a color file. (This is useful for previewing: grayscale - output is faster than full color since the color components need not - be processed.) Note that not all possible color space transforms are - currently implemented; you may need to extend jdcolor.c if you want an - unusual conversion. + output from a color file. Note that not all possible color space + transforms are currently implemented. unsigned int scale_num, scale_denom Scale the image by the fraction scale_num/scale_denom. Default is @@ -1327,31 +1359,33 @@ unsigned int scale_num, scale_denom are M/8 with all M from 1 to 16, or any reduced fraction thereof (such as 1/2, 3/4, etc.) (The library design allows for arbitrary scaling ratios but this is not likely to be implemented any time soon.) - Smaller scaling ratios permit significantly faster decoding since - fewer pixels need be processed and a simpler IDCT method can be used. boolean quantize_colors + [legacy feature] If set TRUE, colormapped output will be delivered. Default is FALSE, meaning that full-color output will be delivered. The next three parameters are relevant only if quantize_colors is TRUE. int desired_number_of_colors + [legacy feature] Maximum number of colors to use in generating a library-supplied color map (the actual number of colors is returned in a different field). Default 256. Ignored when the application supplies its own color map. boolean two_pass_quantize + [legacy feature] If TRUE, an extra pass over the image is made to select a custom color map for the image. This usually looks a lot better than the one-size- fits-all colormap that is used otherwise. Default is TRUE. Ignored when the application supplies its own color map. J_DITHER_MODE dither_mode + [legacy feature] Selects color dithering method. Supported values are: - JDITHER_NONE no dithering: fast, very low quality + JDITHER_NONE no dithering: faster, very low quality JDITHER_ORDERED ordered dither: moderate speed and quality - JDITHER_FS Floyd-Steinberg dither: slow, high quality + JDITHER_FS Floyd-Steinberg dither: slower, high quality Default is JDITHER_FS. (At present, ordered dither is implemented only in the single-pass, standard-colormap case. If you ask for ordered dither when two_pass_quantize is TRUE or when you supply @@ -1366,16 +1400,18 @@ selects a suitable color map and sets these two fields itself. only accepted for 3-component output color spaces.] JSAMPARRAY colormap + [legacy feature] The color map, represented as a 2-D pixel array of out_color_components rows and actual_number_of_colors columns. Ignored if not quantizing. CAUTION: if the JPEG library creates its own colormap, the storage pointed to by this field is released by jpeg_finish_decompress(). Copy the colormap somewhere else first, if you want to save it. - CAUTION: if data_precision is 12 or 16, then this is actually a - J12SAMPARRAY or a J16SAMPARRAY, so it must be type-cast in order to - read/write 12-bit or 16-bit samples from/to the array. + CAUTION: if data_precision is 12, then this is actually a J12SAMPARRAY, + so it must be type-cast in order to read/write 12-bit samples from/to + the array. int actual_number_of_colors + [legacy feature] The number of colors in the color map. Additional decompression parameters that the application may set include: @@ -1432,6 +1468,7 @@ boolean do_block_smoothing boolean enable_1pass_quant boolean enable_external_quant boolean enable_2pass_quant + [legacy feature] These are significant only in buffered-image mode, which is described in its own section below. @@ -2301,7 +2338,7 @@ limited changes of parameters. ONLY THE FOLLOWING parameter changes are allowed after jpeg_start_decompress() is called: * dct_method can be changed before each call to jpeg_start_output(). For example, one could use a fast DCT method for early scans, changing - to a higher quality method for the final scan. + to a higher-quality method for the final scan. * dither_mode can be changed before each call to jpeg_start_output(); of course this has no impact if not using color quantization. Typically one would use ordered dither for initial passes, then switch to @@ -3153,10 +3190,10 @@ This does not count any memory allocated by the application, such as a buffer to hold the final output image. The above figures are valid for 8-bit JPEG data precision and a machine with -32-bit ints. For 12-bit and 16-bit JPEG data, double the size of the strip -buffers and quantization pixel buffer. The "fixed-size" data will be somewhat -smaller with 16-bit ints, larger with 64-bit ints. Also, CMYK or other unusual -color spaces will require different amounts of space. +32-bit ints. For 12-bit-per-sample and 16-bit-per-sample JPEG data, double the +size of the strip buffers and quantization pixel buffer. The "fixed-size" data +will be somewhat smaller with 16-bit ints, larger with 64-bit ints. Also, CMYK +or other unusual color spaces will require different amounts of space. The full-image coefficient and pixel buffers, if needed at all, do not have to be fully RAM resident; you can have the library use temporary @@ -3182,14 +3219,6 @@ The maximum number of components (color channels) in the image is determined by MAX_COMPONENTS. The JPEG standard allows up to 255 components, but we expect that few applications will need more than four or so. -On machines with unusual data type sizes, you may be able to improve -performance or reduce memory space by tweaking the various typedefs in -jmorecfg.h. In particular, on some RISC CPUs, access to arrays of "short"s -is quite slow; consider trading memory for speed by making JCOEF, INT16, and -UINT16 be "int" or "unsigned int". UINT8 is also a candidate to become int. -You probably don't want to make J*SAMPLE be int unless you have lots of memory -to burn. - You can reduce the size of the library by compiling out various optional functions. To do this, undefine xxx_SUPPORTED symbols as necessary. @@ -3228,9 +3257,7 @@ than 8 bits or short is much bigger than 16 bits. The code should work equally well with 16- or 32-bit ints. In a system where these assumptions are not met, you may be able to make the -code work by modifying the typedefs in jmorecfg.h. However, you will probably -have difficulty if int is less than 16 bits wide, since references to plain -int abound in the code. +code work by modifying the typedefs in jmorecfg.h. char can be either signed or unsigned, although the code runs faster if an unsigned char type is available. If char is wider than 8 bits, you will need diff --git a/md5/md5hl.c b/md5/md5hl.c index 849a136..8120093 100644 --- a/md5/md5hl.c +++ b/md5/md5hl.c @@ -6,7 +6,8 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * libjpeg-turbo Modifications: - * Copyright (C)2016, 2018-2019, 2022 D. R. Commander. All Rights Reserved. + * Copyright (C)2016, 2018-2019, 2022, 2024 D. R. Commander. + * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -111,7 +112,7 @@ char *MD5FileChunk(const char *filename, char *buf, off_t ofs, off_t len) n = len; i = 0; while (n > 0) { - if (n > sizeof(buffer)) + if ((size_t)n > sizeof(buffer)) i = read(f, buffer, sizeof(buffer)); else i = read(f, buffer, n); diff --git a/rdbmp.c b/rdbmp.c index 88ee751..c2c06fd 100644 --- a/rdbmp.c +++ b/rdbmp.c @@ -6,7 +6,7 @@ * Modified 2009-2017 by Guido Vollbeding. * libjpeg-turbo Modifications: * Modified 2011 by Siarhei Siamashka. - * Copyright (C) 2015, 2017-2018, 2021-2022, D. R. Commander. + * Copyright (C) 2015, 2017-2018, 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -523,11 +523,9 @@ start_input_bmp(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) if (biWidth <= 0 || biHeight <= 0) ERREXIT(cinfo, JERR_BMP_EMPTY); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sinfo->max_pixels && (unsigned long long)biWidth * biHeight > sinfo->max_pixels) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); -#endif + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels); if (biPlanes != 1) ERREXIT(cinfo, JERR_BMP_BADPLANES); @@ -681,9 +679,7 @@ jinit_read_bmp(j_compress_ptr cinfo, boolean use_inversion_array) /* Fill in method ptrs, except get_pixel_rows which start_input sets */ source->pub.start_input = start_input_bmp; source->pub.finish_input = finish_input_bmp; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION source->pub.max_pixels = 0; -#endif source->use_inversion_array = use_inversion_array; diff --git a/rdgif.c b/rdgif.c index 0cbd279..23e8b9e 100644 --- a/rdgif.c +++ b/rdgif.c @@ -5,7 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * Modified 2019 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2021-2022, D. R. Commander. + * Copyright (C) 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -418,11 +418,9 @@ start_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) height = LM_to_uint(hdrbuf, 2); if (width == 0 || height == 0) ERREXIT(cinfo, JERR_GIF_EMPTY); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sinfo->max_pixels && (unsigned long long)width * height > sinfo->max_pixels) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); -#endif + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels); /* we ignore the color resolution, sort flag, and background color index */ aspectRatio = UCH(hdrbuf[6]); if (aspectRatio != 0 && aspectRatio != 49) @@ -467,11 +465,9 @@ start_input_gif(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) height = LM_to_uint(hdrbuf, 6); if (width == 0 || height == 0) ERREXIT(cinfo, JERR_GIF_EMPTY); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sinfo->max_pixels && (unsigned long long)width * height > sinfo->max_pixels) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); -#endif + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels); source->is_interlaced = (BitSet(hdrbuf[8], INTERLACE) != 0); /* Read local colormap if header indicates it is present */ @@ -715,9 +711,7 @@ _jinit_read_gif(j_compress_ptr cinfo) /* Fill in method ptrs, except get_pixel_rows which start_input sets */ source->pub.start_input = start_input_gif; source->pub.finish_input = finish_input_gif; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION source->pub.max_pixels = 0; -#endif return (cjpeg_source_ptr)source; } diff --git a/rdppm.c b/rdppm.c index 5705806..8a9afdf 100644 --- a/rdppm.c +++ b/rdppm.c @@ -5,7 +5,7 @@ * Copyright (C) 1991-1997, Thomas G. Lane. * Modified 2009 by Bill Allombert, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2015-2017, 2020-2023, D. R. Commander. + * Copyright (C) 2015-2017, 2020-2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -689,10 +689,8 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sinfo->max_pixels && (unsigned long long)w * h > sinfo->max_pixels) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); -#endif + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels); cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ cinfo->image_width = (JDIMENSION)w; @@ -709,7 +707,7 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) if (cinfo->in_color_space == JCS_UNKNOWN || cinfo->in_color_space == JCS_RGB) cinfo->in_color_space = JCS_GRAYSCALE; - TRACEMS2(cinfo, 1, JTRC_PGM_TEXT, w, h); + TRACEMS3(cinfo, 1, JTRC_PGM_TEXT, w, h, maxval); if (cinfo->in_color_space == JCS_GRAYSCALE) source->pub.get_pixel_rows = get_text_gray_row; else if (IsExtRGB(cinfo->in_color_space)) @@ -724,7 +722,7 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) case '3': /* it's a text-format PPM file */ if (cinfo->in_color_space == JCS_UNKNOWN) cinfo->in_color_space = JCS_EXT_RGB; - TRACEMS2(cinfo, 1, JTRC_PPM_TEXT, w, h); + TRACEMS3(cinfo, 1, JTRC_PPM_TEXT, w, h, maxval); if (IsExtRGB(cinfo->in_color_space)) source->pub.get_pixel_rows = get_text_rgb_row; else if (cinfo->in_color_space == JCS_CMYK) @@ -738,7 +736,7 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) if (cinfo->in_color_space == JCS_UNKNOWN || cinfo->in_color_space == JCS_RGB) cinfo->in_color_space = JCS_GRAYSCALE; - TRACEMS2(cinfo, 1, JTRC_PGM, w, h); + TRACEMS3(cinfo, 1, JTRC_PGM, w, h, maxval); if (maxval > 255) { if (cinfo->in_color_space == JCS_GRAYSCALE) source->pub.get_pixel_rows = get_word_gray_row; @@ -768,7 +766,7 @@ start_input_ppm(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) case '6': /* it's a raw-format PPM file */ if (cinfo->in_color_space == JCS_UNKNOWN) cinfo->in_color_space = JCS_EXT_RGB; - TRACEMS2(cinfo, 1, JTRC_PPM, w, h); + TRACEMS3(cinfo, 1, JTRC_PPM, w, h, maxval); if (maxval > 255) { if (IsExtRGB(cinfo->in_color_space)) source->pub.get_pixel_rows = get_word_rgb_row; @@ -883,9 +881,7 @@ _jinit_read_ppm(j_compress_ptr cinfo) /* Fill in method ptrs, except get_pixel_rows which start_input sets */ source->pub.start_input = start_input_ppm; source->pub.finish_input = finish_input_ppm; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION source->pub.max_pixels = 0; -#endif return (cjpeg_source_ptr)source; } diff --git a/rdtarga.c b/rdtarga.c index dae0b58..b78a165 100644 --- a/rdtarga.c +++ b/rdtarga.c @@ -5,7 +5,7 @@ * Copyright (C) 1991-1996, Thomas G. Lane. * Modified 2017 by Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2018, 2021-2022, D. R. Commander. + * Copyright (C) 2018, 2021-2023, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -363,11 +363,9 @@ start_input_tga(j_compress_ptr cinfo, cjpeg_source_ptr sinfo) interlace_type != 0 || /* currently don't allow interlaced image */ width == 0 || height == 0) /* image width/height must be non-zero */ ERREXIT(cinfo, JERR_TGA_BADPARMS); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION if (sinfo->max_pixels && (unsigned long long)width * height > sinfo->max_pixels) - ERREXIT(cinfo, JERR_WIDTH_OVERFLOW); -#endif + ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, sinfo->max_pixels); if (subtype > 8) { /* It's an RLE-coded file */ @@ -501,9 +499,7 @@ jinit_read_targa(j_compress_ptr cinfo) /* Fill in method ptrs, except get_pixel_rows which start_input sets */ source->pub.start_input = start_input_tga; source->pub.finish_input = finish_input_tga; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION source->pub.max_pixels = 0; -#endif return (cjpeg_source_ptr)source; } diff --git a/release/rpm.spec.in b/release/rpm.spec.in index 24872db..7db85c2 100644 --- a/release/rpm.spec.in +++ b/release/rpm.spec.in @@ -45,7 +45,7 @@ Version: @VERSION@ Vendor: @PKGVENDOR@ URL: @PKGURL@ Group: System Environment/Libraries -#-->Source0: http://prdownloads.sourceforge.net/@CMAKE_PROJECT_NAME@/@CMAKE_PROJECT_NAME@-%{version}.tar.gz +#-->Source0: https://github.com/libjpeg-turbo/libjpeg-turbo/releases/download/%{version}/libjpeg-turbo-%{version}.tar.gz Release: @BUILD@ License: BSD-style BuildRoot: %{_blddir}/%{name}-buildroot-%{version}-%{release} diff --git a/sharedlib/CMakeLists.txt b/sharedlib/CMakeLists.txt index 8e94256..eaed9e9 100644 --- a/sharedlib/CMakeLists.txt +++ b/sharedlib/CMakeLists.txt @@ -11,12 +11,24 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/..) if(MSVC) # Build all configurations against shared C library - foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE - CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) - if(${var} MATCHES "/MT") - string(REGEX REPLACE "/MT" "/MD" ${var} "${${var}}") + if(CMAKE_VERSION VERSION_EQUAL "3.15" OR + CMAKE_VERSION VERSION_GREATER "3.15") + if(CMAKE_BUILD_TYPE_UC STREQUAL "DEBUG") + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDebugDLL) + elseif(MSVC_IDE) + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") + else() + set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) endif() - endforeach() + message(STATUS "Visual C++ run-time library for libjpeg API DLL: ${CMAKE_MSVC_RUNTIME_LIBRARY}") + else() + foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE + CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO) + if(${var} MATCHES "/MT") + string(REGEX REPLACE "/MT" "/MD" ${var} "${${var}}") + endif() + endforeach() + endif() endif() foreach(src ${JPEG_SOURCES}) @@ -108,13 +120,13 @@ target_link_libraries(jcstest jpeg) install(TARGETS jpeg EXPORT ${CMAKE_PROJECT_NAME}Targets INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT lib + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin) install(TARGETS cjpeg djpeg jpegtran - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin) if(NOT CMAKE_VERSION VERSION_LESS "3.1" AND MSVC AND CMAKE_C_LINKER_SUPPORTS_PDB) install(FILES "$" - DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) + DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT bin OPTIONAL) endif() diff --git a/simd/CMakeLists.txt b/simd/CMakeLists.txt index 6024900..9c063d5 100644 --- a/simd/CMakeLists.txt +++ b/simd/CMakeLists.txt @@ -96,6 +96,18 @@ if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)) set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DPIC") endif() +if(CPU_TYPE STREQUAL "x86_64" AND CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "^elf") + check_c_source_compiles(" + #if (__CET__ & 3) == 0 + #error \"CET not enabled\" + #endif + int main(void) { return 0; }" HAVE_CET) + + if(HAVE_CET) + set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -D__CET__") + endif() +endif() + string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) set(EFFECTIVE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} ${CMAKE_ASM_NASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}") message(STATUS "CMAKE_ASM_NASM_FLAGS = ${EFFECTIVE_ASM_NASM_FLAGS}") @@ -354,7 +366,8 @@ if(NOT NEON_INTRINSICS) separate_arguments(CMAKE_ASM_FLAGS_SEP UNIX_COMMAND "${CMAKE_ASM_FLAGS}") execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS_SEP} -x assembler-with-cpp -c ${CMAKE_CURRENT_BINARY_DIR}/gastest.S - RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR) + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} RESULT_VARIABLE RESULT + OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR) if(NOT RESULT EQUAL 0) message(WARNING "GAS appears to be broken. Using the full Neon SIMD intrinsics implementation.") set(NEON_INTRINSICS 1 CACHE INTERNAL "" FORCE) diff --git a/simd/i386/jccolext-avx2.asm b/simd/i386/jccolext-avx2.asm index c46d684..28ac952 100644 --- a/simd/i386/jccolext-avx2.asm +++ b/simd/i386/jccolext-avx2.asm @@ -2,17 +2,13 @@ ; jccolext.asm - colorspace conversion (AVX2) ; ; Copyright (C) 2015, Intel Corporation. -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_rgb_ycc_convert_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] test ecx, ecx @@ -80,9 +76,9 @@ EXTN(jsimd_rgb_ycc_convert_avx2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edx push ebx push edi @@ -93,11 +89,11 @@ EXTN(jsimd_rgb_ycc_convert_avx2): mov edi, JSAMPROW [edi] ; outptr0 mov ebx, JSAMPROW [ebx] ; outptr1 mov edx, JSAMPROW [edx] ; outptr2 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_YMMWORD jae near .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -154,7 +150,7 @@ EXTN(jsimd_rgb_ycc_convert_avx2): vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] @@ -278,7 +274,7 @@ EXTN(jsimd_rgb_ycc_convert_avx2): vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] @@ -552,7 +548,7 @@ EXTN(jsimd_rgb_ycc_convert_avx2): pop edi pop ebx pop edx - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jccolext-mmx.asm b/simd/i386/jccolext-mmx.asm index 6357a42..44b6251 100644 --- a/simd/i386/jccolext-mmx.asm +++ b/simd/i386/jccolext-mmx.asm @@ -2,17 +2,13 @@ ; jccolext.asm - colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_rgb_ycc_convert_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] ; num_cols test ecx, ecx @@ -80,9 +76,9 @@ EXTN(jsimd_rgb_ycc_convert_mmx): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edx push ebx push edi @@ -93,11 +89,11 @@ EXTN(jsimd_rgb_ycc_convert_mmx): mov edi, JSAMPROW [edi] ; outptr0 mov ebx, JSAMPROW [ebx] ; outptr1 mov edx, JSAMPROW [edx] ; outptr2 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_MMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -143,7 +139,7 @@ EXTN(jsimd_rgb_ycc_convert_mmx): movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] movq mmG, MMWORD [esi+1*SIZEOF_MMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] @@ -211,7 +207,7 @@ EXTN(jsimd_rgb_ycc_convert_mmx): movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] movq mmF, MMWORD [esi+1*SIZEOF_MMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] @@ -449,7 +445,7 @@ EXTN(jsimd_rgb_ycc_convert_mmx): pop edi pop ebx pop edx - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jccolext-sse2.asm b/simd/i386/jccolext-sse2.asm index c6c8085..1d8d5f5 100644 --- a/simd/i386/jccolext-sse2.asm +++ b/simd/i386/jccolext-sse2.asm @@ -1,17 +1,13 @@ ; ; jccolext.asm - colorspace conversion (SSE2) ; -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -48,15 +44,15 @@ EXTN(jsimd_rgb_ycc_convert_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] test ecx, ecx @@ -79,9 +75,9 @@ EXTN(jsimd_rgb_ycc_convert_sse2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edx push ebx push edi @@ -92,11 +88,11 @@ EXTN(jsimd_rgb_ycc_convert_sse2): mov edi, JSAMPROW [edi] ; outptr0 mov ebx, JSAMPROW [ebx] ; outptr1 mov edx, JSAMPROW [edx] ; outptr2 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_XMMWORD jae near .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -147,7 +143,7 @@ EXTN(jsimd_rgb_ycc_convert_sse2): movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] movdqu xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -232,7 +228,7 @@ EXTN(jsimd_rgb_ycc_convert_sse2): movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] movdqu xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD] jmp short .rgb_ycc_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -478,7 +474,7 @@ EXTN(jsimd_rgb_ycc_convert_sse2): pop edi pop ebx pop edx - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jccolor-avx2.asm b/simd/i386/jccolor-avx2.asm index 14944e9..9ad5ea9 100644 --- a/simd/i386/jccolor-avx2.asm +++ b/simd/i386/jccolor-avx2.asm @@ -1,18 +1,14 @@ ; ; jccolor.asm - colorspace conversion (AVX2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -33,7 +29,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_ycc_convert_avx2) EXTN(jconst_rgb_ycc_convert_avx2): @@ -46,7 +42,7 @@ PD_ONEHALFM1_CJ times 8 dd (1 << (SCALEBITS - 1)) - 1 + \ (CENTERJSAMPLE << SCALEBITS) PD_ONEHALF times 8 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jccolor-mmx.asm b/simd/i386/jccolor-mmx.asm index 8cb399b..0dbec54 100644 --- a/simd/i386/jccolor-mmx.asm +++ b/simd/i386/jccolor-mmx.asm @@ -2,17 +2,13 @@ ; jccolor.asm - colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -33,7 +29,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_ycc_convert_mmx) EXTN(jconst_rgb_ycc_convert_mmx): @@ -46,7 +42,7 @@ PD_ONEHALFM1_CJ times 2 dd (1 << (SCALEBITS - 1)) - 1 + \ (CENTERJSAMPLE << SCALEBITS) PD_ONEHALF times 2 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jccolor-sse2.asm b/simd/i386/jccolor-sse2.asm index 686d222..678306a 100644 --- a/simd/i386/jccolor-sse2.asm +++ b/simd/i386/jccolor-sse2.asm @@ -1,17 +1,13 @@ ; ; jccolor.asm - colorspace conversion (SSE2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_ycc_convert_sse2) EXTN(jconst_rgb_ycc_convert_sse2): @@ -45,7 +41,7 @@ PD_ONEHALFM1_CJ times 4 dd (1 << (SCALEBITS - 1)) - 1 + \ (CENTERJSAMPLE << SCALEBITS) PD_ONEHALF times 4 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jcgray-avx2.asm b/simd/i386/jcgray-avx2.asm index 560ee0c..ded3956 100644 --- a/simd/i386/jcgray-avx2.asm +++ b/simd/i386/jcgray-avx2.asm @@ -1,18 +1,14 @@ ; ; jcgray.asm - grayscale colorspace conversion (AVX2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -29,7 +25,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_gray_convert_avx2) EXTN(jconst_rgb_gray_convert_avx2): @@ -38,7 +34,7 @@ PW_F0299_F0337 times 8 dw F_0_299, F_0_337 PW_F0114_F0250 times 8 dw F_0_114, F_0_250 PD_ONEHALF times 8 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jcgray-mmx.asm b/simd/i386/jcgray-mmx.asm index 79fdf08..d6f0318 100644 --- a/simd/i386/jcgray-mmx.asm +++ b/simd/i386/jcgray-mmx.asm @@ -2,17 +2,13 @@ ; jcgray.asm - grayscale colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -29,7 +25,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_gray_convert_mmx) EXTN(jconst_rgb_gray_convert_mmx): @@ -38,7 +34,7 @@ PW_F0299_F0337 times 2 dw F_0_299, F_0_337 PW_F0114_F0250 times 2 dw F_0_114, F_0_250 PD_ONEHALF times 2 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jcgray-sse2.asm b/simd/i386/jcgray-sse2.asm index cb4b28e..ecc7fa0 100644 --- a/simd/i386/jcgray-sse2.asm +++ b/simd/i386/jcgray-sse2.asm @@ -1,17 +1,13 @@ ; ; jcgray.asm - grayscale colorspace conversion (SSE2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -28,7 +24,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_gray_convert_sse2) EXTN(jconst_rgb_gray_convert_sse2): @@ -37,7 +33,7 @@ PW_F0299_F0337 times 4 dw F_0_299, F_0_337 PW_F0114_F0250 times 4 dw F_0_114, F_0_250 PD_ONEHALF times 4 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jcgryext-avx2.asm b/simd/i386/jcgryext-avx2.asm index 3fa7973..70df8f8 100644 --- a/simd/i386/jcgryext-avx2.asm +++ b/simd/i386/jcgryext-avx2.asm @@ -1,18 +1,14 @@ ; ; jcgryext.asm - grayscale colorspace conversion (AVX2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_rgb_gray_convert_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] test ecx, ecx @@ -76,20 +72,20 @@ EXTN(jsimd_rgb_gray_convert_avx2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edi push esi push ecx ; col mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr0 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_YMMWORD jae near .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -146,7 +142,7 @@ EXTN(jsimd_rgb_gray_convert_avx2): vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] @@ -270,7 +266,7 @@ EXTN(jsimd_rgb_gray_convert_avx2): vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] vmovdqu ymmF, YMMWORD [esi+1*SIZEOF_YMMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymmA, YMMWORD [esi+0*SIZEOF_YMMWORD] @@ -433,7 +429,7 @@ EXTN(jsimd_rgb_gray_convert_avx2): pop ecx ; col pop esi pop edi - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jcgryext-mmx.asm b/simd/i386/jcgryext-mmx.asm index 8af42e5..dd90c3d 100644 --- a/simd/i386/jcgryext-mmx.asm +++ b/simd/i386/jcgryext-mmx.asm @@ -2,17 +2,13 @@ ; jcgryext.asm - grayscale colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_rgb_gray_convert_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] ; num_cols test ecx, ecx @@ -76,20 +72,20 @@ EXTN(jsimd_rgb_gray_convert_mmx): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edi push esi push ecx ; col mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr0 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_MMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -135,7 +131,7 @@ EXTN(jsimd_rgb_gray_convert_mmx): movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] movq mmG, MMWORD [esi+1*SIZEOF_MMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] @@ -203,7 +199,7 @@ EXTN(jsimd_rgb_gray_convert_mmx): movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] movq mmF, MMWORD [esi+1*SIZEOF_MMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mmA, MMWORD [esi+0*SIZEOF_MMWORD] @@ -330,7 +326,7 @@ EXTN(jsimd_rgb_gray_convert_mmx): pop ecx ; col pop esi pop edi - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jcgryext-sse2.asm b/simd/i386/jcgryext-sse2.asm index c9d6ff1..227295f 100644 --- a/simd/i386/jcgryext-sse2.asm +++ b/simd/i386/jcgryext-sse2.asm @@ -1,17 +1,13 @@ ; ; jcgryext.asm - grayscale colorspace conversion (SSE2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -48,15 +44,15 @@ EXTN(jsimd_rgb_gray_convert_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [img_width(eax)] test ecx, ecx @@ -75,20 +71,20 @@ EXTN(jsimd_rgb_gray_convert_sse2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: - pushpic eax + PUSHPIC eax push edi push esi push ecx ; col mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr0 - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) cmp ecx, byte SIZEOF_XMMWORD jae near .columnloop - alignx 16, 7 + ALIGNX 16, 7 %if RGB_PIXELSIZE == 3 ; --------------- @@ -139,7 +135,7 @@ EXTN(jsimd_rgb_gray_convert_sse2): movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] movdqu xmmF, XMMWORD [esi+1*SIZEOF_XMMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -224,7 +220,7 @@ EXTN(jsimd_rgb_gray_convert_sse2): movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] movdqu xmmE, XMMWORD [esi+1*SIZEOF_XMMWORD] jmp short .rgb_gray_cnv - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqu xmmA, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -359,7 +355,7 @@ EXTN(jsimd_rgb_gray_convert_sse2): pop ecx ; col pop esi pop edi - poppic eax + POPPIC eax add esi, byte SIZEOF_JSAMPROW ; input_buf add edi, byte SIZEOF_JSAMPROW diff --git a/simd/i386/jchuff-sse2.asm b/simd/i386/jchuff-sse2.asm index 278cf5e..ed194dd 100644 --- a/simd/i386/jchuff-sse2.asm +++ b/simd/i386/jchuff-sse2.asm @@ -1,7 +1,7 @@ ; ; jchuff-sse2.asm - Huffman entropy encoding (SSE2) ; -; Copyright (C) 2009-2011, 2014-2017, 2019, D. R. Commander. +; Copyright (C) 2009-2011, 2014-2017, 2019, 2024, D. R. Commander. ; Copyright (C) 2015, Matthieu Darbois. ; Copyright (C) 2018, Matthias Räncker. ; @@ -9,11 +9,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains an SSE2 implementation for Huffman coding of one block. ; The following code is based on jchuff.c; see jchuff.c for more details. @@ -42,7 +38,7 @@ endstruc EXTN(jconst_huff_encode_one_block): - alignz 32 + ALIGNZ 32 jpeg_mask_bits dq 0x0000, 0x0001, 0x0003, 0x0007 dq 0x000f, 0x001f, 0x003f, 0x007f @@ -65,7 +61,8 @@ times 1 << 2 db 3 times 1 << 1 db 2 times 1 << 0 db 1 times 1 db 0 -jpeg_nbits_table: +GLOBAL_DATA(jpeg_nbits_table) +EXTN(jpeg_nbits_table): times 1 db 0 times 1 << 0 db 1 times 1 << 1 db 2 @@ -83,14 +80,14 @@ times 1 << 12 db 13 times 1 << 13 db 14 times 1 << 14 db 15 - alignz 32 + ALIGNZ 32 %ifdef PIC %define NBITS(x) nbits_base + x %else -%define NBITS(x) jpeg_nbits_table + x +%define NBITS(x) EXTN(jpeg_nbits_table) + x %endif -%define MASK_BITS(x) NBITS((x) * 8) + (jpeg_mask_bits - jpeg_nbits_table) +%define MASK_BITS(x) NBITS((x) * 8) + (jpeg_mask_bits - EXTN(jpeg_nbits_table)) ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -235,7 +232,7 @@ times 1 << 14 db 15 ; If PIC is defined, load the address of a symbol defined in this file into a ; register. Equivalent to -; get_GOT %1 +; GET_GOT %1 ; lea %1, [GOTOFF(%1, %2)] ; without using the GOT. ; @@ -469,7 +466,7 @@ EXTN(jsimd_huff_encode_one_block_sse2): pcmpeqw mm_all_0xff, mm_all_0xff ;Z: all_0xff[i] = 0xFF; %endmacro - GET_SYM nbits_base, jpeg_nbits_table, GET_SYM_BEFORE, GET_SYM_AFTER + GET_SYM nbits_base, EXTN(jpeg_nbits_table), GET_SYM_BEFORE, GET_SYM_AFTER psrldq xmm4, 1 * SIZEOF_WORD ;G: w4 = 37 44 45 38 39 46 47 -- shufpd xmm1, xmm5, 10b ;F: w1 = 36 37 44 45 50 51 58 59 diff --git a/simd/i386/jcphuff-sse2.asm b/simd/i386/jcphuff-sse2.asm index c26b48a..19a183f 100644 --- a/simd/i386/jcphuff-sse2.asm +++ b/simd/i386/jcphuff-sse2.asm @@ -7,11 +7,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains an SSE2 implementation of data preparation for progressive ; Huffman encoding. See jcphuff.c for more details. diff --git a/simd/i386/jcsample-avx2.asm b/simd/i386/jcsample-avx2.asm index 0a20802..5019829 100644 --- a/simd/i386/jcsample-avx2.asm +++ b/simd/i386/jcsample-avx2.asm @@ -3,17 +3,13 @@ ; ; Copyright 2009 Pierre Ossman for Cendio AB ; Copyright (C) 2015, Intel Corporation. -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -70,7 +66,7 @@ EXTN(jsimd_h2v1_downsample_avx2): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -106,7 +102,7 @@ EXTN(jsimd_h2v1_downsample_avx2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -117,7 +113,7 @@ EXTN(jsimd_h2v1_downsample_avx2): cmp ecx, byte SIZEOF_YMMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_r24: ; ecx can possibly be 8, 16, 24 @@ -141,7 +137,7 @@ EXTN(jsimd_h2v1_downsample_avx2): vpxor ymm1, ymm1, ymm1 mov ecx, SIZEOF_YMMWORD jmp short .downsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymm0, YMMWORD [esi+0*SIZEOF_YMMWORD] @@ -243,7 +239,7 @@ EXTN(jsimd_h2v2_downsample_avx2): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -279,7 +275,7 @@ EXTN(jsimd_h2v2_downsample_avx2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -291,7 +287,7 @@ EXTN(jsimd_h2v2_downsample_avx2): cmp ecx, byte SIZEOF_YMMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_r24: cmp ecx, 24 @@ -320,7 +316,7 @@ EXTN(jsimd_h2v2_downsample_avx2): vpxor ymm3, ymm3, ymm3 mov ecx, SIZEOF_YMMWORD jmp short .downsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymm0, YMMWORD [edx+0*SIZEOF_YMMWORD] diff --git a/simd/i386/jcsample-mmx.asm b/simd/i386/jcsample-mmx.asm index 2c223ee..94dd888 100644 --- a/simd/i386/jcsample-mmx.asm +++ b/simd/i386/jcsample-mmx.asm @@ -2,17 +2,13 @@ ; jcsample.asm - downsampling (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -69,7 +65,7 @@ EXTN(jsimd_h2v1_downsample_mmx): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -104,7 +100,7 @@ EXTN(jsimd_h2v1_downsample_mmx): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -112,7 +108,7 @@ EXTN(jsimd_h2v1_downsample_mmx): mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [esi+0*SIZEOF_MMWORD] @@ -212,7 +208,7 @@ EXTN(jsimd_h2v2_downsample_mmx): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -247,7 +243,7 @@ EXTN(jsimd_h2v2_downsample_mmx): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -256,7 +252,7 @@ EXTN(jsimd_h2v2_downsample_mmx): mov edx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; inptr0 mov esi, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; inptr1 mov edi, JSAMPROW [edi] ; outptr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [edx+0*SIZEOF_MMWORD] diff --git a/simd/i386/jcsample-sse2.asm b/simd/i386/jcsample-sse2.asm index 4fea60d..eb8808b 100644 --- a/simd/i386/jcsample-sse2.asm +++ b/simd/i386/jcsample-sse2.asm @@ -2,17 +2,13 @@ ; jcsample.asm - downsampling (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -69,7 +65,7 @@ EXTN(jsimd_h2v1_downsample_sse2): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -104,7 +100,7 @@ EXTN(jsimd_h2v1_downsample_sse2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -115,14 +111,14 @@ EXTN(jsimd_h2v1_downsample_sse2): cmp ecx, byte SIZEOF_XMMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_r8: movdqa xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD] pxor xmm1, xmm1 mov ecx, SIZEOF_XMMWORD jmp short .downsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqa xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -225,7 +221,7 @@ EXTN(jsimd_h2v2_downsample_sse2): cld mov esi, JSAMPARRAY [input_data(ebp)] ; input_data - alignx 16, 7 + ALIGNX 16, 7 .expandloop: push eax push ecx @@ -260,7 +256,7 @@ EXTN(jsimd_h2v2_downsample_sse2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, JSAMPARRAY [output_data(ebp)] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push ecx push edi @@ -272,7 +268,7 @@ EXTN(jsimd_h2v2_downsample_sse2): cmp ecx, byte SIZEOF_XMMWORD jae short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_r8: movdqa xmm0, XMMWORD [edx+0*SIZEOF_XMMWORD] @@ -281,7 +277,7 @@ EXTN(jsimd_h2v2_downsample_sse2): pxor xmm3, xmm3 mov ecx, SIZEOF_XMMWORD jmp short .downsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqa xmm0, XMMWORD [edx+0*SIZEOF_XMMWORD] diff --git a/simd/i386/jdcolext-avx2.asm b/simd/i386/jdcolext-avx2.asm index 015be04..fd79b79 100644 --- a/simd/i386/jdcolext-avx2.asm +++ b/simd/i386/jdcolext-avx2.asm @@ -2,18 +2,14 @@ ; jdcolext.asm - colorspace conversion (AVX2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2012, 2016, D. R. Commander. +; Copyright (C) 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -50,15 +46,15 @@ EXTN(jsimd_ycc_rgb_convert_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [out_width(eax)] ; num_cols test ecx, ecx @@ -81,7 +77,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax push edi @@ -94,8 +90,8 @@ EXTN(jsimd_ycc_rgb_convert_avx2): mov ebx, JSAMPROW [ebx] ; inptr1 mov edx, JSAMPROW [edx] ; inptr2 mov edi, JSAMPROW [edi] ; outptr - movpic eax, POINTER [gotptr] ; load GOT address (eax) - alignx 16, 7 + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) + ALIGNX 16, 7 .columnloop: vmovdqu ymm5, YMMWORD [ebx] ; ymm5=Cb(0123456789ABCDEFGHIJKLMNOPQRSTUV) @@ -295,7 +291,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): add ebx, byte SIZEOF_YMMWORD ; inptr1 add edx, byte SIZEOF_YMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st64: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -436,7 +432,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): add ebx, byte SIZEOF_YMMWORD ; inptr1 add edx, byte SIZEOF_YMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st64: cmp ecx, byte SIZEOF_YMMWORD/2 @@ -479,7 +475,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): %endif ; RGB_PIXELSIZE ; --------------- - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop ecx diff --git a/simd/i386/jdcolext-mmx.asm b/simd/i386/jdcolext-mmx.asm index 5813cfc..636bd6d 100644 --- a/simd/i386/jdcolext-mmx.asm +++ b/simd/i386/jdcolext-mmx.asm @@ -2,17 +2,13 @@ ; jdcolext.asm - colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_ycc_rgb_convert_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [out_width(eax)] ; num_cols test ecx, ecx @@ -80,7 +76,7 @@ EXTN(jsimd_ycc_rgb_convert_mmx): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax push edi @@ -93,8 +89,8 @@ EXTN(jsimd_ycc_rgb_convert_mmx): mov ebx, JSAMPROW [ebx] ; inptr1 mov edx, JSAMPROW [edx] ; inptr2 mov edi, JSAMPROW [edi] ; outptr - movpic eax, POINTER [gotptr] ; load GOT address (eax) - alignx 16, 7 + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) + ALIGNX 16, 7 .columnloop: movq mm5, MMWORD [ebx] ; mm5=Cb(01234567) @@ -255,7 +251,7 @@ EXTN(jsimd_ycc_rgb_convert_mmx): add edx, byte SIZEOF_MMWORD ; inptr2 add edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD ; outptr jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st16: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -344,7 +340,7 @@ EXTN(jsimd_ycc_rgb_convert_mmx): add edx, byte SIZEOF_MMWORD ; inptr2 add edi, byte RGB_PIXELSIZE*SIZEOF_MMWORD ; outptr jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st16: cmp ecx, byte SIZEOF_MMWORD/2 @@ -369,7 +365,7 @@ EXTN(jsimd_ycc_rgb_convert_mmx): %endif ; RGB_PIXELSIZE ; --------------- - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop ecx diff --git a/simd/i386/jdcolext-sse2.asm b/simd/i386/jdcolext-sse2.asm index d5572b3..0150f2c 100644 --- a/simd/i386/jdcolext-sse2.asm +++ b/simd/i386/jdcolext-sse2.asm @@ -2,17 +2,13 @@ ; jdcolext.asm - colorspace conversion (SSE2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2012, 2016, D. R. Commander. +; Copyright (C) 2012, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_ycc_rgb_convert_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [out_width(eax)] ; num_cols test ecx, ecx @@ -80,7 +76,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): mov eax, INT [num_rows(eax)] test eax, eax jle near .return - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax push edi @@ -93,8 +89,8 @@ EXTN(jsimd_ycc_rgb_convert_sse2): mov ebx, JSAMPROW [ebx] ; inptr1 mov edx, JSAMPROW [edx] ; inptr2 mov edi, JSAMPROW [edi] ; outptr - movpic eax, POINTER [gotptr] ; load GOT address (eax) - alignx 16, 7 + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) + ALIGNX 16, 7 .columnloop: movdqa xmm5, XMMWORD [ebx] ; xmm5=Cb(0123456789ABCDEF) @@ -275,7 +271,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): add ebx, byte SIZEOF_XMMWORD ; inptr1 add edx, byte SIZEOF_XMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st32: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -387,7 +383,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): add ebx, byte SIZEOF_XMMWORD ; inptr1 add edx, byte SIZEOF_XMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st32: cmp ecx, byte SIZEOF_XMMWORD/2 @@ -423,7 +419,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): %endif ; RGB_PIXELSIZE ; --------------- - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop ecx diff --git a/simd/i386/jdcolor-avx2.asm b/simd/i386/jdcolor-avx2.asm index e05b60d..d3a30d6 100644 --- a/simd/i386/jdcolor-avx2.asm +++ b/simd/i386/jdcolor-avx2.asm @@ -3,17 +3,13 @@ ; ; Copyright 2009 Pierre Ossman for Cendio AB ; Copyright (C) 2015, Intel Corporation. -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_ycc_rgb_convert_avx2) EXTN(jconst_ycc_rgb_convert_avx2): @@ -43,7 +39,7 @@ PW_MF0344_F0285 times 8 dw -F_0_344, F_0_285 PW_ONE times 16 dw 1 PD_ONEHALF times 8 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdcolor-mmx.asm b/simd/i386/jdcolor-mmx.asm index fb7e7bc..6e67e4b 100644 --- a/simd/i386/jdcolor-mmx.asm +++ b/simd/i386/jdcolor-mmx.asm @@ -2,17 +2,13 @@ ; jdcolor.asm - colorspace conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_ycc_rgb_convert_mmx) EXTN(jconst_ycc_rgb_convert_mmx): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 2 dw -F_0_344, F_0_285 PW_ONE times 4 dw 1 PD_ONEHALF times 2 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdcolor-sse2.asm b/simd/i386/jdcolor-sse2.asm index b736255..79c9c68 100644 --- a/simd/i386/jdcolor-sse2.asm +++ b/simd/i386/jdcolor-sse2.asm @@ -2,17 +2,13 @@ ; jdcolor.asm - colorspace conversion (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_ycc_rgb_convert_sse2) EXTN(jconst_ycc_rgb_convert_sse2): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 4 dw -F_0_344, F_0_285 PW_ONE times 8 dw 1 PD_ONEHALF times 4 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdmerge-avx2.asm b/simd/i386/jdmerge-avx2.asm index 711e679..90493fd 100644 --- a/simd/i386/jdmerge-avx2.asm +++ b/simd/i386/jdmerge-avx2.asm @@ -2,18 +2,14 @@ ; jdmerge.asm - merged upsampling/color conversion (AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_merged_upsample_avx2) EXTN(jconst_merged_upsample_avx2): @@ -43,7 +39,7 @@ PW_MF0344_F0285 times 8 dw -F_0_344, F_0_285 PW_ONE times 16 dw 1 PD_ONEHALF times 8 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdmerge-mmx.asm b/simd/i386/jdmerge-mmx.asm index 6e8311d..0dc204a 100644 --- a/simd/i386/jdmerge-mmx.asm +++ b/simd/i386/jdmerge-mmx.asm @@ -2,17 +2,13 @@ ; jdmerge.asm - merged upsampling/color conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_merged_upsample_mmx) EXTN(jconst_merged_upsample_mmx): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 2 dw -F_0_344, F_0_285 PW_ONE times 4 dw 1 PD_ONEHALF times 2 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdmerge-sse2.asm b/simd/i386/jdmerge-sse2.asm index e32f90a..06f0762 100644 --- a/simd/i386/jdmerge-sse2.asm +++ b/simd/i386/jdmerge-sse2.asm @@ -2,17 +2,13 @@ ; jdmerge.asm - merged upsampling/color conversion (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_merged_upsample_sse2) EXTN(jconst_merged_upsample_sse2): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 4 dw -F_0_344, F_0_285 PW_ONE times 8 dw 1 PD_ONEHALF times 4 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/i386/jdmrgext-avx2.asm b/simd/i386/jdmrgext-avx2.asm index e35f728..a7aa930 100644 --- a/simd/i386/jdmrgext-avx2.asm +++ b/simd/i386/jdmrgext-avx2.asm @@ -2,18 +2,14 @@ ; jdmrgext.asm - merged upsampling/color conversion (AVX2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2012, 2016, D. R. Commander. +; Copyright (C) 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -50,15 +46,15 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [output_width(eax)] ; col test ecx, ecx @@ -79,9 +75,9 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): pop ecx ; col - alignx 16, 7 + ALIGNX 16, 7 .columnloop: - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) vmovdqu ymm6, YMMWORD [ebx] ; ymm6=Cb(0123456789ABCDEFGHIJKLMNOPQRSTUV) vmovdqu ymm7, YMMWORD [edx] ; ymm7=Cr(0123456789ABCDEFGHIJKLMNOPQRSTUV) @@ -168,13 +164,13 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): mov al, 2 ; Yctr jmp short .Yloop_1st - alignx 16, 7 + ALIGNX 16, 7 .Yloop_2nd: vmovdqa ymm0, YMMWORD [wk(1)] ; ymm0=(R-Y)H vmovdqa ymm2, YMMWORD [wk(2)] ; ymm2=(G-Y)H vmovdqa ymm4, YMMWORD [wk(0)] ; ymm4=(B-Y)H - alignx 16, 7 + ALIGNX 16, 7 .Yloop_1st: vmovdqu ymm7, YMMWORD [esi] ; ymm7=Y(0123456789ABCDEFGHIJKLMNOPQRSTUV) @@ -301,7 +297,7 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): add ebx, byte SIZEOF_YMMWORD ; inptr1 add edx, byte SIZEOF_YMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st64: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -445,7 +441,7 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): add ebx, byte SIZEOF_YMMWORD ; inptr1 add edx, byte SIZEOF_YMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st64: cmp ecx, byte SIZEOF_YMMWORD/2 diff --git a/simd/i386/jdmrgext-mmx.asm b/simd/i386/jdmrgext-mmx.asm index eb3e36b..5627581 100644 --- a/simd/i386/jdmrgext-mmx.asm +++ b/simd/i386/jdmrgext-mmx.asm @@ -2,17 +2,13 @@ ; jdmrgext.asm - merged upsampling/color conversion (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -47,15 +43,15 @@ EXTN(jsimd_h2v1_merged_upsample_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [output_width(eax)] ; col test ecx, ecx @@ -76,9 +72,9 @@ EXTN(jsimd_h2v1_merged_upsample_mmx): pop ecx ; col - alignx 16, 7 + ALIGNX 16, 7 .columnloop: - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) movq mm6, MMWORD [ebx] ; mm6=Cb(01234567) movq mm7, MMWORD [edx] ; mm7=Cr(01234567) @@ -171,13 +167,13 @@ EXTN(jsimd_h2v1_merged_upsample_mmx): mov al, 2 ; Yctr jmp short .Yloop_1st - alignx 16, 7 + ALIGNX 16, 7 .Yloop_2nd: movq mm0, MMWORD [wk(1)] ; mm0=(R-Y)H movq mm2, MMWORD [wk(2)] ; mm2=(G-Y)H movq mm4, MMWORD [wk(0)] ; mm4=(B-Y)H - alignx 16, 7 + ALIGNX 16, 7 .Yloop_1st: movq mm7, MMWORD [esi] ; mm7=Y(01234567) @@ -258,7 +254,7 @@ EXTN(jsimd_h2v1_merged_upsample_mmx): add ebx, byte SIZEOF_MMWORD ; inptr1 add edx, byte SIZEOF_MMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st16: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -350,7 +346,7 @@ EXTN(jsimd_h2v1_merged_upsample_mmx): add ebx, byte SIZEOF_MMWORD ; inptr1 add edx, byte SIZEOF_MMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st16: cmp ecx, byte SIZEOF_MMWORD/2 diff --git a/simd/i386/jdmrgext-sse2.asm b/simd/i386/jdmrgext-sse2.asm index c113dc4..13e7d98 100644 --- a/simd/i386/jdmrgext-sse2.asm +++ b/simd/i386/jdmrgext-sse2.asm @@ -2,17 +2,13 @@ ; jdmrgext.asm - merged upsampling/color conversion (SSE2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2012, 2016, D. R. Commander. +; Copyright (C) 2012, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -49,15 +45,15 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov ecx, JDIMENSION [output_width(eax)] ; col test ecx, ecx @@ -78,9 +74,9 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): pop ecx ; col - alignx 16, 7 + ALIGNX 16, 7 .columnloop: - movpic eax, POINTER [gotptr] ; load GOT address (eax) + MOVPIC eax, POINTER [gotptr] ; load GOT address (eax) movdqa xmm6, XMMWORD [ebx] ; xmm6=Cb(0123456789ABCDEF) movdqa xmm7, XMMWORD [edx] ; xmm7=Cr(0123456789ABCDEF) @@ -173,13 +169,13 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): mov al, 2 ; Yctr jmp short .Yloop_1st - alignx 16, 7 + ALIGNX 16, 7 .Yloop_2nd: movdqa xmm0, XMMWORD [wk(1)] ; xmm0=(R-Y)H movdqa xmm2, XMMWORD [wk(2)] ; xmm2=(G-Y)H movdqa xmm4, XMMWORD [wk(0)] ; xmm4=(B-Y)H - alignx 16, 7 + ALIGNX 16, 7 .Yloop_1st: movdqa xmm7, XMMWORD [esi] ; xmm7=Y(0123456789ABCDEF) @@ -280,7 +276,7 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): add ebx, byte SIZEOF_XMMWORD ; inptr1 add edx, byte SIZEOF_XMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st32: lea ecx, [ecx+ecx*2] ; imul ecx, RGB_PIXELSIZE @@ -395,7 +391,7 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): add ebx, byte SIZEOF_XMMWORD ; inptr1 add edx, byte SIZEOF_XMMWORD ; inptr2 jmp near .columnloop - alignx 16, 7 + ALIGNX 16, 7 .column_st32: cmp ecx, byte SIZEOF_XMMWORD/2 diff --git a/simd/i386/jdsample-avx2.asm b/simd/i386/jdsample-avx2.asm index a800c35..eba53ef 100644 --- a/simd/i386/jdsample-avx2.asm +++ b/simd/i386/jdsample-avx2.asm @@ -3,24 +3,20 @@ ; ; Copyright 2009 Pierre Ossman for Cendio AB ; Copyright (C) 2015, Intel Corporation. -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fancy_upsample_avx2) EXTN(jconst_fancy_upsample_avx2): @@ -31,7 +27,7 @@ PW_THREE times 16 dw 3 PW_SEVEN times 16 dw 7 PW_EIGHT times 16 dw 8 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -62,13 +58,13 @@ PW_EIGHT times 16 dw 8 EXTN(jsimd_h2v1_fancy_upsample_avx2): push ebp mov ebp, esp - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address mov eax, JDIMENSION [downsamp_width(ebp)] ; colctr test eax, eax @@ -81,7 +77,7 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push edi @@ -104,7 +100,7 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): and eax, byte -SIZEOF_YMMWORD cmp eax, byte SIZEOF_YMMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: vpcmpeqb xmm6, xmm6, xmm6 @@ -112,7 +108,7 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): vperm2i128 ymm6, ymm6, ymm6, 1 ; (---- ---- ... ---- ---- ff) MSB is ff vpand ymm6, ymm6, YMMWORD [esi+0*SIZEOF_YMMWORD] jmp short .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: vmovdqu ymm6, YMMWORD [esi+1*SIZEOF_YMMWORD] @@ -196,7 +192,7 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): pop esi ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx pop ebp ret @@ -234,15 +230,15 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov edx, eax ; edx = original ebp mov eax, JDIMENSION [downsamp_width(edx)] ; colctr @@ -256,7 +252,7 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): mov esi, JSAMPARRAY [input_data(edx)] ; input_data mov edi, POINTER [output_data_ptr(edx)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push ecx @@ -286,8 +282,8 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): vmovdqu ymm1, YMMWORD [ecx+0*SIZEOF_YMMWORD] ; ymm1=row[-1][0] vmovdqu ymm2, YMMWORD [esi+0*SIZEOF_YMMWORD] ; ymm2=row[+1][0] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address vpxor ymm3, ymm3, ymm3 ; ymm3=(all 0's) @@ -328,19 +324,19 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): vmovdqa YMMWORD [wk(0)], ymm1 vmovdqa YMMWORD [wk(1)], ymm2 - poppic ebx + POPPIC ebx add eax, byte SIZEOF_YMMWORD-1 and eax, byte -SIZEOF_YMMWORD cmp eax, byte SIZEOF_YMMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: ; -- process the last column block - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address vpcmpeqb xmm1, xmm1, xmm1 vpslldq xmm1, xmm1, (SIZEOF_XMMWORD-2) @@ -353,7 +349,7 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): vmovdqa YMMWORD [wk(3)], ymm2 ; ymm2=(-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 31) jmp near .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: ; -- process the next column block @@ -362,8 +358,8 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): vmovdqu ymm1, YMMWORD [ecx+1*SIZEOF_YMMWORD] ; ymm1=row[-1][1] vmovdqu ymm2, YMMWORD [esi+1*SIZEOF_YMMWORD] ; ymm2=row[+1][1] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address vpxor ymm3, ymm3, ymm3 ; ymm3=(all 0's) @@ -516,7 +512,7 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): vmovdqu YMMWORD [edi+0*SIZEOF_YMMWORD], ymm1 vmovdqu YMMWORD [edi+1*SIZEOF_YMMWORD], ymm0 - poppic ebx + POPPIC ebx sub eax, byte SIZEOF_YMMWORD add ecx, byte 1*SIZEOF_YMMWORD ; inptr1(above) @@ -590,7 +586,7 @@ EXTN(jsimd_h2v1_upsample_avx2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -598,7 +594,7 @@ EXTN(jsimd_h2v1_upsample_avx2): mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: cmp eax, byte SIZEOF_YMMWORD @@ -629,7 +625,7 @@ EXTN(jsimd_h2v1_upsample_avx2): add esi, byte SIZEOF_YMMWORD ; inptr add edi, byte 2*SIZEOF_YMMWORD ; outptr jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi @@ -689,7 +685,7 @@ EXTN(jsimd_h2v2_upsample_avx2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -698,7 +694,7 @@ EXTN(jsimd_h2v2_upsample_avx2): mov ebx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] ; outptr0 mov edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW] ; outptr1 mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: cmp eax, byte SIZEOF_YMMWORD @@ -734,7 +730,7 @@ EXTN(jsimd_h2v2_upsample_avx2): add ebx, 2*SIZEOF_YMMWORD ; outptr0 add edi, 2*SIZEOF_YMMWORD ; outptr1 jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi diff --git a/simd/i386/jdsample-mmx.asm b/simd/i386/jdsample-mmx.asm index 12c49f0..01d09e6 100644 --- a/simd/i386/jdsample-mmx.asm +++ b/simd/i386/jdsample-mmx.asm @@ -2,24 +2,20 @@ ; jdsample.asm - upsampling (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fancy_upsample_mmx) EXTN(jconst_fancy_upsample_mmx): @@ -30,7 +26,7 @@ PW_THREE times 4 dw 3 PW_SEVEN times 4 dw 7 PW_EIGHT times 4 dw 8 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -61,13 +57,13 @@ PW_EIGHT times 4 dw 8 EXTN(jsimd_h2v1_fancy_upsample_mmx): push ebp mov ebp, esp - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address mov eax, JDIMENSION [downsamp_width(ebp)] ; colctr test eax, eax @@ -80,7 +76,7 @@ EXTN(jsimd_h2v1_fancy_upsample_mmx): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push edi @@ -103,14 +99,14 @@ EXTN(jsimd_h2v1_fancy_upsample_mmx): and eax, byte -SIZEOF_MMWORD cmp eax, byte SIZEOF_MMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: pcmpeqb mm6, mm6 psllq mm6, (SIZEOF_MMWORD-1)*BYTE_BIT pand mm6, MMWORD [esi+0*SIZEOF_MMWORD] jmp short .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm6, MMWORD [esi+1*SIZEOF_MMWORD] @@ -187,7 +183,7 @@ EXTN(jsimd_h2v1_fancy_upsample_mmx): pop esi ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx pop ebp ret @@ -224,15 +220,15 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov edx, eax ; edx = original ebp mov eax, JDIMENSION [downsamp_width(edx)] ; colctr @@ -246,7 +242,7 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): mov esi, JSAMPARRAY [input_data(edx)] ; input_data mov edi, POINTER [output_data_ptr(edx)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push ecx @@ -276,8 +272,8 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): movq mm1, MMWORD [ecx+0*SIZEOF_MMWORD] ; mm1=row[-1][0] movq mm2, MMWORD [esi+0*SIZEOF_MMWORD] ; mm2=row[+1][0] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pxor mm3, mm3 ; mm3=(all 0's) movq mm4, mm0 @@ -312,19 +308,19 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): movq MMWORD [wk(0)], mm1 movq MMWORD [wk(1)], mm2 - poppic ebx + POPPIC ebx add eax, byte SIZEOF_MMWORD-1 and eax, byte -SIZEOF_MMWORD cmp eax, byte SIZEOF_MMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: ; -- process the last column block - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pcmpeqb mm1, mm1 psllq mm1, (SIZEOF_MMWORD-2)*BYTE_BIT @@ -337,7 +333,7 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): movq MMWORD [wk(3)], mm2 jmp short .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: ; -- process the next column block @@ -346,8 +342,8 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): movq mm1, MMWORD [ecx+1*SIZEOF_MMWORD] ; mm1=row[-1][1] movq mm2, MMWORD [esi+1*SIZEOF_MMWORD] ; mm2=row[+1][1] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pxor mm3, mm3 ; mm3=(all 0's) movq mm4, mm0 @@ -486,7 +482,7 @@ EXTN(jsimd_h2v2_fancy_upsample_mmx): movq MMWORD [edi+0*SIZEOF_MMWORD], mm1 movq MMWORD [edi+1*SIZEOF_MMWORD], mm0 - poppic ebx + POPPIC ebx sub eax, byte SIZEOF_MMWORD add ecx, byte 1*SIZEOF_MMWORD ; inptr1(above) @@ -561,7 +557,7 @@ EXTN(jsimd_h2v1_upsample_mmx): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -569,7 +565,7 @@ EXTN(jsimd_h2v1_upsample_mmx): mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [esi+0*SIZEOF_MMWORD] @@ -599,7 +595,7 @@ EXTN(jsimd_h2v1_upsample_mmx): add esi, byte 2*SIZEOF_MMWORD ; inptr add edi, byte 4*SIZEOF_MMWORD ; outptr jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi @@ -660,7 +656,7 @@ EXTN(jsimd_h2v2_upsample_mmx): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -669,7 +665,7 @@ EXTN(jsimd_h2v2_upsample_mmx): mov ebx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] ; outptr0 mov edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW] ; outptr1 mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [esi+0*SIZEOF_MMWORD] @@ -704,7 +700,7 @@ EXTN(jsimd_h2v2_upsample_mmx): add ebx, byte 4*SIZEOF_MMWORD ; outptr0 add edi, byte 4*SIZEOF_MMWORD ; outptr1 jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi diff --git a/simd/i386/jdsample-sse2.asm b/simd/i386/jdsample-sse2.asm index 4e28d2f..b10d922 100644 --- a/simd/i386/jdsample-sse2.asm +++ b/simd/i386/jdsample-sse2.asm @@ -2,24 +2,20 @@ ; jdsample.asm - upsampling (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fancy_upsample_sse2) EXTN(jconst_fancy_upsample_sse2): @@ -30,7 +26,7 @@ PW_THREE times 8 dw 3 PW_SEVEN times 8 dw 7 PW_EIGHT times 8 dw 8 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -61,13 +57,13 @@ PW_EIGHT times 8 dw 8 EXTN(jsimd_h2v1_fancy_upsample_sse2): push ebp mov ebp, esp - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address mov eax, JDIMENSION [downsamp_width(ebp)] ; colctr test eax, eax @@ -80,7 +76,7 @@ EXTN(jsimd_h2v1_fancy_upsample_sse2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push edi @@ -103,14 +99,14 @@ EXTN(jsimd_h2v1_fancy_upsample_sse2): and eax, byte -SIZEOF_XMMWORD cmp eax, byte SIZEOF_XMMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: pcmpeqb xmm6, xmm6 pslldq xmm6, (SIZEOF_XMMWORD-1) pand xmm6, XMMWORD [esi+0*SIZEOF_XMMWORD] jmp short .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqa xmm6, XMMWORD [esi+1*SIZEOF_XMMWORD] @@ -185,7 +181,7 @@ EXTN(jsimd_h2v1_fancy_upsample_sse2): pop esi ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx pop ebp ret @@ -223,15 +219,15 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic eax ; make a room for GOT address + PUSHPIC eax ; make a room for GOT address push ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address - movpic POINTER [gotptr], ebx ; save GOT address + GET_GOT ebx ; get GOT address + MOVPIC POINTER [gotptr], ebx ; save GOT address mov edx, eax ; edx = original ebp mov eax, JDIMENSION [downsamp_width(edx)] ; colctr @@ -245,7 +241,7 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): mov esi, JSAMPARRAY [input_data(edx)] ; input_data mov edi, POINTER [output_data_ptr(edx)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push eax ; colctr push ecx @@ -275,8 +271,8 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): movdqa xmm1, XMMWORD [ecx+0*SIZEOF_XMMWORD] ; xmm1=row[-1][0] movdqa xmm2, XMMWORD [esi+0*SIZEOF_XMMWORD] ; xmm2=row[+1][0] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pxor xmm3, xmm3 ; xmm3=(all 0's) movdqa xmm4, xmm0 @@ -311,19 +307,19 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): movdqa XMMWORD [wk(0)], xmm1 movdqa XMMWORD [wk(1)], xmm2 - poppic ebx + POPPIC ebx add eax, byte SIZEOF_XMMWORD-1 and eax, byte -SIZEOF_XMMWORD cmp eax, byte SIZEOF_XMMWORD ja short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .columnloop_last: ; -- process the last column block - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pcmpeqb xmm1, xmm1 pslldq xmm1, (SIZEOF_XMMWORD-2) @@ -336,7 +332,7 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): movdqa XMMWORD [wk(3)], xmm2 ; xmm2=(-- -- -- -- -- -- -- 15) jmp near .upsample - alignx 16, 7 + ALIGNX 16, 7 .columnloop: ; -- process the next column block @@ -345,8 +341,8 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): movdqa xmm1, XMMWORD [ecx+1*SIZEOF_XMMWORD] ; xmm1=row[-1][1] movdqa xmm2, XMMWORD [esi+1*SIZEOF_XMMWORD] ; xmm2=row[+1][1] - pushpic ebx - movpic ebx, POINTER [gotptr] ; load GOT address + PUSHPIC ebx + MOVPIC ebx, POINTER [gotptr] ; load GOT address pxor xmm3, xmm3 ; xmm3=(all 0's) movdqa xmm4, xmm0 @@ -485,7 +481,7 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): movdqa XMMWORD [edi+0*SIZEOF_XMMWORD], xmm1 movdqa XMMWORD [edi+1*SIZEOF_XMMWORD], xmm0 - poppic ebx + POPPIC ebx sub eax, byte SIZEOF_XMMWORD add ecx, byte 1*SIZEOF_XMMWORD ; inptr1(above) @@ -558,7 +554,7 @@ EXTN(jsimd_h2v1_upsample_sse2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -566,7 +562,7 @@ EXTN(jsimd_h2v1_upsample_sse2): mov esi, JSAMPROW [esi] ; inptr mov edi, JSAMPROW [edi] ; outptr mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqa xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -596,7 +592,7 @@ EXTN(jsimd_h2v1_upsample_sse2): add esi, byte 2*SIZEOF_XMMWORD ; inptr add edi, byte 4*SIZEOF_XMMWORD ; outptr jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi @@ -655,7 +651,7 @@ EXTN(jsimd_h2v2_upsample_sse2): mov esi, JSAMPARRAY [input_data(ebp)] ; input_data mov edi, POINTER [output_data_ptr(ebp)] mov edi, JSAMPARRAY [edi] ; output_data - alignx 16, 7 + ALIGNX 16, 7 .rowloop: push edi push esi @@ -664,7 +660,7 @@ EXTN(jsimd_h2v2_upsample_sse2): mov ebx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] ; outptr0 mov edi, JSAMPROW [edi+1*SIZEOF_JSAMPROW] ; outptr1 mov eax, edx ; colctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movdqa xmm0, XMMWORD [esi+0*SIZEOF_XMMWORD] @@ -699,7 +695,7 @@ EXTN(jsimd_h2v2_upsample_sse2): add ebx, byte 4*SIZEOF_XMMWORD ; outptr0 add edi, byte 4*SIZEOF_XMMWORD ; outptr1 jmp short .columnloop - alignx 16, 7 + ALIGNX 16, 7 .nextrow: pop esi diff --git a/simd/i386/jfdctflt-3dn.asm b/simd/i386/jfdctflt-3dn.asm index 322ab16..0cedc6c 100644 --- a/simd/i386/jfdctflt-3dn.asm +++ b/simd/i386/jfdctflt-3dn.asm @@ -2,17 +2,13 @@ ; jfdctflt.asm - floating-point FDCT (3DNow!) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the forward DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -24,7 +20,7 @@ ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_float_3dnow) EXTN(jconst_fdct_float_3dnow): @@ -34,7 +30,7 @@ PD_0_707 times 2 dd 0.707106781186547524400844 PD_0_541 times 2 dd 0.541196100146196984399723 PD_1_306 times 2 dd 1.306562964876376527856643 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -63,19 +59,19 @@ EXTN(jsimd_fdct_float_3dnow): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. mov edx, POINTER [data(eax)] ; (FAST_FLOAT *) mov ecx, DCTSIZE/2 - alignx 16, 7 + ALIGNX 16, 7 .rowloop: movq mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)] @@ -190,7 +186,7 @@ EXTN(jsimd_fdct_float_3dnow): mov edx, POINTER [data(eax)] ; (FAST_FLOAT *) mov ecx, DCTSIZE/2 - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [MMBLOCK(0,0,edx,SIZEOF_FAST_FLOAT)] @@ -307,7 +303,7 @@ EXTN(jsimd_fdct_float_3dnow): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jfdctflt-sse.asm b/simd/i386/jfdctflt-sse.asm index 86952c6..2cb9533 100644 --- a/simd/i386/jfdctflt-sse.asm +++ b/simd/i386/jfdctflt-sse.asm @@ -2,17 +2,13 @@ ; jfdctflt.asm - floating-point FDCT (SSE) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the forward DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -34,7 +30,7 @@ ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_float_sse) EXTN(jconst_fdct_float_sse): @@ -44,7 +40,7 @@ PD_0_707 times 4 dd 0.707106781186547524400844 PD_0_541 times 4 dd 0.541196100146196984399723 PD_1_306 times 4 dd 1.306562964876376527856643 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -74,19 +70,19 @@ EXTN(jsimd_fdct_float_sse): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. mov edx, POINTER [data(eax)] ; (FAST_FLOAT *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .rowloop: movaps xmm0, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)] @@ -222,7 +218,7 @@ EXTN(jsimd_fdct_float_sse): mov edx, POINTER [data(eax)] ; (FAST_FLOAT *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movaps xmm0, XMMWORD [XMMBLOCK(2,0,edx,SIZEOF_FAST_FLOAT)] @@ -358,7 +354,7 @@ EXTN(jsimd_fdct_float_sse): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jfdctfst-mmx.asm b/simd/i386/jfdctfst-mmx.asm index 80645a5..fe16e83 100644 --- a/simd/i386/jfdctfst-mmx.asm +++ b/simd/i386/jfdctfst-mmx.asm @@ -2,17 +2,13 @@ ; jfdctfst.asm - fast integer FDCT (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the forward DCT (Discrete Cosine Transform). The following code is @@ -49,7 +45,7 @@ F_1_306 equ DESCALE(1402911301, 30 - CONST_BITS) ; FIX(1.306562965) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_ifast_mmx) EXTN(jconst_fdct_ifast_mmx): @@ -59,7 +55,7 @@ PW_F0382 times 4 dw F_0_382 << CONST_SHIFT PW_F0541 times 4 dw F_0_541 << CONST_SHIFT PW_F1306 times 4 dw F_1_306 << CONST_SHIFT - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -88,19 +84,19 @@ EXTN(jsimd_fdct_ifast_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. mov edx, POINTER [data(eax)] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .rowloop: movq mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)] @@ -241,7 +237,7 @@ EXTN(jsimd_fdct_ifast_mmx): mov edx, POINTER [data(eax)] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)] @@ -384,7 +380,7 @@ EXTN(jsimd_fdct_ifast_mmx): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jfdctfst-sse2.asm b/simd/i386/jfdctfst-sse2.asm index 446fa7a..890482e 100644 --- a/simd/i386/jfdctfst-sse2.asm +++ b/simd/i386/jfdctfst-sse2.asm @@ -2,17 +2,13 @@ ; jfdctfst.asm - fast integer FDCT (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the forward DCT (Discrete Cosine Transform). The following code is @@ -49,7 +45,7 @@ F_1_306 equ DESCALE(1402911301, 30 - CONST_BITS) ; FIX(1.306562965) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_ifast_sse2) EXTN(jconst_fdct_ifast_sse2): @@ -59,7 +55,7 @@ PW_F0382 times 8 dw F_0_382 << CONST_SHIFT PW_F0541 times 8 dw F_0_541 << CONST_SHIFT PW_F1306 times 8 dw F_1_306 << CONST_SHIFT - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -89,13 +85,13 @@ EXTN(jsimd_fdct_ifast_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. @@ -392,7 +388,7 @@ EXTN(jsimd_fdct_ifast_sse2): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jfdctint-avx2.asm b/simd/i386/jfdctint-avx2.asm index 23cf733..05ea865 100644 --- a/simd/i386/jfdctint-avx2.asm +++ b/simd/i386/jfdctint-avx2.asm @@ -2,17 +2,13 @@ ; jfdctint.asm - accurate integer FDCT (AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2018, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; forward DCT (Discrete Cosine Transform). The following code is based @@ -65,7 +61,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %1-%4: Input/output registers ; %5-%8: Temp registers -%macro dotranspose 8 +%macro DOTRANSPOSE 8 ; %1=(00 01 02 03 04 05 06 07 40 41 42 43 44 45 46 47) ; %2=(10 11 12 13 14 15 16 17 50 51 52 53 54 55 56 57) ; %3=(20 21 22 23 24 25 26 27 60 61 62 63 64 65 66 67) @@ -108,7 +104,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %5-%8: Temp registers ; %9: Pass (1 or 2) -%macro dodct 9 +%macro DODCT 9 vpsubw %5, %1, %4 ; %5=data1_0-data6_7=tmp6_7 vpaddw %6, %1, %4 ; %6=data1_0+data6_7=tmp1_0 vpaddw %7, %2, %3 ; %7=data3_2+data4_5=tmp3_2 @@ -223,7 +219,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_islow_avx2) EXTN(jconst_fdct_islow_avx2): @@ -242,7 +238,7 @@ PW_DESCALE_P2X times 16 dw 1 << (PASS1_BITS - 1) PW_1_NEG1 times 8 dw 1 times 8 dw -1 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -262,13 +258,13 @@ PW_1_NEG1 times 8 dw 1 EXTN(jsimd_fdct_islow_avx2): push ebp mov ebp, esp - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. @@ -292,9 +288,9 @@ EXTN(jsimd_fdct_islow_avx2): ; ymm2=(20 21 22 23 24 25 26 27 60 61 62 63 64 65 66 67) ; ymm3=(30 31 32 33 34 35 36 37 70 71 72 73 74 75 76 77) - dotranspose ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 - dodct ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, 1 + DODCT ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, 1 ; ymm0=data0_4, ymm1=data3_1, ymm2=data2_6, ymm3=data7_5 ; ---- Pass 2: process columns. @@ -302,9 +298,9 @@ EXTN(jsimd_fdct_islow_avx2): vperm2i128 ymm4, ymm1, ymm3, 0x20 ; ymm4=data3_7 vperm2i128 ymm1, ymm1, ymm3, 0x31 ; ymm1=data1_5 - dotranspose ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 - dodct ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, 2 + DODCT ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, 2 ; ymm0=data0_4, ymm1=data3_1, ymm2=data2_6, ymm4=data7_5 vperm2i128 ymm3, ymm0, ymm1, 0x30 ; ymm3=data0_1 @@ -322,7 +318,7 @@ EXTN(jsimd_fdct_islow_avx2): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx pop ebp ret diff --git a/simd/i386/jfdctint-mmx.asm b/simd/i386/jfdctint-mmx.asm index 34a43b9..7d4c61c 100644 --- a/simd/i386/jfdctint-mmx.asm +++ b/simd/i386/jfdctint-mmx.asm @@ -2,17 +2,13 @@ ; jfdctint.asm - accurate integer FDCT (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, 2020, D. R. Commander. +; Copyright (C) 2016, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; forward DCT (Discrete Cosine Transform). The following code is based @@ -63,7 +59,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_islow_mmx) EXTN(jconst_fdct_islow_mmx): @@ -80,7 +76,7 @@ PD_DESCALE_P1 times 2 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 2 dd 1 << (DESCALE_P2 - 1) PW_DESCALE_P2X times 4 dw 1 << (PASS1_BITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -109,19 +105,19 @@ EXTN(jsimd_fdct_islow_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. mov edx, POINTER [data(eax)] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .rowloop: movq mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)] @@ -363,7 +359,7 @@ EXTN(jsimd_fdct_islow_mmx): mov edx, POINTER [data(eax)] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .columnloop: movq mm0, MMWORD [MMBLOCK(2,0,edx,SIZEOF_DCTELEM)] @@ -609,7 +605,7 @@ EXTN(jsimd_fdct_islow_mmx): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jfdctint-sse2.asm b/simd/i386/jfdctint-sse2.asm index 6f8e18c..7ed5c95 100644 --- a/simd/i386/jfdctint-sse2.asm +++ b/simd/i386/jfdctint-sse2.asm @@ -2,17 +2,13 @@ ; jfdctint.asm - accurate integer FDCT (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, 2020, D. R. Commander. +; Copyright (C) 2016, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; forward DCT (Discrete Cosine Transform). The following code is based @@ -63,7 +59,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_islow_sse2) EXTN(jconst_fdct_islow_sse2): @@ -80,7 +76,7 @@ PD_DESCALE_P1 times 4 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 4 dd 1 << (DESCALE_P2 - 1) PW_DESCALE_P2X times 8 dw 1 << (PASS1_BITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -110,13 +106,13 @@ EXTN(jsimd_fdct_islow_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved ; push esi ; unused ; push edi ; unused - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process rows. @@ -622,7 +618,7 @@ EXTN(jsimd_fdct_islow_sse2): ; pop esi ; unused ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jidctflt-3dn.asm b/simd/i386/jidctflt-3dn.asm index 8795191..8612eee 100644 --- a/simd/i386/jidctflt-3dn.asm +++ b/simd/i386/jidctflt-3dn.asm @@ -2,17 +2,13 @@ ; jidctflt.asm - floating-point IDCT (3DNow! & MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the inverse DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -24,7 +20,7 @@ ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_float_3dnow) EXTN(jconst_idct_float_3dnow): @@ -36,7 +32,7 @@ PD_2_613 times 2 dd 2.613125929752753055713286 PD_RNDINT_MAGIC times 2 dd 100663296.0 ; (float)(0x00C00000 << 3) PB_CENTERJSAMP times 8 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -78,7 +74,7 @@ EXTN(jsimd_idct_float_3dnow): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -87,21 +83,21 @@ EXTN(jsimd_idct_float_3dnow): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; FAST_FLOAT *wsptr mov ecx, DCTSIZE/2 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_FLOAT_3DNOW mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] or eax, dword [DWBLOCK(2,0,esi,SIZEOF_JCOEF)] jnz short .columnDCT - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov ebx, dword [DWBLOCK(3,0,esi,SIZEOF_JCOEF)] mov eax, dword [DWBLOCK(4,0,esi,SIZEOF_JCOEF)] or ebx, dword [DWBLOCK(5,0,esi,SIZEOF_JCOEF)] or eax, dword [DWBLOCK(6,0,esi,SIZEOF_JCOEF)] or ebx, dword [DWBLOCK(7,0,esi,SIZEOF_JCOEF)] or eax, ebx - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address jnz short .columnDCT ; -- AC terms all zero @@ -127,7 +123,7 @@ EXTN(jsimd_idct_float_3dnow): movq MMWORD [MMBLOCK(1,2,edi,SIZEOF_FAST_FLOAT)], mm1 movq MMWORD [MMBLOCK(1,3,edi,SIZEOF_FAST_FLOAT)], mm1 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -293,7 +289,7 @@ EXTN(jsimd_idct_float_3dnow): mov edi, JSAMPARRAY [output_buf(eax)] ; (JSAMPROW *) mov eax, JDIMENSION [output_col(eax)] mov ecx, DCTSIZE/2 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .rowloop: ; -- Even part @@ -420,14 +416,14 @@ EXTN(jsimd_idct_float_3dnow): punpckldq mm6, mm4 ; mm6=(00 01 02 03 04 05 06 07) punpckhdq mm7, mm4 ; mm7=(10 11 12 13 14 15 16 17) - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] mov ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW] movq MMWORD [edx+eax*SIZEOF_JSAMPLE], mm6 movq MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm7 - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address add esi, byte 2*SIZEOF_FAST_FLOAT ; wsptr add edi, byte 2*SIZEOF_JSAMPROW diff --git a/simd/i386/jidctflt-sse.asm b/simd/i386/jidctflt-sse.asm index b27ecfd..caf636b 100644 --- a/simd/i386/jidctflt-sse.asm +++ b/simd/i386/jidctflt-sse.asm @@ -2,17 +2,13 @@ ; jidctflt.asm - floating-point IDCT (SSE & MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the inverse DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -23,18 +19,18 @@ ; -------------------------------------------------------------------------- -%macro unpcklps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) +%macro UNPCKLPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) shufps %1, %2, 0x44 %endmacro -%macro unpckhps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) +%macro UNPCKHPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) shufps %1, %2, 0xEE %endmacro ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_float_sse) EXTN(jconst_idct_float_sse): @@ -46,7 +42,7 @@ PD_M2_613 times 4 dd -2.613125929752753055713286 PD_0_125 times 4 dd 0.125 ; 1/8 PB_CENTERJSAMP times 8 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -88,7 +84,7 @@ EXTN(jsimd_idct_float_sse): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -97,7 +93,7 @@ EXTN(jsimd_idct_float_sse): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; FAST_FLOAT *wsptr mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] @@ -149,7 +145,7 @@ EXTN(jsimd_idct_float_sse): movaps XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm3 movaps XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -325,11 +321,11 @@ EXTN(jsimd_idct_float_sse): unpckhps xmm4, xmm0 ; xmm4=(42 52 43 53) movaps xmm3, xmm6 ; transpose coefficients(phase 2) - unpcklps2 xmm6, xmm7 ; xmm6=(00 10 20 30) - unpckhps2 xmm3, xmm7 ; xmm3=(01 11 21 31) + UNPCKLPS2 xmm6, xmm7 ; xmm6=(00 10 20 30) + UNPCKHPS2 xmm3, xmm7 ; xmm3=(01 11 21 31) movaps xmm0, xmm1 ; transpose coefficients(phase 2) - unpcklps2 xmm1, xmm2 ; xmm1=(02 12 22 32) - unpckhps2 xmm0, xmm2 ; xmm0=(03 13 23 33) + UNPCKLPS2 xmm1, xmm2 ; xmm1=(02 12 22 32) + UNPCKHPS2 xmm0, xmm2 ; xmm0=(03 13 23 33) movaps xmm7, XMMWORD [wk(0)] ; xmm7=(60 70 61 71) movaps xmm2, XMMWORD [wk(1)] ; xmm2=(62 72 63 73) @@ -340,11 +336,11 @@ EXTN(jsimd_idct_float_sse): movaps XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm0 movaps xmm6, xmm5 ; transpose coefficients(phase 2) - unpcklps2 xmm5, xmm7 ; xmm5=(40 50 60 70) - unpckhps2 xmm6, xmm7 ; xmm6=(41 51 61 71) + UNPCKLPS2 xmm5, xmm7 ; xmm5=(40 50 60 70) + UNPCKHPS2 xmm6, xmm7 ; xmm6=(41 51 61 71) movaps xmm3, xmm4 ; transpose coefficients(phase 2) - unpcklps2 xmm4, xmm2 ; xmm4=(42 52 62 72) - unpckhps2 xmm3, xmm2 ; xmm3=(43 53 63 73) + UNPCKLPS2 xmm4, xmm2 ; xmm4=(42 52 62 72) + UNPCKHPS2 xmm3, xmm2 ; xmm3=(43 53 63 73) movaps XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm5 movaps XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm6 @@ -372,7 +368,7 @@ EXTN(jsimd_idct_float_sse): mov edi, JSAMPARRAY [output_buf(eax)] ; (JSAMPROW *) mov eax, JDIMENSION [output_col(eax)] mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .rowloop: ; -- Even part @@ -536,7 +532,7 @@ EXTN(jsimd_idct_float_sse): punpckldq mm5, mm6 ; mm5=(20 21 22 23 24 25 26 27) punpckhdq mm4, mm6 ; mm4=(30 31 32 33 34 35 36 37) - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] mov ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW] @@ -547,7 +543,7 @@ EXTN(jsimd_idct_float_sse): movq MMWORD [edx+eax*SIZEOF_JSAMPLE], mm5 movq MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm4 - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address add esi, byte 4*SIZEOF_FAST_FLOAT ; wsptr add edi, byte 4*SIZEOF_JSAMPROW diff --git a/simd/i386/jidctflt-sse2.asm b/simd/i386/jidctflt-sse2.asm index c646eae..42703a8 100644 --- a/simd/i386/jidctflt-sse2.asm +++ b/simd/i386/jidctflt-sse2.asm @@ -2,17 +2,13 @@ ; jidctflt.asm - floating-point IDCT (SSE & SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the inverse DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -23,18 +19,18 @@ ; -------------------------------------------------------------------------- -%macro unpcklps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) +%macro UNPCKLPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) shufps %1, %2, 0x44 %endmacro -%macro unpckhps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) +%macro UNPCKHPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) shufps %1, %2, 0xEE %endmacro ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_float_sse2) EXTN(jconst_idct_float_sse2): @@ -46,7 +42,7 @@ PD_M2_613 times 4 dd -2.613125929752753055713286 PD_RNDINT_MAGIC times 4 dd 100663296.0 ; (float)(0x00C00000 << 3) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -88,7 +84,7 @@ EXTN(jsimd_idct_float_sse2): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -97,7 +93,7 @@ EXTN(jsimd_idct_float_sse2): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; FAST_FLOAT *wsptr mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_FLOAT_SSE mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] @@ -150,7 +146,7 @@ EXTN(jsimd_idct_float_sse2): movaps XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm3 movaps XMMWORD [XMMBLOCK(3,1,edi,SIZEOF_FAST_FLOAT)], xmm3 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -287,11 +283,11 @@ EXTN(jsimd_idct_float_sse2): unpckhps xmm4, xmm0 ; xmm4=(42 52 43 53) movaps xmm3, xmm6 ; transpose coefficients(phase 2) - unpcklps2 xmm6, xmm7 ; xmm6=(00 10 20 30) - unpckhps2 xmm3, xmm7 ; xmm3=(01 11 21 31) + UNPCKLPS2 xmm6, xmm7 ; xmm6=(00 10 20 30) + UNPCKHPS2 xmm3, xmm7 ; xmm3=(01 11 21 31) movaps xmm0, xmm1 ; transpose coefficients(phase 2) - unpcklps2 xmm1, xmm2 ; xmm1=(02 12 22 32) - unpckhps2 xmm0, xmm2 ; xmm0=(03 13 23 33) + UNPCKLPS2 xmm1, xmm2 ; xmm1=(02 12 22 32) + UNPCKHPS2 xmm0, xmm2 ; xmm0=(03 13 23 33) movaps xmm7, XMMWORD [wk(0)] ; xmm7=(60 70 61 71) movaps xmm2, XMMWORD [wk(1)] ; xmm2=(62 72 63 73) @@ -302,11 +298,11 @@ EXTN(jsimd_idct_float_sse2): movaps XMMWORD [XMMBLOCK(3,0,edi,SIZEOF_FAST_FLOAT)], xmm0 movaps xmm6, xmm5 ; transpose coefficients(phase 2) - unpcklps2 xmm5, xmm7 ; xmm5=(40 50 60 70) - unpckhps2 xmm6, xmm7 ; xmm6=(41 51 61 71) + UNPCKLPS2 xmm5, xmm7 ; xmm5=(40 50 60 70) + UNPCKHPS2 xmm6, xmm7 ; xmm6=(41 51 61 71) movaps xmm3, xmm4 ; transpose coefficients(phase 2) - unpcklps2 xmm4, xmm2 ; xmm4=(42 52 62 72) - unpckhps2 xmm3, xmm2 ; xmm3=(43 53 63 73) + UNPCKLPS2 xmm4, xmm2 ; xmm4=(42 52 62 72) + UNPCKHPS2 xmm3, xmm2 ; xmm3=(43 53 63 73) movaps XMMWORD [XMMBLOCK(0,1,edi,SIZEOF_FAST_FLOAT)], xmm5 movaps XMMWORD [XMMBLOCK(1,1,edi,SIZEOF_FAST_FLOAT)], xmm6 @@ -334,7 +330,7 @@ EXTN(jsimd_idct_float_sse2): mov edi, JSAMPARRAY [output_buf(eax)] ; (JSAMPROW *) mov eax, JDIMENSION [output_col(eax)] mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .rowloop: ; -- Even part @@ -464,7 +460,7 @@ EXTN(jsimd_idct_float_sse2): pshufd xmm5, xmm6, 0x4E ; xmm5=(10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07) pshufd xmm3, xmm7, 0x4E ; xmm3=(30 31 32 33 34 35 36 37 20 21 22 23 24 25 26 27) - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] mov ebx, JSAMPROW [edi+2*SIZEOF_JSAMPROW] @@ -475,7 +471,7 @@ EXTN(jsimd_idct_float_sse2): movq XMM_MMWORD [edx+eax*SIZEOF_JSAMPLE], xmm5 movq XMM_MMWORD [ebx+eax*SIZEOF_JSAMPLE], xmm3 - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address add esi, byte 4*SIZEOF_FAST_FLOAT ; wsptr add edi, byte 4*SIZEOF_JSAMPROW diff --git a/simd/i386/jidctfst-mmx.asm b/simd/i386/jidctfst-mmx.asm index 24622d4..77d4613 100644 --- a/simd/i386/jidctfst-mmx.asm +++ b/simd/i386/jidctfst-mmx.asm @@ -2,17 +2,13 @@ ; jidctfst.asm - fast integer IDCT (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the inverse DCT (Discrete Cosine Transform). The following code is @@ -56,7 +52,7 @@ F_1_613 equ (F_2_613 - (1 << CONST_BITS)) ; FIX(2.613125930) - FIX(1) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_ifast_mmx) EXTN(jconst_idct_ifast_mmx): @@ -67,7 +63,7 @@ PW_MF1613 times 4 dw -F_1_613 << CONST_SHIFT PW_F1082 times 4 dw F_1_082 << CONST_SHIFT PB_CENTERJSAMP times 8 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -109,7 +105,7 @@ EXTN(jsimd_idct_ifast_mmx): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -118,7 +114,7 @@ EXTN(jsimd_idct_ifast_mmx): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; JCOEF *wsptr mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_IFAST_MMX mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] @@ -163,7 +159,7 @@ EXTN(jsimd_idct_ifast_mmx): movq MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3 movq MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm3 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -326,7 +322,7 @@ EXTN(jsimd_idct_ifast_mmx): mov edi, JSAMPARRAY [output_buf(eax)] ; (JSAMPROW *) mov eax, JDIMENSION [output_col(eax)] mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .rowloop: ; -- Even part @@ -464,7 +460,7 @@ EXTN(jsimd_idct_ifast_mmx): punpckldq mm5, mm4 ; mm5=(20 21 22 23 24 25 26 27) punpckhdq mm1, mm4 ; mm1=(30 31 32 33 34 35 36 37) - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] mov ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW] @@ -475,7 +471,7 @@ EXTN(jsimd_idct_ifast_mmx): movq MMWORD [edx+eax*SIZEOF_JSAMPLE], mm5 movq MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm1 - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address add esi, byte 4*SIZEOF_JCOEF ; wsptr add edi, byte 4*SIZEOF_JSAMPROW diff --git a/simd/i386/jidctfst-sse2.asm b/simd/i386/jidctfst-sse2.asm index 19704ff..c2fe34b 100644 --- a/simd/i386/jidctfst-sse2.asm +++ b/simd/i386/jidctfst-sse2.asm @@ -2,17 +2,13 @@ ; jidctfst.asm - fast integer IDCT (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the inverse DCT (Discrete Cosine Transform). The following code is @@ -56,7 +52,7 @@ F_1_613 equ (F_2_613 - (1 << CONST_BITS)) ; FIX(2.613125930) - FIX(1) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_ifast_sse2) EXTN(jconst_idct_ifast_sse2): @@ -67,7 +63,7 @@ PW_MF1613 times 8 dw -F_1_613 << CONST_SHIFT PW_F1082 times 8 dw F_1_082 << CONST_SHIFT PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -101,13 +97,13 @@ EXTN(jsimd_idct_ifast_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input. @@ -155,7 +151,7 @@ EXTN(jsimd_idct_ifast_sse2): movdqa XMMWORD [wk(0)], xmm2 ; wk(0)=col1 movdqa XMMWORD [wk(1)], xmm0 ; wk(1)=col3 jmp near .column_end - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -490,7 +486,7 @@ EXTN(jsimd_idct_ifast_sse2): pop esi ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jidctint-avx2.asm b/simd/i386/jidctint-avx2.asm index 199c7df..cb119d3 100644 --- a/simd/i386/jidctint-avx2.asm +++ b/simd/i386/jidctint-avx2.asm @@ -2,17 +2,13 @@ ; jidctint.asm - accurate integer IDCT (AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2018, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; inverse DCT (Discrete Cosine Transform). The following code is based @@ -65,7 +61,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %1-%4: Input/output registers ; %5-%8: Temp registers -%macro dotranspose 8 +%macro DOTRANSPOSE 8 ; %5=(00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71) ; %6=(03 13 23 33 43 53 63 73 02 12 22 32 42 52 62 72) ; %7=(04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75) @@ -118,7 +114,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %5-%12: Temp registers ; %9: Pass (1 or 2) -%macro dodct 13 +%macro DODCT 13 ; -- Even part ; (Original) @@ -250,7 +246,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_islow_avx2) EXTN(jconst_idct_islow_avx2): @@ -269,7 +265,7 @@ PB_CENTERJSAMP times 32 db CENTERJSAMPLE PW_1_NEG1 times 8 dw 1 times 8 dw -1 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -303,13 +299,13 @@ EXTN(jsimd_idct_islow_avx2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns. @@ -353,7 +349,7 @@ EXTN(jsimd_idct_islow_avx2): vpshufd ymm3, ymm4, 0xFF ; ymm3=col3_7=(03 03 03 03 03 03 03 03 07 07 07 07 07 07 07 07) jmp near .column_end - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -371,10 +367,10 @@ EXTN(jsimd_idct_islow_avx2): vperm2i128 ymm2, ymm5, ymm7, 0x20 ; ymm2=in2_6 vperm2i128 ymm3, ymm7, ymm6, 0x31 ; ymm3=in7_5 - dodct ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, XMMWORD [wk(0)], XMMWORD [wk(1)], XMMWORD [wk(2)], XMMWORD [wk(3)], 1 + DODCT ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, XMMWORD [wk(0)], XMMWORD [wk(1)], XMMWORD [wk(2)], XMMWORD [wk(3)], 1 ; ymm0=data0_1, ymm1=data3_2, ymm2=data4_5, ymm3=data7_6 - dotranspose ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 ; ymm0=data0_4, ymm1=data1_5, ymm2=data2_6, ymm3=data3_7 .column_end: @@ -395,10 +391,10 @@ EXTN(jsimd_idct_islow_avx2): vperm2i128 ymm4, ymm3, ymm1, 0x31 ; ymm3=in7_5 vperm2i128 ymm1, ymm3, ymm1, 0x20 ; ymm1=in3_1 - dodct ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, XMMWORD [wk(0)], XMMWORD [wk(1)], XMMWORD [wk(2)], XMMWORD [wk(3)], 2 + DODCT ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, XMMWORD [wk(0)], XMMWORD [wk(1)], XMMWORD [wk(2)], XMMWORD [wk(3)], 2 ; ymm0=data0_1, ymm1=data3_2, ymm2=data4_5, ymm4=data7_6 - dotranspose ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 ; ymm0=data0_4, ymm1=data1_5, ymm2=data2_6, ymm4=data3_7 vpacksswb ymm0, ymm0, ymm1 ; ymm0=data01_45 @@ -442,7 +438,7 @@ EXTN(jsimd_idct_islow_avx2): pop esi ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jidctint-mmx.asm b/simd/i386/jidctint-mmx.asm index f15c8d3..c2c17f4 100644 --- a/simd/i386/jidctint-mmx.asm +++ b/simd/i386/jidctint-mmx.asm @@ -2,17 +2,13 @@ ; jidctint.asm - accurate integer IDCT (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, 2020, D. R. Commander. +; Copyright (C) 2016, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; inverse DCT (Discrete Cosine Transform). The following code is based @@ -63,7 +59,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_islow_mmx) EXTN(jconst_idct_islow_mmx): @@ -80,7 +76,7 @@ PD_DESCALE_P1 times 2 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 2 dd 1 << (DESCALE_P2 - 1) PB_CENTERJSAMP times 8 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -122,7 +118,7 @@ EXTN(jsimd_idct_islow_mmx): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -131,7 +127,7 @@ EXTN(jsimd_idct_islow_mmx): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; JCOEF *wsptr mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_ISLOW_MMX mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] @@ -178,7 +174,7 @@ EXTN(jsimd_idct_islow_mmx): movq MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3 movq MMWORD [MMBLOCK(3,1,edi,SIZEOF_JCOEF)], mm3 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -513,7 +509,7 @@ EXTN(jsimd_idct_islow_mmx): mov edi, JSAMPARRAY [output_buf(eax)] ; (JSAMPROW *) mov eax, JDIMENSION [output_col(eax)] mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .rowloop: ; -- Even part @@ -816,7 +812,7 @@ EXTN(jsimd_idct_islow_mmx): punpckldq mm7, mm5 ; mm7=(20 21 22 23 24 25 26 27) punpckhdq mm4, mm5 ; mm4=(30 31 32 33 34 35 36 37) - pushpic ebx ; save GOT address + PUSHPIC ebx ; save GOT address mov edx, JSAMPROW [edi+0*SIZEOF_JSAMPROW] mov ebx, JSAMPROW [edi+1*SIZEOF_JSAMPROW] @@ -827,7 +823,7 @@ EXTN(jsimd_idct_islow_mmx): movq MMWORD [edx+eax*SIZEOF_JSAMPLE], mm7 movq MMWORD [ebx+eax*SIZEOF_JSAMPLE], mm4 - poppic ebx ; restore GOT address + POPPIC ebx ; restore GOT address add esi, byte 4*SIZEOF_JCOEF ; wsptr add edi, byte 4*SIZEOF_JSAMPROW diff --git a/simd/i386/jidctint-sse2.asm b/simd/i386/jidctint-sse2.asm index 43e3201..70516ca 100644 --- a/simd/i386/jidctint-sse2.asm +++ b/simd/i386/jidctint-sse2.asm @@ -2,17 +2,13 @@ ; jidctint.asm - accurate integer IDCT (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, 2020, D. R. Commander. +; Copyright (C) 2016, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; inverse DCT (Discrete Cosine Transform). The following code is based @@ -63,7 +59,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_islow_sse2) EXTN(jconst_idct_islow_sse2): @@ -80,7 +76,7 @@ PD_DESCALE_P1 times 4 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 4 dd 1 << (DESCALE_P2 - 1) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -114,13 +110,13 @@ EXTN(jsimd_idct_islow_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input. @@ -172,7 +168,7 @@ EXTN(jsimd_idct_islow_sse2): movdqa XMMWORD [wk(10)], xmm3 ; wk(10)=col5 movdqa XMMWORD [wk(11)], xmm4 ; wk(11)=col7 jmp near .column_end - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -847,7 +843,7 @@ EXTN(jsimd_idct_islow_sse2): pop esi ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp diff --git a/simd/i386/jidctred-mmx.asm b/simd/i386/jidctred-mmx.asm index e2307e1..96cda65 100644 --- a/simd/i386/jidctred-mmx.asm +++ b/simd/i386/jidctred-mmx.asm @@ -2,17 +2,13 @@ ; jidctred.asm - reduced-size IDCT (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains inverse-DCT routines that produce reduced-size ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block. @@ -69,7 +65,7 @@ F_3_624 equ DESCALE(3891787747, 30 - CONST_BITS) ; FIX(3.624509785) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_red_mmx) EXTN(jconst_idct_red_mmx): @@ -87,7 +83,7 @@ PD_DESCALE_P1_2 times 2 dd 1 << (DESCALE_P1_2 - 1) PD_DESCALE_P2_2 times 2 dd 1 << (DESCALE_P2_2 - 1) PB_CENTERJSAMP times 8 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -124,13 +120,13 @@ EXTN(jsimd_idct_4x4_mmx): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [workspace] - pushpic ebx + PUSHPIC ebx ; push ecx ; need not be preserved ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input, store into work array. @@ -139,7 +135,7 @@ EXTN(jsimd_idct_4x4_mmx): mov esi, JCOEFPTR [coef_block(eax)] ; inptr lea edi, [workspace] ; JCOEF *wsptr mov ecx, DCTSIZE/4 ; ctr - alignx 16, 7 + ALIGNX 16, 7 .columnloop: %ifndef NO_ZERO_COLUMN_TEST_4X4_MMX mov eax, dword [DWBLOCK(1,0,esi,SIZEOF_JCOEF)] @@ -181,7 +177,7 @@ EXTN(jsimd_idct_4x4_mmx): movq MMWORD [MMBLOCK(2,0,edi,SIZEOF_JCOEF)], mm2 movq MMWORD [MMBLOCK(3,0,edi,SIZEOF_JCOEF)], mm3 jmp near .nextcolumn - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -479,7 +475,7 @@ EXTN(jsimd_idct_4x4_mmx): pop esi ; pop edx ; need not be preserved ; pop ecx ; need not be preserved - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp @@ -512,7 +508,7 @@ EXTN(jsimd_idct_2x2_mmx): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input. diff --git a/simd/i386/jidctred-sse2.asm b/simd/i386/jidctred-sse2.asm index 6e56494..1fe967d 100644 --- a/simd/i386/jidctred-sse2.asm +++ b/simd/i386/jidctred-sse2.asm @@ -2,17 +2,13 @@ ; jidctred.asm - reduced-size IDCT (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains inverse-DCT routines that produce reduced-size ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block. @@ -69,7 +65,7 @@ F_3_624 equ DESCALE(3891787747, 30 - CONST_BITS) ; FIX(3.624509785) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_red_sse2) EXTN(jconst_idct_red_sse2): @@ -87,7 +83,7 @@ PD_DESCALE_P1_2 times 4 dd 1 << (DESCALE_P1_2 - 1) PD_DESCALE_P2_2 times 4 dd 1 << (DESCALE_P2_2 - 1) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -122,13 +118,13 @@ EXTN(jsimd_idct_4x4_sse2): mov [esp], eax mov ebp, esp ; ebp = aligned ebp lea esp, [wk(0)] - pushpic ebx + PUSHPIC ebx ; push ecx ; unused ; push edx ; need not be preserved push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input. @@ -171,7 +167,7 @@ EXTN(jsimd_idct_4x4_sse2): pshufd xmm3, xmm3, 0xFA ; xmm3=[col6 col7]=(06 06 06 06 07 07 07 07) jmp near .column_end - alignx 16, 7 + ALIGNX 16, 7 %endif .columnDCT: @@ -400,7 +396,7 @@ EXTN(jsimd_idct_4x4_sse2): pop esi ; pop edx ; need not be preserved ; pop ecx ; unused - poppic ebx + POPPIC ebx mov esp, ebp ; esp <- aligned ebp pop esp ; esp <- original ebp pop ebp @@ -433,7 +429,7 @@ EXTN(jsimd_idct_2x2_sse2): push esi push edi - get_GOT ebx ; get GOT address + GET_GOT ebx ; get GOT address ; ---- Pass 1: process columns from input. diff --git a/simd/i386/jquant-3dn.asm b/simd/i386/jquant-3dn.asm index 5cb60ca..58e0011 100644 --- a/simd/i386/jquant-3dn.asm +++ b/simd/i386/jquant-3dn.asm @@ -2,17 +2,13 @@ ; jquant.asm - sample data conversion and quantization (3DNow! & MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -52,7 +48,7 @@ EXTN(jsimd_convsamp_float_3dnow): mov eax, JDIMENSION [start_col] mov edi, POINTER [workspace] ; (DCTELEM *) mov ecx, DCTSIZE/2 - alignx 16, 7 + ALIGNX 16, 7 .convloop: mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *) mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *) @@ -154,7 +150,7 @@ EXTN(jsimd_quantize_float_3dnow): mov edx, POINTER [divisors] mov edi, JCOEFPTR [coef_block] mov eax, DCTSIZE2/16 - alignx 16, 7 + ALIGNX 16, 7 .quantloop: movq mm0, MMWORD [MMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)] movq mm1, MMWORD [MMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)] diff --git a/simd/i386/jquant-mmx.asm b/simd/i386/jquant-mmx.asm index 61305c6..4eda95c 100644 --- a/simd/i386/jquant-mmx.asm +++ b/simd/i386/jquant-mmx.asm @@ -2,17 +2,13 @@ ; jquant.asm - sample data conversion and quantization (MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -52,7 +48,7 @@ EXTN(jsimd_convsamp_mmx): mov eax, JDIMENSION [start_col] mov edi, POINTER [workspace] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .convloop: mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *) mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *) @@ -120,8 +116,8 @@ EXTN(jsimd_convsamp_mmx): ; Quantize/descale the coefficients, and store into coef_block ; ; This implementation is based on an algorithm described in -; "How to optimize for the Pentium family of microprocessors" -; (http://www.agner.org/assem/). +; "Optimizing subroutines in assembly language: +; An optimization guide for x86 platforms" (https://agner.org/optimize). ; ; GLOBAL(void) ; jsimd_quantize_mmx(JCOEFPTR coef_block, DCTELEM *divisors, @@ -157,10 +153,10 @@ EXTN(jsimd_quantize_mmx): mov edx, POINTER [divisors] mov edi, JCOEFPTR [coef_block] mov ah, 2 - alignx 16, 7 + ALIGNX 16, 7 .quantloop1: mov al, DCTSIZE2/8/2 - alignx 16, 7 + ALIGNX 16, 7 .quantloop2: movq mm2, MMWORD [MMBLOCK(0,0,esi,SIZEOF_DCTELEM)] movq mm3, MMWORD [MMBLOCK(0,1,esi,SIZEOF_DCTELEM)] diff --git a/simd/i386/jquant-sse.asm b/simd/i386/jquant-sse.asm index 218adc9..6cb5f79 100644 --- a/simd/i386/jquant-sse.asm +++ b/simd/i386/jquant-sse.asm @@ -2,17 +2,13 @@ ; jquant.asm - sample data conversion and quantization (SSE & MMX) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -52,7 +48,7 @@ EXTN(jsimd_convsamp_float_sse): mov eax, JDIMENSION [start_col] mov edi, POINTER [workspace] ; (DCTELEM *) mov ecx, DCTSIZE/2 - alignx 16, 7 + ALIGNX 16, 7 .convloop: mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *) mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *) @@ -150,7 +146,7 @@ EXTN(jsimd_quantize_float_sse): mov edx, POINTER [divisors] mov edi, JCOEFPTR [coef_block] mov eax, DCTSIZE2/16 - alignx 16, 7 + ALIGNX 16, 7 .quantloop: movaps xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)] movaps xmm1, XMMWORD [XMMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)] diff --git a/simd/i386/jquantf-sse2.asm b/simd/i386/jquantf-sse2.asm index a881ab5..5668f8c 100644 --- a/simd/i386/jquantf-sse2.asm +++ b/simd/i386/jquantf-sse2.asm @@ -2,17 +2,13 @@ ; jquantf.asm - sample data conversion and quantization (SSE & SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -52,7 +48,7 @@ EXTN(jsimd_convsamp_float_sse2): mov eax, JDIMENSION [start_col] mov edi, POINTER [workspace] ; (DCTELEM *) mov ecx, DCTSIZE/2 - alignx 16, 7 + ALIGNX 16, 7 .convloop: mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *) mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *) @@ -127,7 +123,7 @@ EXTN(jsimd_quantize_float_sse2): mov edx, POINTER [divisors] mov edi, JCOEFPTR [coef_block] mov eax, DCTSIZE2/16 - alignx 16, 7 + ALIGNX 16, 7 .quantloop: movaps xmm0, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_FAST_FLOAT)] movaps xmm1, XMMWORD [XMMBLOCK(0,1,esi,SIZEOF_FAST_FLOAT)] diff --git a/simd/i386/jquanti-avx2.asm b/simd/i386/jquanti-avx2.asm index 5ed6bec..60ae098 100644 --- a/simd/i386/jquanti-avx2.asm +++ b/simd/i386/jquanti-avx2.asm @@ -2,18 +2,14 @@ ; jquanti.asm - sample data conversion and quantization (AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, 2018, D. R. Commander. +; Copyright (C) 2016, 2018, 2024, D. R. Commander. ; Copyright (C) 2016, Matthieu Darbois. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -107,8 +103,8 @@ EXTN(jsimd_convsamp_avx2): ; Quantize/descale the coefficients, and store into coef_block ; ; This implementation is based on an algorithm described in -; "How to optimize for the Pentium family of microprocessors" -; (http://www.agner.org/assem/). +; "Optimizing subroutines in assembly language: +; An optimization guide for x86 platforms" (https://agner.org/optimize). ; ; GLOBAL(void) ; jsimd_quantize_avx2(JCOEFPTR coef_block, DCTELEM *divisors, diff --git a/simd/i386/jquanti-sse2.asm b/simd/i386/jquanti-sse2.asm index 0a50940..c1edde9 100644 --- a/simd/i386/jquanti-sse2.asm +++ b/simd/i386/jquanti-sse2.asm @@ -2,17 +2,13 @@ ; jquanti.asm - sample data conversion and quantization (SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2016, D. R. Commander. +; Copyright (C) 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -52,7 +48,7 @@ EXTN(jsimd_convsamp_sse2): mov eax, JDIMENSION [start_col] mov edi, POINTER [workspace] ; (DCTELEM *) mov ecx, DCTSIZE/4 - alignx 16, 7 + ALIGNX 16, 7 .convloop: mov ebx, JSAMPROW [esi+0*SIZEOF_JSAMPROW] ; (JSAMPLE *) mov edx, JSAMPROW [esi+1*SIZEOF_JSAMPROW] ; (JSAMPLE *) @@ -98,8 +94,8 @@ EXTN(jsimd_convsamp_sse2): ; Quantize/descale the coefficients, and store into coef_block ; ; This implementation is based on an algorithm described in -; "How to optimize for the Pentium family of microprocessors" -; (http://www.agner.org/assem/). +; "Optimizing subroutines in assembly language: +; An optimization guide for x86 platforms" (https://agner.org/optimize). ; ; GLOBAL(void) ; jsimd_quantize_sse2(JCOEFPTR coef_block, DCTELEM *divisors, @@ -133,7 +129,7 @@ EXTN(jsimd_quantize_sse2): mov edx, POINTER [divisors] mov edi, JCOEFPTR [coef_block] mov eax, DCTSIZE2/32 - alignx 16, 7 + ALIGNX 16, 7 .quantloop: movdqa xmm4, XMMWORD [XMMBLOCK(0,0,esi,SIZEOF_DCTELEM)] movdqa xmm5, XMMWORD [XMMBLOCK(1,0,esi,SIZEOF_DCTELEM)] diff --git a/simd/i386/jsimdcpu.asm b/simd/i386/jsimdcpu.asm index ddcafa9..df80f17 100644 --- a/simd/i386/jsimdcpu.asm +++ b/simd/i386/jsimdcpu.asm @@ -8,11 +8,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" diff --git a/simd/nasm/jsimdext.inc b/simd/nasm/jsimdext.inc index bebcb20..b5341ed 100644 --- a/simd/nasm/jsimdext.inc +++ b/simd/nasm/jsimdext.inc @@ -2,7 +2,7 @@ ; jsimdext.inc - common declarations ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2010, 2016, 2018-2019, D. R. Commander. +; Copyright (C) 2010, 2016, 2018-2019, 2024, D. R. Commander. ; Copyright (C) 2018, Matthieu Darbois. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -76,6 +76,14 @@ ; mark stack as non-executable section .note.GNU-stack noalloc noexec nowrite progbits +%ifdef __CET__ +%ifdef __x86_64__ +section .note.gnu.property note alloc noexec align=8 + dd 0x00000004, 0x00000010, 0x00000005, 0x00554e47 + dd 0xc0000002, 0x00000004, 0x00000003, 0x00000000 +%endif +%endif + ; -- segment definition -- ; %ifdef __x86_64__ @@ -272,7 +280,7 @@ const_base: %define GOTOFF(got, sym) (got) + (sym) - const_base -%imacro get_GOT 1 +%imacro GET_GOT 1 ; NOTE: this macro destroys ecx resister. call %%geteip add ecx, byte (%%ref - $) @@ -304,7 +312,7 @@ const_base: %define GOTOFF(got, sym) (got) + (sym) wrt ..gotoff -%imacro get_GOT 1 +%imacro GET_GOT 1 extern GOT_SYMBOL call %%geteip add %1, GOT_SYMBOL + $$ - $ wrt ..gotpc @@ -317,13 +325,13 @@ const_base: %endif ; GOT_SYMBOL == _MACHO_PIC_ ---------------- -%imacro pushpic 1.nolist +%imacro PUSHPIC 1.nolist push %1 %endmacro -%imacro poppic 1.nolist +%imacro POPPIC 1.nolist pop %1 %endmacro -%imacro movpic 2.nolist +%imacro MOVPIC 2.nolist mov %1, %2 %endmacro @@ -331,13 +339,13 @@ const_base: %define GOTOFF(got, sym) (sym) -%imacro get_GOT 1.nolist +%imacro GET_GOT 1.nolist %endmacro -%imacro pushpic 1.nolist +%imacro PUSHPIC 1.nolist %endmacro -%imacro poppic 1.nolist +%imacro POPPIC 1.nolist %endmacro -%imacro movpic 2.nolist +%imacro MOVPIC 2.nolist %endmacro %endif ; PIC ----------------------------------------- @@ -349,7 +357,7 @@ const_base: %define MSKLE(x, y) (~(((y) & 0xFFFF) - ((x) & 0xFFFF)) >> 16) %define FILLB(b, n) (($$-(b)) & ((n)-1)) -%imacro alignx 1-2.nolist 0xFFFF +%imacro ALIGNX 1-2.nolist 0xFFFF %%bs: \ times MSKLE(FILLB(%%bs, %1), %2) & MSKLE(16, FILLB($, %1)) & FILLB($, %1) \ db 0x90 ; nop @@ -371,7 +379,7 @@ const_base: ; Align the next data on {2,4,8,16,..}-byte boundary. ; -%imacro alignz 1.nolist +%imacro ALIGNZ 1.nolist align %1, db 0 ; filling zeros %endmacro @@ -379,7 +387,7 @@ const_base: %ifdef WIN64 -%imacro collect_args 1 +%imacro COLLECT_ARGS 1 sub rsp, SIZEOF_XMMWORD movaps XMMWORD [rsp], xmm6 sub rsp, SIZEOF_XMMWORD @@ -408,7 +416,7 @@ const_base: push rdi %endmacro -%imacro uncollect_args 1 +%imacro UNCOLLECT_ARGS 1 pop rdi pop rsi %if %1 > 5 @@ -429,7 +437,7 @@ const_base: add rsp, SIZEOF_XMMWORD %endmacro -%imacro push_xmm 1 +%imacro PUSH_XMM 1 sub rsp, %1 * SIZEOF_XMMWORD movaps XMMWORD [rsp+0*SIZEOF_XMMWORD], xmm8 %if %1 > 1 @@ -443,7 +451,7 @@ const_base: %endif %endmacro -%imacro pop_xmm 1 +%imacro POP_XMM 1 movaps xmm8, XMMWORD [rsp+0*SIZEOF_XMMWORD] %if %1 > 1 movaps xmm9, XMMWORD [rsp+1*SIZEOF_XMMWORD] @@ -459,7 +467,7 @@ const_base: %else -%imacro collect_args 1 +%imacro COLLECT_ARGS 1 push r10 mov r10, rdi %if %1 > 1 @@ -484,7 +492,7 @@ const_base: %endif %endmacro -%imacro uncollect_args 1 +%imacro UNCOLLECT_ARGS 1 %if %1 > 5 pop r15 %endif @@ -503,16 +511,29 @@ const_base: pop r10 %endmacro -%imacro push_xmm 1 +%imacro PUSH_XMM 1 %endmacro -%imacro pop_xmm 1 +%imacro POP_XMM 1 %endmacro %endif %endif +%ifdef __CET__ + +%imacro ENDBR64 0 + dd 0xfa1e0ff3 +%endmacro + +%else + +%imacro ENDBR64 0 +%endmacro + +%endif + ; -------------------------------------------------------------------------- ; Defines picked up from the C headers ; diff --git a/simd/x86_64/jccolext-avx2.asm b/simd/x86_64/jccolext-avx2.asm index dd7ea39..aeeda0a 100644 --- a/simd/x86_64/jccolext-avx2.asm +++ b/simd/x86_64/jccolext-avx2.asm @@ -1,7 +1,7 @@ ; ; jccolext.asm - colorspace conversion (64-bit AVX2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -41,6 +37,7 @@ GLOBAL_FUNCTION(jsimd_rgb_ycc_convert_avx2) EXTN(jsimd_rgb_ycc_convert_avx2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -48,7 +45,7 @@ EXTN(jsimd_rgb_ycc_convert_avx2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, (SIZEOF_YMMWORD * WK_NUM) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d @@ -549,7 +546,7 @@ EXTN(jsimd_rgb_ycc_convert_avx2): .return: pop rbx vzeroupper - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jccolext-sse2.asm b/simd/x86_64/jccolext-sse2.asm index bc1e817..f3a1244 100644 --- a/simd/x86_64/jccolext-sse2.asm +++ b/simd/x86_64/jccolext-sse2.asm @@ -1,7 +1,7 @@ ; ; jccolext.asm - colorspace conversion (64-bit SSE2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -9,11 +9,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -40,6 +36,7 @@ GLOBAL_FUNCTION(jsimd_rgb_ycc_convert_sse2) EXTN(jsimd_rgb_ycc_convert_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -47,7 +44,7 @@ EXTN(jsimd_rgb_ycc_convert_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, (SIZEOF_XMMWORD * WK_NUM) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d @@ -474,7 +471,7 @@ EXTN(jsimd_rgb_ycc_convert_sse2): .return: pop rbx - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jccolor-avx2.asm b/simd/x86_64/jccolor-avx2.asm index 16b7829..e262891 100644 --- a/simd/x86_64/jccolor-avx2.asm +++ b/simd/x86_64/jccolor-avx2.asm @@ -1,18 +1,14 @@ ; ; jccolor.asm - colorspace conversion (64-bit AVX2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -33,7 +29,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_ycc_convert_avx2) EXTN(jconst_rgb_ycc_convert_avx2): @@ -46,7 +42,7 @@ PD_ONEHALFM1_CJ times 8 dd (1 << (SCALEBITS - 1)) - 1 + \ (CENTERJSAMPLE << SCALEBITS) PD_ONEHALF times 8 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jccolor-sse2.asm b/simd/x86_64/jccolor-sse2.asm index e2955c2..cc9edb4 100644 --- a/simd/x86_64/jccolor-sse2.asm +++ b/simd/x86_64/jccolor-sse2.asm @@ -1,17 +1,13 @@ ; ; jccolor.asm - colorspace conversion (64-bit SSE2) ; -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_ycc_convert_sse2) EXTN(jconst_rgb_ycc_convert_sse2): @@ -45,7 +41,7 @@ PD_ONEHALFM1_CJ times 4 dd (1 << (SCALEBITS - 1)) - 1 + \ (CENTERJSAMPLE << SCALEBITS) PD_ONEHALF times 4 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jcgray-avx2.asm b/simd/x86_64/jcgray-avx2.asm index 591255b..267ec51 100644 --- a/simd/x86_64/jcgray-avx2.asm +++ b/simd/x86_64/jcgray-avx2.asm @@ -1,18 +1,14 @@ ; ; jcgray.asm - grayscale colorspace conversion (64-bit AVX2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -29,7 +25,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_gray_convert_avx2) EXTN(jconst_rgb_gray_convert_avx2): @@ -38,7 +34,7 @@ PW_F0299_F0337 times 8 dw F_0_299, F_0_337 PW_F0114_F0250 times 8 dw F_0_114, F_0_250 PD_ONEHALF times 8 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jcgray-sse2.asm b/simd/x86_64/jcgray-sse2.asm index e389904..4b94d7b 100644 --- a/simd/x86_64/jcgray-sse2.asm +++ b/simd/x86_64/jcgray-sse2.asm @@ -1,17 +1,13 @@ ; ; jcgray.asm - grayscale colorspace conversion (64-bit SSE2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -28,7 +24,7 @@ F_0_337 equ (F_0_587 - F_0_250) ; FIX(0.58700) - FIX(0.25000) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_rgb_gray_convert_sse2) EXTN(jconst_rgb_gray_convert_sse2): @@ -37,7 +33,7 @@ PW_F0299_F0337 times 4 dw F_0_299, F_0_337 PW_F0114_F0250 times 4 dw F_0_114, F_0_250 PD_ONEHALF times 4 dd (1 << (SCALEBITS - 1)) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jcgryext-avx2.asm b/simd/x86_64/jcgryext-avx2.asm index c8c8d12..77e85f7 100644 --- a/simd/x86_64/jcgryext-avx2.asm +++ b/simd/x86_64/jcgryext-avx2.asm @@ -1,7 +1,7 @@ ; ; jcgryext.asm - grayscale colorspace conversion (64-bit AVX2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -41,6 +37,7 @@ GLOBAL_FUNCTION(jsimd_rgb_gray_convert_avx2) EXTN(jsimd_rgb_gray_convert_avx2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -48,7 +45,7 @@ EXTN(jsimd_rgb_gray_convert_avx2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_YMMWORD * WK_NUM) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d @@ -428,7 +425,7 @@ EXTN(jsimd_rgb_gray_convert_avx2): .return: pop rbx vzeroupper - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jcgryext-sse2.asm b/simd/x86_64/jcgryext-sse2.asm index 7e5a0f2..3e8087c 100644 --- a/simd/x86_64/jcgryext-sse2.asm +++ b/simd/x86_64/jcgryext-sse2.asm @@ -1,7 +1,7 @@ ; ; jcgryext.asm - grayscale colorspace conversion (64-bit SSE2) ; -; Copyright (C) 2011, 2016, D. R. Commander. +; Copyright (C) 2011, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -9,11 +9,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -40,6 +36,7 @@ GLOBAL_FUNCTION(jsimd_rgb_gray_convert_sse2) EXTN(jsimd_rgb_gray_convert_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -47,7 +44,7 @@ EXTN(jsimd_rgb_gray_convert_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d @@ -353,7 +350,7 @@ EXTN(jsimd_rgb_gray_convert_sse2): .return: pop rbx - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jchuff-sse2.asm b/simd/x86_64/jchuff-sse2.asm index a0eb9ce..b18b7f5 100644 --- a/simd/x86_64/jchuff-sse2.asm +++ b/simd/x86_64/jchuff-sse2.asm @@ -1,7 +1,7 @@ ; ; jchuff-sse2.asm - Huffman entropy encoding (64-bit SSE2) ; -; Copyright (C) 2009-2011, 2014-2016, 2019, 2021, 2023, D. R. Commander. +; Copyright (C) 2009-2011, 2014-2016, 2019, 2021, 2023-2024, D. R. Commander. ; Copyright (C) 2015, Matthieu Darbois. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains an SSE2 implementation for Huffman coding of one block. ; The following code is based on jchuff.c; see jchuff.c for more details. @@ -39,7 +35,7 @@ endstruc ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_huff_encode_one_block) EXTN(jconst_huff_encode_one_block): @@ -49,7 +45,7 @@ jpeg_mask_bits dd 0x0000, 0x0001, 0x0003, 0x0007 dd 0x00ff, 0x01ff, 0x03ff, 0x07ff dd 0x0fff, 0x1fff, 0x3fff, 0x7fff - alignz 32 + ALIGNZ 32 times 1 << 14 db 15 times 1 << 13 db 14 @@ -67,7 +63,8 @@ times 1 << 2 db 3 times 1 << 1 db 2 times 1 << 0 db 1 times 1 db 0 -jpeg_nbits_table: +GLOBAL_DATA(jpeg_nbits_table) +EXTN(jpeg_nbits_table): times 1 db 0 times 1 << 0 db 1 times 1 << 1 db 2 @@ -86,10 +83,10 @@ times 1 << 13 db 14 times 1 << 14 db 15 times 1 << 15 db 16 - alignz 32 + ALIGNZ 32 %define NBITS(x) nbits_base + x -%define MASK_BITS(x) NBITS((x) * 4) + (jpeg_mask_bits - jpeg_nbits_table) +%define MASK_BITS(x) NBITS((x) * 4) + (jpeg_mask_bits - EXTN(jpeg_nbits_table)) ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -260,6 +257,7 @@ times 1 << 15 db 16 GLOBAL_FUNCTION(jsimd_huff_encode_one_block_sse2) EXTN(jsimd_huff_encode_one_block_sse2): + ENDBR64 push rbp mov rbp, rsp @@ -290,7 +288,7 @@ EXTN(jsimd_huff_encode_one_block_sse2): mov dctbl, POINTER [rbp+48] mov actbl, POINTER [rbp+56] punpckldq xmm0, xmm1 ;A: w0 = xx 01 08 09 02 03 10 11 - lea nbits_base, [rel jpeg_nbits_table] + lea nbits_base, [rel EXTN(jpeg_nbits_table)] %else @@ -312,7 +310,7 @@ EXTN(jsimd_huff_encode_one_block_sse2): mov buffer, rsi movups xmm1, XMMWORD [block + 8 * SIZEOF_WORD] ;B: w1 = 08 09 10 11 12 13 14 15 movsx codeq, word [block] ;Z: code = block[0]; - lea nbits_base, [rel jpeg_nbits_table] + lea nbits_base, [rel EXTN(jpeg_nbits_table)] pxor xmm4, xmm4 ;A: w4[i] = 0; sub codeq, rcx ;Z: code -= last_dc_val; punpckldq xmm0, xmm1 ;A: w0 = xx 01 08 09 02 03 10 11 diff --git a/simd/x86_64/jcphuff-sse2.asm b/simd/x86_64/jcphuff-sse2.asm index 11db4b2..c9ac59f 100644 --- a/simd/x86_64/jcphuff-sse2.asm +++ b/simd/x86_64/jcphuff-sse2.asm @@ -4,16 +4,13 @@ ; ; Copyright (C) 2016, 2018, Matthieu Darbois ; Copyright (C) 2023, Aliaksiej Kandracienka. +; Copyright (C) 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains an SSE2 implementation of data preparation for progressive ; Huffman encoding. See jcphuff.c for more details. @@ -282,12 +279,13 @@ GLOBAL_FUNCTION(jsimd_encode_mcu_AC_first_prepare_sse2) EXTN(jsimd_encode_mcu_AC_first_prepare_sse2): + ENDBR64 push rbp mov rbp, rsp and rsp, byte (-SIZEOF_XMMWORD) ; align to 128 bits sub rsp, SIZEOF_XMMWORD movdqa XMMWORD [rsp], ZERO - collect_args 6 + COLLECT_ARGS 6 movd AL, r13d pxor ZERO, ZERO @@ -381,7 +379,7 @@ EXTN(jsimd_encode_mcu_AC_first_prepare_sse2): REDUCE0 - uncollect_args 6 + UNCOLLECT_ARGS 6 movdqa ZERO, XMMWORD [rsp] mov rsp, rbp pop rbp @@ -445,12 +443,13 @@ EXTN(jsimd_encode_mcu_AC_first_prepare_sse2): GLOBAL_FUNCTION(jsimd_encode_mcu_AC_refine_prepare_sse2) EXTN(jsimd_encode_mcu_AC_refine_prepare_sse2): + ENDBR64 push rbp mov rbp, rsp and rsp, byte (-SIZEOF_XMMWORD) ; align to 128 bits sub rsp, SIZEOF_XMMWORD movdqa XMMWORD [rsp], ZERO - collect_args 6 + COLLECT_ARGS 6 xor SIGN, SIGN xor EOB, EOB @@ -598,7 +597,7 @@ EXTN(jsimd_encode_mcu_AC_refine_prepare_sse2): REDUCE0 mov eax, EOB - uncollect_args 6 + UNCOLLECT_ARGS 6 movdqa ZERO, XMMWORD [rsp] mov rsp, rbp pop rbp diff --git a/simd/x86_64/jcsample-avx2.asm b/simd/x86_64/jcsample-avx2.asm index 589c52b..53afc7d 100644 --- a/simd/x86_64/jcsample-avx2.asm +++ b/simd/x86_64/jcsample-avx2.asm @@ -2,7 +2,7 @@ ; jcsample.asm - downsampling (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -44,9 +40,10 @@ GLOBAL_FUNCTION(jsimd_h2v1_downsample_avx2) EXTN(jsimd_h2v1_downsample_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 6 + COLLECT_ARGS 6 mov ecx, r13d shl rcx, 3 ; imul rcx,DCTSIZE (rcx = output_cols) @@ -177,7 +174,7 @@ EXTN(jsimd_h2v1_downsample_avx2): .return: vzeroupper - uncollect_args 6 + UNCOLLECT_ARGS 6 pop rbp ret @@ -205,9 +202,10 @@ EXTN(jsimd_h2v1_downsample_avx2): GLOBAL_FUNCTION(jsimd_h2v2_downsample_avx2) EXTN(jsimd_h2v2_downsample_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 6 + COLLECT_ARGS 6 mov ecx, r13d shl rcx, 3 ; imul rcx,DCTSIZE (rcx = output_cols) @@ -356,7 +354,7 @@ EXTN(jsimd_h2v2_downsample_avx2): .return: vzeroupper - uncollect_args 6 + UNCOLLECT_ARGS 6 pop rbp ret diff --git a/simd/x86_64/jcsample-sse2.asm b/simd/x86_64/jcsample-sse2.asm index 7a4f1bc..d7ffa93 100644 --- a/simd/x86_64/jcsample-sse2.asm +++ b/simd/x86_64/jcsample-sse2.asm @@ -2,18 +2,14 @@ ; jcsample.asm - downsampling (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -43,9 +39,10 @@ GLOBAL_FUNCTION(jsimd_h2v1_downsample_sse2) EXTN(jsimd_h2v1_downsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 6 + COLLECT_ARGS 6 mov ecx, r13d shl rcx, 3 ; imul rcx,DCTSIZE (rcx = output_cols) @@ -159,7 +156,7 @@ EXTN(jsimd_h2v1_downsample_sse2): jg near .rowloop .return: - uncollect_args 6 + UNCOLLECT_ARGS 6 pop rbp ret @@ -187,9 +184,10 @@ EXTN(jsimd_h2v1_downsample_sse2): GLOBAL_FUNCTION(jsimd_h2v2_downsample_sse2) EXTN(jsimd_h2v2_downsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 6 + COLLECT_ARGS 6 mov ecx, r13d shl rcx, 3 ; imul rcx,DCTSIZE (rcx = output_cols) @@ -319,7 +317,7 @@ EXTN(jsimd_h2v2_downsample_sse2): jg near .rowloop .return: - uncollect_args 6 + UNCOLLECT_ARGS 6 pop rbp ret diff --git a/simd/x86_64/jdcolext-avx2.asm b/simd/x86_64/jdcolext-avx2.asm index 070436c..7b8a084 100644 --- a/simd/x86_64/jdcolext-avx2.asm +++ b/simd/x86_64/jdcolext-avx2.asm @@ -2,7 +2,7 @@ ; jdcolext.asm - colorspace conversion (64-bit AVX2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2012, 2016, D. R. Commander. +; Copyright (C) 2009, 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -11,11 +11,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -42,6 +38,7 @@ GLOBAL_FUNCTION(jsimd_ycc_rgb_convert_avx2) EXTN(jsimd_ycc_rgb_convert_avx2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -49,7 +46,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (WK_NUM * SIZEOF_YMMWORD) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d ; num_cols @@ -486,7 +483,7 @@ EXTN(jsimd_ycc_rgb_convert_avx2): .return: pop rbx vzeroupper - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jdcolext-sse2.asm b/simd/x86_64/jdcolext-sse2.asm index bba3a30..261f74d 100644 --- a/simd/x86_64/jdcolext-sse2.asm +++ b/simd/x86_64/jdcolext-sse2.asm @@ -2,7 +2,7 @@ ; jdcolext.asm - colorspace conversion (64-bit SSE2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2012, 2016, D. R. Commander. +; Copyright (C) 2009, 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -41,6 +37,7 @@ GLOBAL_FUNCTION(jsimd_ycc_rgb_convert_sse2) EXTN(jsimd_ycc_rgb_convert_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -48,7 +45,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 5 + COLLECT_ARGS 5 push rbx mov ecx, r10d ; num_cols @@ -429,7 +426,7 @@ EXTN(jsimd_ycc_rgb_convert_sse2): .return: pop rbx - uncollect_args 5 + UNCOLLECT_ARGS 5 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jdcolor-avx2.asm b/simd/x86_64/jdcolor-avx2.asm index 43de9db..bd5aa00 100644 --- a/simd/x86_64/jdcolor-avx2.asm +++ b/simd/x86_64/jdcolor-avx2.asm @@ -2,18 +2,14 @@ ; jdcolor.asm - colorspace conversion (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_ycc_rgb_convert_avx2) EXTN(jconst_ycc_rgb_convert_avx2): @@ -43,7 +39,7 @@ PW_MF0344_F0285 times 8 dw -F_0_344, F_0_285 PW_ONE times 16 dw 1 PD_ONEHALF times 8 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jdcolor-sse2.asm b/simd/x86_64/jdcolor-sse2.asm index b3f1fec..40343fe 100644 --- a/simd/x86_64/jdcolor-sse2.asm +++ b/simd/x86_64/jdcolor-sse2.asm @@ -2,17 +2,13 @@ ; jdcolor.asm - colorspace conversion (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_ycc_rgb_convert_sse2) EXTN(jconst_ycc_rgb_convert_sse2): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 4 dw -F_0_344, F_0_285 PW_ONE times 8 dw 1 PD_ONEHALF times 4 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jdmerge-avx2.asm b/simd/x86_64/jdmerge-avx2.asm index 9515a17..6a5f1da 100644 --- a/simd/x86_64/jdmerge-avx2.asm +++ b/simd/x86_64/jdmerge-avx2.asm @@ -2,18 +2,14 @@ ; jdmerge.asm - merged upsampling/color conversion (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -32,7 +28,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_merged_upsample_avx2) EXTN(jconst_merged_upsample_avx2): @@ -43,7 +39,7 @@ PW_MF0344_F0285 times 8 dw -F_0_344, F_0_285 PW_ONE times 16 dw 1 PD_ONEHALF times 8 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jdmerge-sse2.asm b/simd/x86_64/jdmerge-sse2.asm index aedccc2..8c269b8 100644 --- a/simd/x86_64/jdmerge-sse2.asm +++ b/simd/x86_64/jdmerge-sse2.asm @@ -2,17 +2,13 @@ ; jdmerge.asm - merged upsampling/color conversion (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" @@ -31,7 +27,7 @@ F_0_228 equ (131072 - F_1_772) ; FIX(2) - FIX(1.77200) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_merged_upsample_sse2) EXTN(jconst_merged_upsample_sse2): @@ -42,7 +38,7 @@ PW_MF0344_F0285 times 4 dw -F_0_344, F_0_285 PW_ONE times 8 dw 1 PD_ONEHALF times 4 dd 1 << (SCALEBITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT diff --git a/simd/x86_64/jdmrgext-avx2.asm b/simd/x86_64/jdmrgext-avx2.asm index 1191645..01826fb 100644 --- a/simd/x86_64/jdmrgext-avx2.asm +++ b/simd/x86_64/jdmrgext-avx2.asm @@ -2,7 +2,7 @@ ; jdmrgext.asm - merged upsampling/color conversion (64-bit AVX2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2012, 2016, D. R. Commander. +; Copyright (C) 2009, 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -11,11 +11,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -42,6 +38,7 @@ GLOBAL_FUNCTION(jsimd_h2v1_merged_upsample_avx2) EXTN(jsimd_h2v1_merged_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -49,7 +46,7 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, SIZEOF_YMMWORD * WK_NUM - collect_args 4 + COLLECT_ARGS 4 push rbx mov ecx, r10d ; col @@ -480,7 +477,7 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): .return: pop rbx vzeroupper - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp @@ -506,9 +503,10 @@ EXTN(jsimd_h2v1_merged_upsample_avx2): GLOBAL_FUNCTION(jsimd_h2v2_merged_upsample_avx2) EXTN(jsimd_h2v2_merged_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 push rbx mov eax, r10d @@ -587,7 +585,7 @@ EXTN(jsimd_h2v2_merged_upsample_avx2): add rsp, SIZEOF_JSAMPARRAY*4 pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret diff --git a/simd/x86_64/jdmrgext-sse2.asm b/simd/x86_64/jdmrgext-sse2.asm index 8988dd0..abd22e2 100644 --- a/simd/x86_64/jdmrgext-sse2.asm +++ b/simd/x86_64/jdmrgext-sse2.asm @@ -2,7 +2,7 @@ ; jdmrgext.asm - merged upsampling/color conversion (64-bit SSE2) ; ; Copyright 2009, 2012 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2012, 2016, D. R. Commander. +; Copyright (C) 2009, 2012, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jcolsamp.inc" @@ -41,6 +37,7 @@ GLOBAL_FUNCTION(jsimd_h2v1_merged_upsample_sse2) EXTN(jsimd_h2v1_merged_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -48,7 +45,7 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 4 + COLLECT_ARGS 4 push rbx mov ecx, r10d ; col @@ -422,7 +419,7 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): .return: pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp @@ -448,9 +445,10 @@ EXTN(jsimd_h2v1_merged_upsample_sse2): GLOBAL_FUNCTION(jsimd_h2v2_merged_upsample_sse2) EXTN(jsimd_h2v2_merged_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 push rbx mov eax, r10d @@ -529,7 +527,7 @@ EXTN(jsimd_h2v2_merged_upsample_sse2): add rsp, SIZEOF_JSAMPARRAY*4 pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret diff --git a/simd/x86_64/jdsample-avx2.asm b/simd/x86_64/jdsample-avx2.asm index c6ddbb5..6ae4cf8 100644 --- a/simd/x86_64/jdsample-avx2.asm +++ b/simd/x86_64/jdsample-avx2.asm @@ -2,7 +2,7 @@ ; jdsample.asm - upsampling (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2015, Intel Corporation. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. @@ -11,18 +11,14 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fancy_upsample_avx2) EXTN(jconst_fancy_upsample_avx2): @@ -33,7 +29,7 @@ PW_THREE times 16 dw 3 PW_SEVEN times 16 dw 7 PW_EIGHT times 16 dw 8 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -62,10 +58,11 @@ PW_EIGHT times 16 dw 8 GLOBAL_FUNCTION(jsimd_h2v1_fancy_upsample_avx2) EXTN(jsimd_h2v1_fancy_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp - push_xmm 3 - collect_args 4 + PUSH_XMM 3 + COLLECT_ARGS 4 mov eax, r11d ; colctr test rax, rax @@ -186,8 +183,8 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): .return: vzeroupper - uncollect_args 4 - pop_xmm 3 + UNCOLLECT_ARGS 4 + POP_XMM 3 pop rbp ret @@ -215,6 +212,7 @@ EXTN(jsimd_h2v1_fancy_upsample_avx2): GLOBAL_FUNCTION(jsimd_h2v2_fancy_upsample_avx2) EXTN(jsimd_h2v2_fancy_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -222,8 +220,8 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, (SIZEOF_YMMWORD * WK_NUM) - push_xmm 3 - collect_args 4 + PUSH_XMM 3 + COLLECT_ARGS 4 push rbx mov eax, r11d ; colctr @@ -498,8 +496,8 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): .return: pop rbx vzeroupper - uncollect_args 4 - pop_xmm 3 + UNCOLLECT_ARGS 4 + POP_XMM 3 lea rsp, [rbp-8] pop r15 pop rbp @@ -524,9 +522,10 @@ EXTN(jsimd_h2v2_fancy_upsample_avx2): GLOBAL_FUNCTION(jsimd_h2v1_upsample_avx2) EXTN(jsimd_h2v1_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 mov edx, r11d add rdx, byte (SIZEOF_YMMWORD-1) @@ -589,7 +588,7 @@ EXTN(jsimd_h2v1_upsample_avx2): .return: vzeroupper - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret @@ -612,9 +611,10 @@ EXTN(jsimd_h2v1_upsample_avx2): GLOBAL_FUNCTION(jsimd_h2v2_upsample_avx2) EXTN(jsimd_h2v2_upsample_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 push rbx mov edx, r11d @@ -685,7 +685,7 @@ EXTN(jsimd_h2v2_upsample_avx2): .return: pop rbx vzeroupper - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret diff --git a/simd/x86_64/jdsample-sse2.asm b/simd/x86_64/jdsample-sse2.asm index 24cd389..54c560f 100644 --- a/simd/x86_64/jdsample-sse2.asm +++ b/simd/x86_64/jdsample-sse2.asm @@ -2,7 +2,7 @@ ; jdsample.asm - upsampling (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,18 +10,14 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fancy_upsample_sse2) EXTN(jconst_fancy_upsample_sse2): @@ -32,7 +28,7 @@ PW_THREE times 8 dw 3 PW_SEVEN times 8 dw 7 PW_EIGHT times 8 dw 8 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -61,9 +57,10 @@ PW_EIGHT times 8 dw 8 GLOBAL_FUNCTION(jsimd_h2v1_fancy_upsample_sse2) EXTN(jsimd_h2v1_fancy_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 mov eax, r11d ; colctr test rax, rax @@ -174,7 +171,7 @@ EXTN(jsimd_h2v1_fancy_upsample_sse2): jg near .rowloop .return: - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret @@ -202,6 +199,7 @@ EXTN(jsimd_h2v1_fancy_upsample_sse2): GLOBAL_FUNCTION(jsimd_h2v2_fancy_upsample_sse2) EXTN(jsimd_h2v2_fancy_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -209,7 +207,7 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 4 + COLLECT_ARGS 4 push rbx mov eax, r11d ; colctr @@ -472,7 +470,7 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): .return: pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp @@ -497,9 +495,10 @@ EXTN(jsimd_h2v2_fancy_upsample_sse2): GLOBAL_FUNCTION(jsimd_h2v1_upsample_sse2) EXTN(jsimd_h2v1_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 mov edx, r11d add rdx, byte (2*SIZEOF_XMMWORD)-1 @@ -560,7 +559,7 @@ EXTN(jsimd_h2v1_upsample_sse2): jg short .rowloop .return: - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret @@ -583,9 +582,10 @@ EXTN(jsimd_h2v1_upsample_sse2): GLOBAL_FUNCTION(jsimd_h2v2_upsample_sse2) EXTN(jsimd_h2v2_upsample_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 push rbx mov edx, r11d @@ -654,7 +654,7 @@ EXTN(jsimd_h2v2_upsample_sse2): .return: pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret diff --git a/simd/x86_64/jfdctflt-sse.asm b/simd/x86_64/jfdctflt-sse.asm index 3595496..58a1f55 100644 --- a/simd/x86_64/jfdctflt-sse.asm +++ b/simd/x86_64/jfdctflt-sse.asm @@ -2,18 +2,14 @@ ; jfdctflt.asm - floating-point FDCT (64-bit SSE) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the forward DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -35,7 +31,7 @@ ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_float_sse) EXTN(jconst_fdct_float_sse): @@ -45,7 +41,7 @@ PD_0_707 times 4 dd 0.707106781186547524400844 PD_0_541 times 4 dd 0.541196100146196984399723 PD_1_306 times 4 dd 1.306562964876376527856643 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -66,6 +62,7 @@ PD_1_306 times 4 dd 1.306562964876376527856643 GLOBAL_FUNCTION(jsimd_fdct_float_sse) EXTN(jsimd_fdct_float_sse): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -73,7 +70,7 @@ EXTN(jsimd_fdct_float_sse): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 1 + COLLECT_ARGS 1 ; ---- Pass 1: process rows. @@ -345,7 +342,7 @@ EXTN(jsimd_fdct_float_sse): dec rcx jnz near .columnloop - uncollect_args 1 + UNCOLLECT_ARGS 1 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jfdctfst-sse2.asm b/simd/x86_64/jfdctfst-sse2.asm index d33c58a..3b92d4e 100644 --- a/simd/x86_64/jfdctfst-sse2.asm +++ b/simd/x86_64/jfdctfst-sse2.asm @@ -2,18 +2,14 @@ ; jfdctfst.asm - fast integer FDCT (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the forward DCT (Discrete Cosine Transform). The following code is @@ -50,7 +46,7 @@ F_1_306 equ DESCALE(1402911301, 30 - CONST_BITS) ; FIX(1.306562965) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_ifast_sse2) EXTN(jconst_fdct_ifast_sse2): @@ -60,7 +56,7 @@ PW_F0382 times 8 dw F_0_382 << CONST_SHIFT PW_F0541 times 8 dw F_0_541 << CONST_SHIFT PW_F1306 times 8 dw F_1_306 << CONST_SHIFT - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -81,6 +77,7 @@ PW_F1306 times 8 dw F_1_306 << CONST_SHIFT GLOBAL_FUNCTION(jsimd_fdct_ifast_sse2) EXTN(jsimd_fdct_ifast_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -88,7 +85,7 @@ EXTN(jsimd_fdct_ifast_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 1 + COLLECT_ARGS 1 ; ---- Pass 1: process rows. @@ -379,7 +376,7 @@ EXTN(jsimd_fdct_ifast_sse2): movdqa XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)], xmm6 movdqa XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)], xmm2 - uncollect_args 1 + UNCOLLECT_ARGS 1 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jfdctint-avx2.asm b/simd/x86_64/jfdctint-avx2.asm index d0afe5e..0c45286 100644 --- a/simd/x86_64/jfdctint-avx2.asm +++ b/simd/x86_64/jfdctint-avx2.asm @@ -2,17 +2,13 @@ ; jfdctint.asm - accurate integer FDCT (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2018, 2020, 2024, D. R. Commander. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; forward DCT (Discrete Cosine Transform). The following code is based @@ -65,7 +61,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %1-%4: Input/output registers ; %5-%8: Temp registers -%macro dotranspose 8 +%macro DOTRANSPOSE 8 ; %1=(00 01 02 03 04 05 06 07 40 41 42 43 44 45 46 47) ; %2=(10 11 12 13 14 15 16 17 50 51 52 53 54 55 56 57) ; %3=(20 21 22 23 24 25 26 27 60 61 62 63 64 65 66 67) @@ -108,7 +104,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %5-%8: Temp registers ; %9: Pass (1 or 2) -%macro dodct 9 +%macro DODCT 9 vpsubw %5, %1, %4 ; %5=data1_0-data6_7=tmp6_7 vpaddw %6, %1, %4 ; %6=data1_0+data6_7=tmp1_0 vpaddw %7, %2, %3 ; %7=data3_2+data4_5=tmp3_2 @@ -223,7 +219,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_islow_avx2) EXTN(jconst_fdct_islow_avx2): @@ -242,7 +238,7 @@ PW_DESCALE_P2X times 16 dw 1 << (PASS1_BITS - 1) PW_1_NEG1 times 8 dw 1 times 8 dw -1 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -260,9 +256,10 @@ PW_1_NEG1 times 8 dw 1 GLOBAL_FUNCTION(jsimd_fdct_islow_avx2) EXTN(jsimd_fdct_islow_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 1 + COLLECT_ARGS 1 ; ---- Pass 1: process rows. @@ -284,9 +281,9 @@ EXTN(jsimd_fdct_islow_avx2): ; ymm2=(20 21 22 23 24 25 26 27 60 61 62 63 64 65 66 67) ; ymm3=(30 31 32 33 34 35 36 37 70 71 72 73 74 75 76 77) - dotranspose ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 - dodct ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, 1 + DODCT ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, 1 ; ymm0=data0_4, ymm1=data3_1, ymm2=data2_6, ymm3=data7_5 ; ---- Pass 2: process columns. @@ -294,9 +291,9 @@ EXTN(jsimd_fdct_islow_avx2): vperm2i128 ymm4, ymm1, ymm3, 0x20 ; ymm4=data3_7 vperm2i128 ymm1, ymm1, ymm3, 0x31 ; ymm1=data1_5 - dotranspose ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 - dodct ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, 2 + DODCT ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, 2 ; ymm0=data0_4, ymm1=data3_1, ymm2=data2_6, ymm4=data7_5 vperm2i128 ymm3, ymm0, ymm1, 0x30 ; ymm3=data0_1 @@ -310,7 +307,7 @@ EXTN(jsimd_fdct_islow_avx2): vmovdqu YMMWORD [YMMBLOCK(6,0,r10,SIZEOF_DCTELEM)], ymm7 vzeroupper - uncollect_args 1 + UNCOLLECT_ARGS 1 pop rbp ret diff --git a/simd/x86_64/jfdctint-sse2.asm b/simd/x86_64/jfdctint-sse2.asm index 024ce90..3a6be02 100644 --- a/simd/x86_64/jfdctint-sse2.asm +++ b/simd/x86_64/jfdctint-sse2.asm @@ -2,18 +2,14 @@ ; jfdctint.asm - accurate integer FDCT (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2020, 2024, D. R. Commander. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; forward DCT (Discrete Cosine Transform). The following code is based @@ -64,7 +60,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_fdct_islow_sse2) EXTN(jconst_fdct_islow_sse2): @@ -81,7 +77,7 @@ PD_DESCALE_P1 times 4 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 4 dd 1 << (DESCALE_P2 - 1) PW_DESCALE_P2X times 8 dw 1 << (PASS1_BITS - 1) - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -102,6 +98,7 @@ PW_DESCALE_P2X times 8 dw 1 << (PASS1_BITS - 1) GLOBAL_FUNCTION(jsimd_fdct_islow_sse2) EXTN(jsimd_fdct_islow_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -109,7 +106,7 @@ EXTN(jsimd_fdct_islow_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 1 + COLLECT_ARGS 1 ; ---- Pass 1: process rows. @@ -609,7 +606,7 @@ EXTN(jsimd_fdct_islow_sse2): movdqa XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)], xmm1 movdqa XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)], xmm3 - uncollect_args 1 + UNCOLLECT_ARGS 1 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jidctflt-sse2.asm b/simd/x86_64/jidctflt-sse2.asm index 952fbe3..1443734 100644 --- a/simd/x86_64/jidctflt-sse2.asm +++ b/simd/x86_64/jidctflt-sse2.asm @@ -2,7 +2,7 @@ ; jidctflt.asm - floating-point IDCT (64-bit SSE & SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a floating-point implementation of the inverse DCT ; (Discrete Cosine Transform). The following code is based directly on @@ -25,18 +21,18 @@ ; -------------------------------------------------------------------------- -%macro unpcklps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) +%macro UNPCKLPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(0 1 4 5) shufps %1, %2, 0x44 %endmacro -%macro unpckhps2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) +%macro UNPCKHPS2 2 ; %1=(0 1 2 3) / %2=(4 5 6 7) => %1=(2 3 6 7) shufps %1, %2, 0xEE %endmacro ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_float_sse2) EXTN(jconst_idct_float_sse2): @@ -48,7 +44,7 @@ PD_M2_613 times 4 dd -2.613125929752753055713286 PD_RNDINT_MAGIC times 4 dd 100663296.0 ; (float)(0x00C00000 << 3) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -76,6 +72,7 @@ PB_CENTERJSAMP times 16 db CENTERJSAMPLE GLOBAL_FUNCTION(jsimd_idct_float_sse2) EXTN(jsimd_idct_float_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -83,7 +80,7 @@ EXTN(jsimd_idct_float_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp lea rsp, [workspace] - collect_args 4 + COLLECT_ARGS 4 push rbx ; ---- Pass 1: process columns from input, store into work array. @@ -280,11 +277,11 @@ EXTN(jsimd_idct_float_sse2): unpckhps xmm4, xmm0 ; xmm4=(42 52 43 53) movaps xmm3, xmm6 ; transpose coefficients(phase 2) - unpcklps2 xmm6, xmm7 ; xmm6=(00 10 20 30) - unpckhps2 xmm3, xmm7 ; xmm3=(01 11 21 31) + UNPCKLPS2 xmm6, xmm7 ; xmm6=(00 10 20 30) + UNPCKHPS2 xmm3, xmm7 ; xmm3=(01 11 21 31) movaps xmm0, xmm1 ; transpose coefficients(phase 2) - unpcklps2 xmm1, xmm2 ; xmm1=(02 12 22 32) - unpckhps2 xmm0, xmm2 ; xmm0=(03 13 23 33) + UNPCKLPS2 xmm1, xmm2 ; xmm1=(02 12 22 32) + UNPCKHPS2 xmm0, xmm2 ; xmm0=(03 13 23 33) movaps xmm7, XMMWORD [wk(0)] ; xmm7=(60 70 61 71) movaps xmm2, XMMWORD [wk(1)] ; xmm2=(62 72 63 73) @@ -295,11 +292,11 @@ EXTN(jsimd_idct_float_sse2): movaps XMMWORD [XMMBLOCK(3,0,rdi,SIZEOF_FAST_FLOAT)], xmm0 movaps xmm6, xmm5 ; transpose coefficients(phase 2) - unpcklps2 xmm5, xmm7 ; xmm5=(40 50 60 70) - unpckhps2 xmm6, xmm7 ; xmm6=(41 51 61 71) + UNPCKLPS2 xmm5, xmm7 ; xmm5=(40 50 60 70) + UNPCKHPS2 xmm6, xmm7 ; xmm6=(41 51 61 71) movaps xmm3, xmm4 ; transpose coefficients(phase 2) - unpcklps2 xmm4, xmm2 ; xmm4=(42 52 62 72) - unpckhps2 xmm3, xmm2 ; xmm3=(43 53 63 73) + UNPCKLPS2 xmm4, xmm2 ; xmm4=(42 52 62 72) + UNPCKHPS2 xmm3, xmm2 ; xmm3=(43 53 63 73) movaps XMMWORD [XMMBLOCK(0,1,rdi,SIZEOF_FAST_FLOAT)], xmm5 movaps XMMWORD [XMMBLOCK(1,1,rdi,SIZEOF_FAST_FLOAT)], xmm6 @@ -470,7 +467,7 @@ EXTN(jsimd_idct_float_sse2): jnz near .rowloop pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jidctfst-sse2.asm b/simd/x86_64/jidctfst-sse2.asm index a3da8d8..cffabb8 100644 --- a/simd/x86_64/jidctfst-sse2.asm +++ b/simd/x86_64/jidctfst-sse2.asm @@ -2,7 +2,7 @@ ; jidctfst.asm - fast integer IDCT (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a fast, not so accurate integer implementation of ; the inverse DCT (Discrete Cosine Transform). The following code is @@ -58,7 +54,7 @@ F_1_613 equ (F_2_613 - (1 << CONST_BITS)) ; FIX(2.613125930) - FIX(1) %define PRE_MULTIPLY_SCALE_BITS 2 %define CONST_SHIFT (16 - PRE_MULTIPLY_SCALE_BITS - CONST_BITS) - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_ifast_sse2) EXTN(jconst_idct_ifast_sse2): @@ -69,7 +65,7 @@ PW_MF1613 times 8 dw -F_1_613 << CONST_SHIFT PW_F1082 times 8 dw F_1_082 << CONST_SHIFT PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -95,6 +91,7 @@ PB_CENTERJSAMP times 16 db CENTERJSAMPLE GLOBAL_FUNCTION(jsimd_idct_ifast_sse2) EXTN(jsimd_idct_ifast_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -102,7 +99,7 @@ EXTN(jsimd_idct_ifast_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 4 + COLLECT_ARGS 4 ; ---- Pass 1: process columns from input. @@ -478,7 +475,7 @@ EXTN(jsimd_idct_ifast_sse2): movq XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6 movq XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm2 - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jidctint-avx2.asm b/simd/x86_64/jidctint-avx2.asm index 528da01..be3b468 100644 --- a/simd/x86_64/jidctint-avx2.asm +++ b/simd/x86_64/jidctint-avx2.asm @@ -2,18 +2,14 @@ ; jidctint.asm - accurate integer IDCT (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2018, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2018, 2020, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; inverse DCT (Discrete Cosine Transform). The following code is based @@ -66,7 +62,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %1-%4: Input/output registers ; %5-%8: Temp registers -%macro dotranspose 8 +%macro DOTRANSPOSE 8 ; %5=(00 10 20 30 40 50 60 70 01 11 21 31 41 51 61 71) ; %6=(03 13 23 33 43 53 63 73 02 12 22 32 42 52 62 72) ; %7=(04 14 24 34 44 54 64 74 05 15 25 35 45 55 65 75) @@ -119,7 +115,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; %5-%12: Temp registers ; %9: Pass (1 or 2) -%macro dodct 13 +%macro DODCT 13 ; -- Even part ; (Original) @@ -241,7 +237,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_islow_avx2) EXTN(jconst_idct_islow_avx2): @@ -260,7 +256,7 @@ PB_CENTERJSAMP times 32 db CENTERJSAMPLE PW_1_NEG1 times 8 dw 1 times 8 dw -1 - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -282,10 +278,11 @@ PW_1_NEG1 times 8 dw 1 GLOBAL_FUNCTION(jsimd_idct_islow_avx2) EXTN(jsimd_idct_islow_avx2): + ENDBR64 push rbp mov rbp, rsp ; rbp = aligned rbp - push_xmm 4 - collect_args 4 + PUSH_XMM 4 + COLLECT_ARGS 4 ; ---- Pass 1: process columns. @@ -342,10 +339,10 @@ EXTN(jsimd_idct_islow_avx2): vperm2i128 ymm2, ymm5, ymm7, 0x20 ; ymm2=in2_6 vperm2i128 ymm3, ymm7, ymm6, 0x31 ; ymm3=in7_5 - dodct ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, ymm8, ymm9, ymm10, ymm11, 1 + DODCT ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7, ymm8, ymm9, ymm10, ymm11, 1 ; ymm0=data0_1, ymm1=data3_2, ymm2=data4_5, ymm3=data7_6 - dotranspose ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7 ; ymm0=data0_4, ymm1=data1_5, ymm2=data2_6, ymm3=data3_7 .column_end: @@ -362,10 +359,10 @@ EXTN(jsimd_idct_islow_avx2): vperm2i128 ymm4, ymm3, ymm1, 0x31 ; ymm3=in7_5 vperm2i128 ymm1, ymm3, ymm1, 0x20 ; ymm1=in3_1 - dodct ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, ymm8, ymm9, ymm10, ymm11, 2 + DODCT ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7, ymm8, ymm9, ymm10, ymm11, 2 ; ymm0=data0_1, ymm1=data3_2, ymm2=data4_5, ymm4=data7_6 - dotranspose ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 + DOTRANSPOSE ymm0, ymm1, ymm2, ymm4, ymm3, ymm5, ymm6, ymm7 ; ymm0=data0_4, ymm1=data1_5, ymm2=data2_6, ymm4=data3_7 vpacksswb ymm0, ymm0, ymm1 ; ymm0=data01_45 @@ -407,8 +404,8 @@ EXTN(jsimd_idct_islow_avx2): movq XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm6 movq XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm7 - uncollect_args 4 - pop_xmm 4 + UNCOLLECT_ARGS 4 + POP_XMM 4 pop rbp ret diff --git a/simd/x86_64/jidctint-sse2.asm b/simd/x86_64/jidctint-sse2.asm index 92f633e..b186871 100644 --- a/simd/x86_64/jidctint-sse2.asm +++ b/simd/x86_64/jidctint-sse2.asm @@ -2,7 +2,7 @@ ; jidctint.asm - accurate integer IDCT (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2020, D. R. Commander. +; Copyright (C) 2009, 2016, 2020, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains a slower but more accurate integer implementation of the ; inverse DCT (Discrete Cosine Transform). The following code is based @@ -65,7 +61,7 @@ F_3_072 equ DESCALE(3299298341, 30 - CONST_BITS) ; FIX(3.072711026) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_islow_sse2) EXTN(jconst_idct_islow_sse2): @@ -82,7 +78,7 @@ PD_DESCALE_P1 times 4 dd 1 << (DESCALE_P1 - 1) PD_DESCALE_P2 times 4 dd 1 << (DESCALE_P2 - 1) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -108,6 +104,7 @@ PB_CENTERJSAMP times 16 db CENTERJSAMPLE GLOBAL_FUNCTION(jsimd_idct_islow_sse2) EXTN(jsimd_idct_islow_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -115,7 +112,7 @@ EXTN(jsimd_idct_islow_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, (SIZEOF_XMMWORD * WK_NUM) - collect_args 4 + COLLECT_ARGS 4 ; ---- Pass 1: process columns from input. @@ -835,7 +832,7 @@ EXTN(jsimd_idct_islow_sse2): movq XMM_MMWORD [rdx+rax*SIZEOF_JSAMPLE], xmm2 movq XMM_MMWORD [rsi+rax*SIZEOF_JSAMPLE], xmm5 - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp diff --git a/simd/x86_64/jidctred-sse2.asm b/simd/x86_64/jidctred-sse2.asm index 1ec500c..6fb7095 100644 --- a/simd/x86_64/jidctred-sse2.asm +++ b/simd/x86_64/jidctred-sse2.asm @@ -2,7 +2,7 @@ ; jidctred.asm - reduced-size IDCT (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; Copyright (C) 2023, Aliaksiej Kandracienka. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. ; ; This file contains inverse-DCT routines that produce reduced-size ; output: either 4x4 or 2x2 pixels from an 8x8 DCT block. @@ -71,7 +67,7 @@ F_3_624 equ DESCALE(3891787747, 30 - CONST_BITS) ; FIX(3.624509785) ; -------------------------------------------------------------------------- SECTION SEG_CONST - alignz 32 + ALIGNZ 32 GLOBAL_DATA(jconst_idct_red_sse2) EXTN(jconst_idct_red_sse2): @@ -89,7 +85,7 @@ PD_DESCALE_P1_2 times 4 dd 1 << (DESCALE_P1_2 - 1) PD_DESCALE_P2_2 times 4 dd 1 << (DESCALE_P2_2 - 1) PB_CENTERJSAMP times 16 db CENTERJSAMPLE - alignz 32 + ALIGNZ 32 ; -------------------------------------------------------------------------- SECTION SEG_TEXT @@ -116,6 +112,7 @@ PB_CENTERJSAMP times 16 db CENTERJSAMPLE GLOBAL_FUNCTION(jsimd_idct_4x4_sse2) EXTN(jsimd_idct_4x4_sse2): + ENDBR64 push rbp mov rbp, rsp push r15 @@ -123,7 +120,7 @@ EXTN(jsimd_idct_4x4_sse2): ; Allocate stack space for wk array. r15 is used to access it. mov r15, rsp sub rsp, byte (SIZEOF_XMMWORD * WK_NUM) - collect_args 4 + COLLECT_ARGS 4 ; ---- Pass 1: process columns from input. @@ -388,7 +385,7 @@ EXTN(jsimd_idct_4x4_sse2): movd XMM_DWORD [rdx+rax*SIZEOF_JSAMPLE], xmm1 movd XMM_DWORD [rsi+rax*SIZEOF_JSAMPLE], xmm3 - uncollect_args 4 + UNCOLLECT_ARGS 4 lea rsp, [rbp-8] pop r15 pop rbp @@ -413,9 +410,10 @@ EXTN(jsimd_idct_4x4_sse2): GLOBAL_FUNCTION(jsimd_idct_2x2_sse2) EXTN(jsimd_idct_2x2_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 4 + COLLECT_ARGS 4 push rbx ; ---- Pass 1: process columns from input. @@ -563,7 +561,7 @@ EXTN(jsimd_idct_2x2_sse2): mov word [rsi+rax*SIZEOF_JSAMPLE], cx pop rbx - uncollect_args 4 + UNCOLLECT_ARGS 4 pop rbp ret diff --git a/simd/x86_64/jquantf-sse2.asm b/simd/x86_64/jquantf-sse2.asm index 232bbb2..6476333 100644 --- a/simd/x86_64/jquantf-sse2.asm +++ b/simd/x86_64/jquantf-sse2.asm @@ -2,18 +2,14 @@ ; jquantf.asm - sample data conversion and quantization (64-bit SSE & SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -37,9 +33,10 @@ GLOBAL_FUNCTION(jsimd_convsamp_float_sse2) EXTN(jsimd_convsamp_float_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 push rbx pcmpeqw xmm7, xmm7 @@ -88,7 +85,7 @@ EXTN(jsimd_convsamp_float_sse2): jnz short .convloop pop rbx - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret @@ -109,9 +106,10 @@ EXTN(jsimd_convsamp_float_sse2): GLOBAL_FUNCTION(jsimd_quantize_float_sse2) EXTN(jsimd_quantize_float_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 mov rsi, r12 mov rdx, r11 @@ -144,7 +142,7 @@ EXTN(jsimd_quantize_float_sse2): dec rax jnz short .quantloop - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret diff --git a/simd/x86_64/jquanti-avx2.asm b/simd/x86_64/jquanti-avx2.asm index 66104d7..7e126e8 100644 --- a/simd/x86_64/jquanti-avx2.asm +++ b/simd/x86_64/jquanti-avx2.asm @@ -2,7 +2,7 @@ ; jquanti.asm - sample data conversion and quantization (64-bit AVX2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, 2018, D. R. Commander. +; Copyright (C) 2009, 2016, 2018, 2024, D. R. Commander. ; Copyright (C) 2016, Matthieu Darbois. ; Copyright (C) 2018, Matthias Räncker. ; @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -38,9 +34,10 @@ GLOBAL_FUNCTION(jsimd_convsamp_avx2) EXTN(jsimd_convsamp_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 mov eax, r11d @@ -83,7 +80,7 @@ EXTN(jsimd_convsamp_avx2): vmovdqu YMMWORD [YMMBLOCK(6,0,r12,SIZEOF_DCTELEM)], ymm3 vzeroupper - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret @@ -92,8 +89,8 @@ EXTN(jsimd_convsamp_avx2): ; Quantize/descale the coefficients, and store into coef_block ; ; This implementation is based on an algorithm described in -; "How to optimize for the Pentium family of microprocessors" -; (http://www.agner.org/assem/). +; "Optimizing subroutines in assembly language: +; An optimization guide for x86 platforms" (https://agner.org/optimize). ; ; GLOBAL(void) ; jsimd_quantize_avx2(JCOEFPTR coef_block, DCTELEM *divisors, @@ -115,9 +112,10 @@ EXTN(jsimd_convsamp_avx2): GLOBAL_FUNCTION(jsimd_quantize_avx2) EXTN(jsimd_quantize_avx2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 vmovdqu ymm4, [YMMBLOCK(0,0,r12,SIZEOF_DCTELEM)] vmovdqu ymm5, [YMMBLOCK(2,0,r12,SIZEOF_DCTELEM)] @@ -152,7 +150,7 @@ EXTN(jsimd_quantize_avx2): vmovdqu [YMMBLOCK(6,0,r10,SIZEOF_DCTELEM)], ymm3 vzeroupper - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret diff --git a/simd/x86_64/jquanti-sse2.asm b/simd/x86_64/jquanti-sse2.asm index 11e9f4c..284b9fe 100644 --- a/simd/x86_64/jquanti-sse2.asm +++ b/simd/x86_64/jquanti-sse2.asm @@ -2,18 +2,14 @@ ; jquanti.asm - sample data conversion and quantization (64-bit SSE2) ; ; Copyright 2009 Pierre Ossman for Cendio AB -; Copyright (C) 2009, 2016, D. R. Commander. +; Copyright (C) 2009, 2016, 2024, D. R. Commander. ; Copyright (C) 2018, Matthias Räncker. ; ; Based on the x86 SIMD extension for IJG JPEG library ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" %include "jdct.inc" @@ -37,9 +33,10 @@ GLOBAL_FUNCTION(jsimd_convsamp_sse2) EXTN(jsimd_convsamp_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 push rbx pxor xmm6, xmm6 ; xmm6=(all 0's) @@ -83,7 +80,7 @@ EXTN(jsimd_convsamp_sse2): jnz short .convloop pop rbx - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret @@ -92,8 +89,8 @@ EXTN(jsimd_convsamp_sse2): ; Quantize/descale the coefficients, and store into coef_block ; ; This implementation is based on an algorithm described in -; "How to optimize for the Pentium family of microprocessors" -; (http://www.agner.org/assem/). +; "Optimizing subroutines in assembly language: +; An optimization guide for x86 platforms" (https://agner.org/optimize). ; ; GLOBAL(void) ; jsimd_quantize_sse2(JCOEFPTR coef_block, DCTELEM *divisors, @@ -115,9 +112,10 @@ EXTN(jsimd_convsamp_sse2): GLOBAL_FUNCTION(jsimd_quantize_sse2) EXTN(jsimd_quantize_sse2): + ENDBR64 push rbp mov rbp, rsp - collect_args 3 + COLLECT_ARGS 3 mov rsi, r12 mov rdx, r11 @@ -177,7 +175,7 @@ EXTN(jsimd_quantize_sse2): dec rax jnz near .quantloop - uncollect_args 3 + UNCOLLECT_ARGS 3 pop rbp ret diff --git a/simd/x86_64/jsimdcpu.asm b/simd/x86_64/jsimdcpu.asm index 251bc4c..b72f3b0 100644 --- a/simd/x86_64/jsimdcpu.asm +++ b/simd/x86_64/jsimdcpu.asm @@ -10,11 +10,7 @@ ; Copyright (C) 1999-2006, MIYASAKA Masaru. ; For conditions of distribution and use, see copyright notice in jsimdext.inc ; -; This file should be assembled with NASM (Netwide Assembler), -; can *not* be assembled with Microsoft's MASM or any compatible -; assembler (including Borland's Turbo Assembler). -; NASM is available from http://nasm.sourceforge.net/ or -; http://sourceforge.net/project/showfiles.php?group_id=6208 +; This file should be assembled with NASM (Netwide Assembler) or Yasm. %include "jsimdext.inc" diff --git a/testimages/big_building16.ppm b/testimages/big_building16.ppm deleted file mode 100644 index b0b8439..0000000 Binary files a/testimages/big_building16.ppm and /dev/null differ diff --git a/testimages/big_tree8.bmp b/testimages/big_tree8.bmp deleted file mode 100644 index b1dfc45..0000000 Binary files a/testimages/big_tree8.bmp and /dev/null differ diff --git a/testimages/big_tree8.txt b/testimages/big_tree8.txt deleted file mode 100644 index 2f0be72..0000000 --- a/testimages/big_tree8.txt +++ /dev/null @@ -1,25 +0,0 @@ -libjpeg-turbo note: This image was extracted from the 8-bit big_tree image. -The original can be downloaded at the link below. - -The New Image Compression Test Set - Jan 2008 -http://www.imagecompression.info/test_images - -The images historically used for compression research (lena, barbra, pepper etc...) have outlived their useful life and its about time they become a part of history only. They are too small, come from data sources too old and are available in only 8-bit precision. - -These images have been carefully selected to aid in image compression algorithm research and evaluation. These are photographic images chosen to come from a wide variety of sources and each one picked to stress different aspects of algorithms. Images are available in 8-bit, 16-bit and 16-bit linear variations, RGB and gray. - -Images are available without any prohibitive copyright restrictions. - -These images are (c) there respective owners. You are granted full redistribution and publication rights on these images provided: - -1. The origin of the pictures must not be misrepresented; you must not claim that you took the original pictures. If you use, publish or redistribute them, an acknowledgment would be appreciated but is not required. -2. Altered versions must be plainly marked as such, and must not be misinterpreted as being the originals. -3. No payment is required for distribution this material, it must be available freely under the conditions stated here. That is, it is prohibited to sell the material. -4. This notice may not be removed or altered from any distribution. - -Acknowledgments: A lot of people contributed a lot of time and effort in making this test set possible. Thanks to everyone who voiced their opinion in any of the discussions online. Thanks to Axel Becker, Thomas Richter and Niels Fröhling for their extensive help in picking images, running all the various tests etc... Thanks to Pete Fraser, Tony Story, Wayne J. Cosshall, David Coffin, Bruce Lindbloom and raw.fotosite.pl for the images which make up this set. - -Sachin Garg [India] -sachingarg@c10n.info - -www.sachingarg.com | www.c10n.info | www.imagecompression.info diff --git a/testimages/monkey16.ppm b/testimages/monkey16.ppm new file mode 100644 index 0000000..cfcd1b9 Binary files /dev/null and b/testimages/monkey16.ppm differ diff --git a/testimages/shira_bird8.bmp b/testimages/shira_bird8.bmp new file mode 100644 index 0000000..81f4e2d Binary files /dev/null and b/testimages/shira_bird8.bmp differ diff --git a/testimages/test2.icc b/testimages/test2.icc deleted file mode 100644 index 73f1b5a..0000000 Binary files a/testimages/test2.icc and /dev/null differ diff --git a/testimages/test2.icc.txt b/testimages/test2.icc.txt deleted file mode 100644 index 57fc52f..0000000 --- a/testimages/test2.icc.txt +++ /dev/null @@ -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. diff --git a/testimages/test3.icc b/testimages/test3.icc new file mode 100644 index 0000000..d0e7930 Binary files /dev/null and b/testimages/test3.icc differ diff --git a/testimages/test3.icc.txt b/testimages/test3.icc.txt new file mode 100644 index 0000000..57fc52f --- /dev/null +++ b/testimages/test3.icc.txt @@ -0,0 +1,20 @@ +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. diff --git a/tjbench.c b/tjbench.c index e053dc6..b91c36e 100644 --- a/tjbench.c +++ b/tjbench.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2019, 2021-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2009-2019, 2021-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -37,6 +37,9 @@ #include #include #include +#if !defined(_MSC_VER) || _MSC_VER > 1600 +#include +#endif #include #include "./tjutil.h" #include "./turbojpeg.h" @@ -48,8 +51,8 @@ } #define THROW_UNIX(m) THROW(m, strerror(errno)) -char tjErrorStr[JMSG_LENGTH_MAX] = "\0"; -int tjErrorLine = -1, tjErrorCode = -1; +static char tjErrorStr[JMSG_LENGTH_MAX] = "\0"; +static int tjErrorLine = -1, tjErrorCode = -1; #define THROW_TJG() { \ printf("ERROR in line %d\n%s\n", __LINE__, tj3GetErrorStr(NULL)); \ @@ -88,29 +91,31 @@ int tjErrorLine = -1, tjErrorCode = -1; (IS_CROPPED(cr) ? (cr.h != 0 ? cr.h : TJSCALED(height, sf) - cr.y) : \ TJSCALED(height, sf)) -int stopOnWarning = 0, bottomUp = 0, noRealloc = 1, fastUpsample = 0, - fastDCT = 0, optimize = 0, progressive = 0, limitScans = 0, arithmetic = 0, - lossless = 0, restartIntervalBlocks = 0, restartIntervalRows = 0; -int precision = 8, sampleSize, compOnly = 0, decompOnly = 0, doYUV = 0, +static int stopOnWarning = 0, bottomUp = 0, noRealloc = 1, fastUpsample = 0, + fastDCT = 0, optimize = 0, progressive = 0, limitScans = 0, maxMemory = 0, + maxPixels = 0, arithmetic = 0, lossless = 0, restartIntervalBlocks = 0, + restartIntervalRows = 0; +static int precision = 8, sampleSize, compOnly = 0, decompOnly = 0, doYUV = 0, quiet = 0, doTile = 0, pf = TJPF_BGR, yuvAlign = 1, doWrite = 1; -char *ext = "ppm"; -const char *pixFormatStr[TJ_NUMPF] = { +static char *ext = "ppm"; +static const char *pixFormatStr[TJ_NUMPF] = { "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY", "", "", "", "", "CMYK" }; -const char *subNameLong[TJ_NUMSAMP] = { +static const char *subNameLong[TJ_NUMSAMP] = { "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1", "4:4:1" }; -const char *csName[TJ_NUMCS] = { +static const char *csName[TJ_NUMCS] = { "RGB", "YCbCr", "GRAY", "CMYK", "YCCK" }; -const char *subName[TJ_NUMSAMP] = { +static const char *subName[TJ_NUMSAMP] = { "444", "422", "420", "GRAY", "440", "411", "441" }; -tjscalingfactor *scalingFactors = NULL, sf = { 1, 1 }; -tjregion cr = { 0, 0, 0, 0 }; -int nsf = 0, xformOp = TJXOP_NONE, xformOpt = 0; -int (*customFilter) (short *, tjregion, tjregion, int, int, tjtransform *); -double benchTime = 5.0, warmup = 1.0; +static tjscalingfactor *scalingFactors = NULL, sf = { 1, 1 }; +static tjregion cr = { 0, 0, 0, 0 }; +static int nsf = 0, xformOp = TJXOP_NONE, xformOpt = 0; +static int (*customFilter) (short *, tjregion, tjregion, int, int, + tjtransform *); +static double benchTime = 5.0, warmup = 1.0; static char *formatName(int subsamp, int cs, char *buf) @@ -201,6 +206,10 @@ static int decomp(unsigned char **jpegBufs, size_t *jpegSizes, void *dstBuf, THROW_TJ(); if (tj3Set(handle, TJPARAM_SCANLIMIT, limitScans ? 500 : 0) == -1) THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXMEMORY, maxMemory) == -1) + THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1) + THROW_TJ(); if (IS_CROPPED(cr)) { if (tj3DecompressHeader(handle, jpegBufs[0], jpegSizes[0]) == -1) @@ -217,9 +226,11 @@ static int decomp(unsigned char **jpegBufs, size_t *jpegSizes, void *dstBuf, pitch = scaledw * ps; if (dstBuf == NULL) { +#if ULLONG_MAX > SIZE_MAX if ((unsigned long long)pitch * (unsigned long long)scaledh * (unsigned long long)sampleSize > (unsigned long long)((size_t)-1)) THROW("allocating destination buffer", "Image is too large"); +#endif if ((dstBuf = malloc((size_t)pitch * scaledh * sampleSize)) == NULL) THROW_UNIX("allocating destination buffer"); dstBufAlloc = 1; @@ -376,9 +387,11 @@ static int fullTest(tjhandle handle, void *srcBuf, int w, int h, int subsamp, int ntilesw = 1, ntilesh = 1, pitch = w * ps; const char *pfStr = pixFormatStr[pf]; +#if ULLONG_MAX > SIZE_MAX if ((unsigned long long)pitch * (unsigned long long)h * (unsigned long long)sampleSize > (unsigned long long)((size_t)-1)) THROW("allocating temporary image buffer", "Image is too large"); +#endif if ((tmpBuf = malloc((size_t)pitch * h * sampleSize)) == NULL) THROW_UNIX("allocating temporary image buffer"); @@ -454,6 +467,8 @@ static int fullTest(tjhandle handle, void *srcBuf, int w, int h, int subsamp, THROW_TJ(); if (tj3Set(handle, TJPARAM_RESTARTROWS, restartIntervalRows) == -1) THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXMEMORY, maxMemory) == -1) + THROW_TJ(); if (doYUV) { yuvSize = tj3YUVBufSize(tilew, yuvAlign, tileh, subsamp); @@ -652,6 +667,10 @@ static int decompTest(char *fileName) THROW_TJ(); if (tj3Set(handle, TJPARAM_SCANLIMIT, limitScans ? 500 : 0) == -1) THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXMEMORY, maxMemory) == -1) + THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1) + THROW_TJ(); if (tj3DecompressHeader(handle, srcBuf, srcSize) == -1) THROW_TJ(); @@ -660,7 +679,7 @@ static int decompTest(char *fileName) subsamp = tj3Get(handle, TJPARAM_SUBSAMP); precision = tj3Get(handle, TJPARAM_PRECISION); if (tj3Get(handle, TJPARAM_PROGRESSIVE) == 1) - printf("JPEG image uses progressive entropy coding\n\n"); + printf("JPEG image is progressive\n\n"); if (tj3Get(handle, TJPARAM_ARITHMETIC) == 1) printf("JPEG image uses arithmetic entropy coding\n\n"); if (tj3Set(handle, TJPARAM_PROGRESSIVE, progressive) == -1) @@ -719,6 +738,15 @@ static int decompTest(char *fileName) THROW_UNIX("allocating JPEG size array"); memset(jpegSizes, 0, sizeof(size_t) * ntilesw * ntilesh); + tsubsamp = (xformOpt & TJXOPT_GRAY) ? TJSAMP_GRAY : subsamp; + if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE || + xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) { + if (tsubsamp == TJSAMP_422) tsubsamp = TJSAMP_440; + else if (tsubsamp == TJSAMP_440) tsubsamp = TJSAMP_422; + else if (tsubsamp == TJSAMP_411) tsubsamp = TJSAMP_441; + else if (tsubsamp == TJSAMP_441) tsubsamp = TJSAMP_411; + } + if (noRealloc && (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter)) { for (i = 0; i < ntilesw * ntilesh; i++) { @@ -726,9 +754,9 @@ static int decompTest(char *fileName) if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) - jpegBufSize = tj3JPEGBufSize(tileh, tilew, subsamp); + jpegBufSize = tj3JPEGBufSize(tileh, tilew, tsubsamp); else - jpegBufSize = tj3JPEGBufSize(tilew, tileh, subsamp); + jpegBufSize = tj3JPEGBufSize(tilew, tileh, tsubsamp); if (jpegBufSize == 0) THROW_TJG(); if ((jpegBufs[i] = tj3Alloc(jpegBufSize)) == NULL) @@ -748,7 +776,6 @@ static int decompTest(char *fileName) printf("%-5d %-5d ", CROPPED_WIDTH(tilew), CROPPED_HEIGHT(tileh)); } - tsubsamp = subsamp; if (doTile || xformOp != TJXOP_NONE || xformOpt != 0 || customFilter) { if ((t = (tjtransform *)malloc(sizeof(tjtransform) * ntilesw * ntilesh)) == NULL) @@ -763,26 +790,15 @@ static int decompTest(char *fileName) subsamp == TJSAMP_UNKNOWN) THROW("transforming", "Could not determine subsampling level of JPEG image"); - if (xformOpt & TJXOPT_GRAY) tsubsamp = TJSAMP_GRAY; - if (xformOp == TJXOP_HFLIP || xformOp == TJXOP_ROT180) + if (xformOp == TJXOP_HFLIP || xformOp == TJXOP_TRANSVERSE || + xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT180) tw = tw - (tw % tjMCUWidth[tsubsamp]); - if (xformOp == TJXOP_VFLIP || xformOp == TJXOP_ROT180) + if (xformOp == TJXOP_VFLIP || xformOp == TJXOP_TRANSVERSE || + xformOp == TJXOP_ROT180 || xformOp == TJXOP_ROT270) th = th - (th % tjMCUHeight[tsubsamp]); - if (xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT90) - tw = tw - (tw % tjMCUHeight[tsubsamp]); - if (xformOp == TJXOP_TRANSVERSE || xformOp == TJXOP_ROT270) - th = th - (th % tjMCUWidth[tsubsamp]); tntilesw = (tw + ttilew - 1) / ttilew; tntilesh = (th + ttileh - 1) / ttileh; - if (xformOp == TJXOP_TRANSPOSE || xformOp == TJXOP_TRANSVERSE || - xformOp == TJXOP_ROT90 || xformOp == TJXOP_ROT270) { - if (tsubsamp == TJSAMP_422) tsubsamp = TJSAMP_440; - else if (tsubsamp == TJSAMP_440) tsubsamp = TJSAMP_422; - else if (tsubsamp == TJSAMP_411) tsubsamp = TJSAMP_441; - else if (tsubsamp == TJSAMP_441) tsubsamp = TJSAMP_411; - } - for (row = 0, tile = 0; row < tntilesh; row++) { for (col = 0; col < tntilesw; col++, tile++) { t[tile].r.w = min(ttilew, tw - col * ttilew); @@ -899,6 +915,11 @@ static void usage(char *progName) printf("-componly = Stop after running compression tests. Do not test decompression.\n"); printf("-lossless = Generate lossless JPEG images when compressing (implies\n"); printf(" -subsamp 444). PSV is the predictor selection value (1-7).\n"); + printf("-maxmemory N = Memory limit (in megabytes) for intermediate buffers used with\n"); + printf(" progressive JPEG compression and decompression, Huffman table\n"); + printf(" optimization, lossless JPEG compression, and lossless transformation\n"); + printf(" [default = no limit]\n"); + printf("-maxpixels N = Input image size limit (in pixels) [default = no limit]\n"); printf("-nowrite = Do not write reference or output images (improves consistency of\n"); printf(" benchmark results)\n"); printf("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =\n"); @@ -910,10 +931,9 @@ static void usage(char *progName) printf(" default = 8; if N is 16, then -lossless must also be specified]\n"); printf(" (-precision 12 implies -optimize unless -arithmetic is also specified)\n"); printf("-quiet = Output results in tabular rather than verbose format\n"); - printf("-restart N = When compressing, add a restart marker every N MCU rows (lossy) or\n"); - printf(" N sample rows (lossless) [default = 0 (no restart markers)]. Append 'B'\n"); - printf(" to specify the restart marker interval in MCU blocks (lossy) or samples\n"); - printf(" (lossless).\n"); + printf("-restart N = When compressing, add a restart marker every N MCU rows\n"); + printf(" [default = 0 (no restart markers)]. Append 'B' to specify the restart\n"); + printf(" marker interval in MCUs (lossy only.)\n"); printf("-stoponwarning = Immediately discontinue the current\n"); printf(" compression/decompression/transform operation if a warning (non-fatal\n"); printf(" error) occurs\n"); @@ -931,14 +951,14 @@ static void usage(char *progName) printf(" and H are the width and height of the region (0 = maximum possible width\n"); printf(" or height) and X and Y are the left and upper boundary of the region, all\n"); printf(" specified relative to the scaled image dimensions. X must be divible by\n"); - printf(" the scaled MCU width.\n"); + printf(" the scaled iMCU width.\n"); printf("-fastdct = Use the fastest DCT/IDCT algorithm available\n"); printf("-fastupsample = Use the fastest chrominance upsampling algorithm available\n"); - printf("-optimize = Use optimized baseline entropy coding in JPEG images generated by\n"); + printf("-optimize = Compute optimal Huffman tables for JPEG images generated by\n"); printf(" compession and transform operations\n"); - printf("-progressive = Use progressive entropy coding in JPEG images generated by\n"); - printf(" compression and transform operations (can be combined with -arithmetic;\n"); - printf(" implies -optimize unless -arithmetic is also specified)\n"); + printf("-progressive = Generate progressive JPEG images when compressing or\n"); + printf(" transforming (can be combined with -arithmetic; implies -optimize unless\n"); + printf(" -arithmetic is also specified)\n"); printf("-limitscans = Refuse to decompress or transform progressive JPEG images that\n"); printf(" have an unreasonably large number of scans\n"); printf("-scale M/N = When decompressing, scale the width/height of the JPEG image by a\n"); @@ -961,7 +981,7 @@ static void usage(char *progName) printf(" prior to decompression (these operations are mutually exclusive)\n"); printf("-grayscale = Transform the input image into a grayscale JPEG image prior to\n"); printf(" decompression (can be combined with the other transform operations above)\n"); - printf("-copynone = Do not copy any extra markers (including EXIF and ICC profile data)\n"); + printf("-copynone = Do not copy any extra markers (including Exif and ICC profile data)\n"); printf(" when transforming the input image\n"); printf("-yuv = Compress from/decompress to intermediate planar YUV images\n"); printf(" ** 8-bit data precision only **\n"); @@ -1023,21 +1043,19 @@ int main(int argc, char *argv[]) printf("Using fastest DCT/IDCT algorithm\n\n"); fastDCT = 1; } else if (!strcasecmp(argv[i], "-optimize")) { - printf("Using optimized baseline entropy coding\n\n"); optimize = 1; xformOpt |= TJXOPT_OPTIMIZE; } else if (!strcasecmp(argv[i], "-progressive")) { - printf("Using progressive entropy coding\n\n"); + printf("Generating progressive JPEG images\n\n"); progressive = 1; xformOpt |= TJXOPT_PROGRESSIVE; } else if (!strcasecmp(argv[i], "-arithmetic")) { printf("Using arithmetic entropy coding\n\n"); arithmetic = 1; xformOpt |= TJXOPT_ARITHMETIC; - } else if (!strcasecmp(argv[i], "-lossless")) { + } else if (!strcasecmp(argv[i], "-lossless")) lossless = 1; - subsamp = TJSAMP_444; - } else if (!strcasecmp(argv[i], "-rgb")) + else if (!strcasecmp(argv[i], "-rgb")) pf = TJPF_RGB; else if (!strcasecmp(argv[i], "-rgbx")) pf = TJPF_RGBX; @@ -1062,8 +1080,9 @@ int main(int argc, char *argv[]) if (sscanf(argv[++i], "%d/%d", &temp1, &temp2) == 2) { for (j = 0; j < nsf; j++) { - if (temp1 == scalingFactors[j].num && - temp2 == scalingFactors[j].denom) { + if ((double)temp1 / (double)temp2 == + (double)scalingFactors[j].num / + (double)scalingFactors[j].denom) { sf = scalingFactors[j]; match = 1; break; } @@ -1074,8 +1093,8 @@ int main(int argc, char *argv[]) int temp1 = -1, temp2 = -1, temp3 = -1, temp4 = -1; if (sscanf(argv[++i], "%dx%d+%d+%d", &temp1, &temp2, &temp3, - &temp4) == 4 && temp1 >= 0 && temp2 >= 0 && temp3 >= 0 && - temp4 >= 0) { + &temp4) == 4 && + temp1 >= 0 && temp2 >= 0 && temp3 >= 0 && temp4 >= 0) { cr.w = temp1; cr.h = temp2; cr.x = temp3; cr.y = temp4; } else usage(argv[0]); } else if (!strcasecmp(argv[i], "-hflip")) @@ -1145,7 +1164,17 @@ int main(int argc, char *argv[]) doWrite = 0; else if (!strcasecmp(argv[i], "-limitscans")) limitScans = 1; - else if (!strcasecmp(argv[i], "-restart") && i < argc - 1) { + else if (!strcasecmp(argv[i], "-maxmemory") && i < argc - 1) { + int tempi = atoi(argv[++i]); + + if (tempi < 0) usage(argv[0]); + maxMemory = tempi; + } else if (!strcasecmp(argv[i], "-maxpixels") && i < argc - 1) { + int tempi = atoi(argv[++i]); + + if (tempi < 0) usage(argv[0]); + maxPixels = tempi; + } else if (!strcasecmp(argv[i], "-restart") && i < argc - 1) { int tempi = -1, nscan; char tempc = 0; if ((nscan = sscanf(argv[++i], "%d%c", &tempi, &tempc)) < 1 || @@ -1163,6 +1192,12 @@ int main(int argc, char *argv[]) } } + if (optimize && !progressive && !arithmetic && !lossless && precision != 12) + printf("Computing optimal Huffman tables\n\n"); + + if (lossless) + subsamp = TJSAMP_444; + if (precision == 16 && !lossless) { printf("ERROR: -lossless must be specified along with -precision 16\n"); retval = -1; goto bailout; @@ -1212,6 +1247,8 @@ int main(int argc, char *argv[]) THROW_TJ(); if (tj3Set(handle, TJPARAM_BOTTOMUP, bottomUp) == -1) THROW_TJ(); + if (tj3Set(handle, TJPARAM_MAXPIXELS, maxPixels) == -1) + THROW_TJ(); if (precision == 8) { if ((srcBuf = tj3LoadImage8(handle, argv[1], &w, 1, &h, &pf)) == NULL) diff --git a/tjbenchtest.in b/tjbenchtest.in index 4f5a972..d26f6f6 100755 --- a/tjbenchtest.in +++ b/tjbenchtest.in @@ -20,7 +20,7 @@ runme() } EXT=bmp -IMAGES="vgl_5674_0098.${EXT} vgl_6434_0018a.${EXT} vgl_6548_0026a.${EXT} big_tree8.${EXT}" +IMAGES="vgl_5674_0098.${EXT} vgl_6434_0018a.${EXT} vgl_6548_0026a.${EXT} shira_bird8.${EXT}" IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages OUTDIR=`mktemp -d /tmp/__tjbenchtest_output.XXXXXX` EXEDIR=@CMAKE_CURRENT_BINARY_DIR@ @@ -64,12 +64,12 @@ while [ $# -gt 0 ]; do # each downsampled dimension is an odd number or is evenly divisible by the MCU # width/height. This disagreement basically amounts to a round-off error, but # there is no easy way around it, so for now, we just test the only image that -# works. (NOTE: big_tree8 does not suffer from the above issue, but it suffers -# from an unrelated problem whereby the combination of tj3DecompressToYUV*() -# and tj3DecodeYUV*() do not produce bitwise-identical 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.) +# works. (NOTE: shira_bird8 does not suffer from the above issue, but it +# suffers from an unrelated problem whereby the combination of +# tj3DecompressToYUV*() and tj3DecodeYUV*() does not produce bitwise-identical +# 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}" ;; -alloc) @@ -110,7 +110,7 @@ while [ $# -gt 0 ]; do PRECISION=$1 if [ $PRECISION != 8 ]; then EXT=ppm - IMAGES="big_building16.${EXT}" + IMAGES="monkey16.${EXT}" BMPARG= fi ;; @@ -125,7 +125,7 @@ if [ $PRECISION = 8 -a "$YUVARG" = "" ]; then IMAGES="vgl_6548_0026a.${EXT}" elif [ "$ENTROPYARG" = "-arithmetic" -o \ "$ENTROPYARG" = "-progressive-arithmetic" ]; then - IMAGES="big_tree8.${EXT}" + IMAGES="shira_bird8.${EXT}" fi fi @@ -317,13 +317,13 @@ for image in $IMAGES; do runme cmp $OUTDIR/${basename}_${samp}_Q${TJQUAL}_full.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm rm $OUTDIR/${basename}_${samp}_Q${TJQUAL}_full.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm - runme $EXEDIR/djpeg -rgb -scale 7/8 -crop ${CROPW7_8}x81+${CROPL7_8}+3 $NSARG -outfile $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg + runme $EXEDIR/djpeg -rgb -scale 14/16 -crop ${CROPW7_8}x81+${CROPL7_8}+3 $NSARG -outfile $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg runme $TJBENCH $OUTDIR/${basename}_${samp}_Q${TJQUAL}.jpg -scale 7/8 -crop ${CROPW7_8}x81+${CROPL7_8}+3 -quiet -benchtime 0.01 -warmup 0 ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG runme cmp $OUTDIR/${basename}_${samp}_Q${TJQUAL}_7_8.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm rm $OUTDIR/${basename}_${samp}_Q${TJQUAL}_7_8.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm runme $EXEDIR/djpeg -rgb -scale 1/2 -crop 40x40+0+0 $NSARG -outfile $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg - runme $TJBENCH $OUTDIR/${basename}_${samp}_Q${TJQUAL}.jpg -scale 1/2 -crop 40x40+0+0 -quiet -benchtime 0.01 -warmup 0 ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG + runme $TJBENCH $OUTDIR/${basename}_${samp}_Q${TJQUAL}.jpg -scale 4/8 -crop 40x40+0+0 -quiet -benchtime 0.01 -warmup 0 ${dctarg} $YUVARG $ALLOCARG $ENTROPYARG $LOSSLSARG runme cmp $OUTDIR/${basename}_${samp}_Q${TJQUAL}_1_2.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm rm $OUTDIR/${basename}_${samp}_Q${TJQUAL}_1_2.ppm $OUTDIR/${basename}_${samp}_scale_crop_djpeg.ppm done diff --git a/tjexample.c b/tjexample.c index 579ebe5..ca61f55 100644 --- a/tjexample.c +++ b/tjexample.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2012, 2014-2015, 2017, 2019, 2021-2023 + * Copyright (C)2011-2012, 2014-2015, 2017, 2019, 2021-2024 * D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,10 @@ #include #include #include +#include +#if !defined(_MSC_VER) || _MSC_VER > 1600 +#include +#endif #include @@ -61,16 +65,16 @@ #define DEFAULT_QUALITY 95 -const char *subsampName[TJ_NUMSAMP] = { +static const char *subsampName[TJ_NUMSAMP] = { "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1", "4:4:1" }; -const char *colorspaceName[TJ_NUMCS] = { +static const char *colorspaceName[TJ_NUMCS] = { "RGB", "YCbCr", "GRAY", "CMYK", "YCCK" }; -tjscalingfactor *scalingFactors = NULL; -int numScalingFactors = 0; +static tjscalingfactor *scalingFactors = NULL; +static int numScalingFactors = 0; /* DCT filter example. This produces a negative of the image. */ @@ -141,8 +145,8 @@ static void usage(char *programName) printf("-crop WxH+X+Y = Perform lossless cropping on the input image prior to\n"); printf(" decompressing it. X and Y specify the upper left corner of the cropping\n"); printf(" region, and W and H specify the width and height of the cropping region.\n"); - printf(" X and Y must be evenly divible by the MCU block size (8x8 if the input\n"); - printf(" image was compressed using no subsampling or grayscale, 16x8 if it was\n"); + printf(" X and Y must be evenly divible by the iMCU size (8x8 if the input image\n"); + printf(" was compressed using no subsampling or grayscale, 16x8 if it was\n"); printf(" compressed using 4:2:2 subsampling, or 16x16 if it was compressed using\n"); printf(" 4:2:0 subsampling.)\n\n"); @@ -252,6 +256,9 @@ int main(int argc, char **argv) inFormat = &inFormat[1]; outFormat = &outFormat[1]; + if ((tjInstance = tj3Init(TJINIT_TRANSFORM)) == NULL) + THROW_TJ("creating TurboJPEG instance"); + if (!strcasecmp(inFormat, "jpg")) { /* Input image is a JPEG image. Decompress and/or transform it. */ long size; @@ -280,8 +287,6 @@ int main(int argc, char **argv) unsigned char *dstBuf = NULL; /* Dynamically allocate the JPEG buffer */ size_t dstSize = 0; - if ((tjInstance = tj3Init(TJINIT_TRANSFORM)) == NULL) - THROW_TJ("initializing transformer"); xform.options |= TJXOPT_TRIM; if (tj3Transform(tjInstance, jpegBuf, jpegSize, 1, &dstBuf, &dstSize, &xform) < 0) { @@ -291,9 +296,6 @@ int main(int argc, char **argv) tj3Free(jpegBuf); jpegBuf = dstBuf; jpegSize = dstSize; - } else { - if ((tjInstance = tj3Init(TJINIT_DECOMPRESS)) == NULL) - THROW_TJ("initializing decompressor"); } if (tj3Set(tjInstance, TJPARAM_FASTUPSAMPLE, fastUpsample) < 0) THROW_TJ("setting TJPARAM_FASTUPSAMPLE"); @@ -323,7 +325,6 @@ int main(int argc, char **argv) THROW_UNIX("opening output file"); if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1) THROW_UNIX("writing output file"); - fclose(jpegFile); jpegFile = NULL; goto bailout; } @@ -338,9 +339,11 @@ int main(int argc, char **argv) outSubsamp = inSubsamp; pixelFormat = TJPF_BGRX; +#if ULLONG_MAX > SIZE_MAX if ((unsigned long long)width * height * tjPixelSize[pixelFormat] > (unsigned long long)((size_t)-1)) THROW("allocating uncompressed image buffer", "Image is too large"); +#endif if ((imgBuf = (unsigned char *)malloc(sizeof(unsigned char) * width * height * tjPixelSize[pixelFormat])) == NULL) @@ -350,11 +353,8 @@ int main(int argc, char **argv) pixelFormat) < 0) THROW_TJ("decompressing JPEG image"); tj3Free(jpegBuf); jpegBuf = NULL; - tj3Destroy(tjInstance); tjInstance = NULL; } else { /* Input image is not a JPEG image. Load it into memory. */ - if ((tjInstance = tj3Init(TJINIT_COMPRESS)) == NULL) - THROW_TJ("initializing compressor"); if ((imgBuf = tj3LoadImage8(tjInstance, argv[1], &width, 1, &height, &pixelFormat)) == NULL) THROW_TJ("loading input image"); @@ -380,8 +380,6 @@ int main(int argc, char **argv) printf(", %s subsampling, quality = %d\n", subsampName[outSubsamp], outQual); - if (!tjInstance && (tjInstance = tj3Init(TJINIT_COMPRESS)) == NULL) - THROW_TJ("initializing compressor"); if (tj3Set(tjInstance, TJPARAM_SUBSAMP, outSubsamp) < 0) THROW_TJ("setting TJPARAM_SUBSAMP"); if (tj3Set(tjInstance, TJPARAM_QUALITY, outQual) < 0) @@ -391,16 +389,12 @@ int main(int argc, char **argv) if (tj3Compress8(tjInstance, imgBuf, width, 0, height, pixelFormat, &jpegBuf, &jpegSize) < 0) THROW_TJ("compressing image"); - tj3Destroy(tjInstance); tjInstance = NULL; /* Write the JPEG image to disk. */ if ((jpegFile = fopen(argv[2], "wb")) == NULL) THROW_UNIX("opening output file"); if (fwrite(jpegBuf, jpegSize, 1, jpegFile) < 1) THROW_UNIX("writing output file"); - tj3Destroy(tjInstance); tjInstance = NULL; - fclose(jpegFile); jpegFile = NULL; - tj3Free(jpegBuf); jpegBuf = NULL; } else { /* Output image format is not JPEG. Save the uncompressed image directly to disk. */ diff --git a/tjexampletest.in b/tjexampletest.in index c56fc42..0d720b4 100755 --- a/tjexampletest.in +++ b/tjexampletest.in @@ -19,7 +19,7 @@ runme() $* } -IMAGES="vgl_5674_0098.bmp vgl_6434_0018a.bmp vgl_6548_0026a.bmp big_tree8.bmp" +IMAGES="vgl_5674_0098.bmp vgl_6434_0018a.bmp vgl_6548_0026a.bmp shira_bird8.bmp" IMGDIR=@CMAKE_CURRENT_SOURCE_DIR@/testimages OUTDIR=`mktemp -d /tmp/__tjexampletest_output.XXXXXX` EXEDIR=@CMAKE_CURRENT_BINARY_DIR@ @@ -39,7 +39,7 @@ while [ $# -gt 0 ]; do JAVAARG=-java TJEXAMPLE="$JAVA $JAVAARGS TJExample" # The Java version of TJExample can't currently handle pixel density - # information, so it fails on big_tree8.bmp. + # information, so it fails on shira_bird8.bmp. IMAGES="vgl_5674_0098.bmp vgl_6434_0018a.bmp vgl_6548_0026a.bmp" ;; esac @@ -68,6 +68,14 @@ for image in $IMAGES; do runme $EXEDIR/djpeg -dct fast -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_fast_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_fast_cjpeg.jpg runme $EXEDIR/djpeg -dct int -nosmooth -bmp -outfile $OUTDIR/${basename}_${samp}_accurate_nosmooth_djpeg.bmp $OUTDIR/${basename}_${samp}_accurate_cjpeg.jpg done + runme $EXEDIR/cjpeg -quality 95 -dct fast -grayscale -outfile $OUTDIR/${basename}_GRAY_fast_cjpeg2.jpg $OUTDIR/${basename}_GRAY_fast_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x2 -outfile $OUTDIR/${basename}_420_fast_cjpeg2.jpg $OUTDIR/${basename}_420_fast_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 2x1 -outfile $OUTDIR/${basename}_422_fast_cjpeg2.jpg $OUTDIR/${basename}_422_fast_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct fast -sample 1x1 -outfile $OUTDIR/${basename}_444_fast_cjpeg2.jpg $OUTDIR/${basename}_444_fast_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct int -grayscale -outfile $OUTDIR/${basename}_GRAY_accurate_cjpeg2.jpg $OUTDIR/${basename}_GRAY_accurate_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x2 -outfile $OUTDIR/${basename}_420_accurate_cjpeg2.jpg $OUTDIR/${basename}_420_accurate_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct int -sample 2x1 -outfile $OUTDIR/${basename}_422_accurate_cjpeg2.jpg $OUTDIR/${basename}_422_accurate_djpeg.bmp + runme $EXEDIR/cjpeg -quality 95 -dct int -sample 1x1 -outfile $OUTDIR/${basename}_444_accurate_cjpeg2.jpg $OUTDIR/${basename}_444_accurate_djpeg.bmp # Compression for dct in fast accurate; do @@ -81,6 +89,18 @@ for image in $IMAGES; do done done + # Recompression + for dct in fast accurate; do + dctarg= + if [ "${dct}" = "fast" ]; then + dctarg=-fastdct + fi + for samp in GRAY 420 422 444; do + runme $TJEXAMPLE $OUTDIR/${basename}_${samp}_${dct}.jpg $OUTDIR/${basename}_${samp}_${dct}_recomp.jpg -q 95 -subsamp ${samp} ${dctarg} + runme cmp $OUTDIR/${basename}_${samp}_${dct}_recomp.jpg $OUTDIR/${basename}_${samp}_${dct}_cjpeg2.jpg + done + done + # Decompression for dct in fast accurate; do dctarg= diff --git a/tjunittest.c b/tjunittest.c index dcd5006..3942833 100644 --- a/tjunittest.c +++ b/tjunittest.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2014, 2017-2019, 2022-2023 D. R. Commander. + * Copyright (C)2009-2014, 2017-2019, 2022-2024 D. R. Commander. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -83,29 +83,29 @@ static void usage(char *progName) BAILOUT() \ } -const char *subNameLong[TJ_NUMSAMP] = { +static const char *subNameLong[TJ_NUMSAMP] = { "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0", "4:1:1", "4:4:1" }; -const char *subName[TJ_NUMSAMP] = { +static const char *subName[TJ_NUMSAMP] = { "444", "422", "420", "GRAY", "440", "411", "441" }; -const char *pixFormatStr[TJ_NUMPF] = { +static const char *pixFormatStr[TJ_NUMPF] = { "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", "RGBA", "BGRA", "ABGR", "ARGB", "CMYK" }; -const int _3sampleFormats[] = { TJPF_RGB, TJPF_BGR }; -const int _4sampleFormats[] = { +static const int _3sampleFormats[] = { TJPF_RGB, TJPF_BGR }; +static const int _4sampleFormats[] = { TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB, TJPF_CMYK }; -const int _onlyGray[] = { TJPF_GRAY }; -const int _onlyRGB[] = { TJPF_RGB }; +static const int _onlyGray[] = { TJPF_GRAY }; +static const int _onlyRGB[] = { TJPF_RGB }; -int doYUV = 0, lossless = 0, psv = 1, alloc = 0, yuvAlign = 4; -int precision = 8, sampleSize, maxSample, tolerance, redToY, yellowToY; +static int doYUV = 0, lossless = 0, psv = 1, alloc = 0, yuvAlign = 4; +static int precision = 8, sampleSize, maxSample, tolerance, redToY, yellowToY; -int exitStatus = 0; +static int exitStatus = 0; #define BAILOUT() { exitStatus = -1; goto bailout; } diff --git a/transupp.c b/transupp.c index 34fbb37..0a92413 100644 --- a/transupp.c +++ b/transupp.c @@ -4,7 +4,7 @@ * This file was part of the Independent JPEG Group's software: * Copyright (C) 1997-2019, Thomas G. Lane, Guido Vollbeding. * libjpeg-turbo Modifications: - * Copyright (C) 2010, 2017, 2021-2022, D. R. Commander. + * Copyright (C) 2010, 2017, 2021-2022, 2024, D. R. Commander. * For conditions of distribution and use, see the accompanying README.ijg * file. * @@ -201,7 +201,11 @@ adjust_quant(j_decompress_ptr srcinfo, jvirt_barray_ptr *src_coef_arrays, compptr1 = srcinfo->comp_info + ci; compptr2 = dropinfo->comp_info + ci; qtblptr1 = compptr1->quant_table; + if (qtblptr1 == NULL) + ERREXIT1(srcinfo, JERR_NO_QUANT_TABLE, compptr1->quant_tbl_no); qtblptr2 = compptr2->quant_table; + if (qtblptr2 == NULL) + ERREXIT1(dropinfo, JERR_NO_QUANT_TABLE, compptr2->quant_tbl_no); for (k = 0; k < DCTSIZE2; k++) { if (qtblptr1->quantval[k] != qtblptr2->quantval[k]) { if (trim) @@ -2311,19 +2315,20 @@ jcopy_markers_setup(j_decompress_ptr srcinfo, JCOPY_OPTION option) #ifdef SAVE_MARKERS_SUPPORTED int m; - /* Save comments except under NONE option */ + /* Save comments unless JCOPYOPT_NONE or JCOPYOPT_ICC specified */ if (option != JCOPYOPT_NONE && option != JCOPYOPT_ICC) { jpeg_save_markers(srcinfo, JPEG_COM, 0xFFFF); } - /* Save all types of APPn markers iff ALL option */ + /* Save all APPn markers iff JCOPYOPT_ALL* specified ... */ if (option == JCOPYOPT_ALL || option == JCOPYOPT_ALL_EXCEPT_ICC) { for (m = 0; m < 16; m++) { + /* ... except APP2 markers if JCOPYOPT_ALL_EXCEPT_ICC specified */ if (option == JCOPYOPT_ALL_EXCEPT_ICC && m == 2) continue; jpeg_save_markers(srcinfo, JPEG_APP0 + m, 0xFFFF); } } - /* Save only APP2 markers if ICC option selected */ + /* Save only APP2 markers if JCOPYOPT_ICC specified */ if (option == JCOPYOPT_ICC) { jpeg_save_markers(srcinfo, JPEG_APP0 + 2, 0xFFFF); } @@ -2343,12 +2348,22 @@ jcopy_markers_execute(j_decompress_ptr srcinfo, j_compress_ptr dstinfo, { jpeg_saved_marker_ptr marker; - /* In the current implementation, we don't actually need to examine the - * option flag here; we just copy everything that got saved. - * But to avoid confusion, we do not output JFIF and Adobe APP14 markers - * if the encoder library already wrote one. - */ for (marker = srcinfo->marker_list; marker != NULL; marker = marker->next) { + if (option == JCOPYOPT_NONE) + continue; + else if (option == JCOPYOPT_COMMENTS) { + if (marker->marker != JPEG_COM) + continue; + } else if (option == JCOPYOPT_ALL_EXCEPT_ICC) { + if (marker->marker == JPEG_APP0 + 2) + continue; + } else if (option == JCOPYOPT_ICC) { + if (marker->marker != JPEG_APP0 + 2) + continue; + } + /* To avoid confusion, we do not output JFIF and Adobe APP14 markers if the + * encoder library already wrote one. + */ if (dstinfo->write_JFIF_header && marker->marker == JPEG_APP0 && marker->data_length >= 5 && diff --git a/turbojpeg-jni.c b/turbojpeg-jni.c index 32186f3..68e5739 100644 --- a/turbojpeg-jni.c +++ b/turbojpeg-jni.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2011-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2011-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -91,7 +91,9 @@ cArray = NULL; \ } -/* TurboJPEG 1.2.x: TJ::bufSize() */ +#define PAD(v, p) ((v + (p) - 1) & (~((p) - 1))) + +/* TurboJPEG 1.2.x: TJ.bufSize() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSize (JNIEnv *env, jclass cls, jint width, jint height, jint jpegSubsamp) { @@ -105,7 +107,7 @@ bailout: return (jint)retval; } -/* TurboJPEG 1.4.x: TJ::bufSizeYUV() */ +/* TurboJPEG 1.4.x: TJ.bufSizeYUV() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_bufSizeYUV__IIII (JNIEnv *env, jclass cls, jint width, jint align, jint height, jint subsamp) { @@ -119,7 +121,7 @@ bailout: return (jint)retval; } -/* TurboJPEG 1.4.x: TJ::planeSizeYUV() */ +/* TurboJPEG 1.4.x: TJ.planeSizeYUV() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeSizeYUV__IIIII (JNIEnv *env, jclass cls, jint componentID, jint width, jint stride, jint height, jint subsamp) @@ -134,7 +136,7 @@ bailout: return (jint)retval; } -/* TurboJPEG 1.4.x: TJ::planeWidth() */ +/* TurboJPEG 1.4.x: TJ.planeWidth() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeWidth__III (JNIEnv *env, jclass cls, jint componentID, jint width, jint subsamp) { @@ -146,7 +148,7 @@ bailout: return retval; } -/* TurboJPEG 1.4.x: TJ::planeHeight() */ +/* TurboJPEG 1.4.x: TJ.planeHeight() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJ_planeHeight__III (JNIEnv *env, jclass cls, jint componentID, jint height, jint subsamp) { @@ -158,7 +160,7 @@ bailout: return retval; } -/* TurboJPEG 1.2.x: TJCompressor::init() */ +/* TurboJPEG 1.2.x: TJCompressor.init() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_init (JNIEnv *env, jobject obj) { @@ -177,7 +179,7 @@ bailout: return; } -/* TurboJPEG 3: TJCompressor::set() */ +/* TurboJPEG 3: TJCompressor.set() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_set (JNIEnv *env, jobject obj, jint param, jint value) { @@ -192,7 +194,7 @@ bailout: return; } -/* TurboJPEG 3: TJCompressor::get() */ +/* TurboJPEG 3: TJCompressor.get() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_get (JNIEnv *env, jobject obj, jint param) { @@ -277,7 +279,7 @@ bailout: return (jint)jpegSize; } -/* TurboJPEG 3: TJCompressor::compress8() byte source */ +/* TurboJPEG 3: TJCompressor.compress8() byte source */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress8___3BIIIIII_3B (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, jint pitch, jint height, jint pf, jbyteArray dst) @@ -286,7 +288,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress8___ pf, dst); } -/* TurboJPEG 3: TJCompressor::compress12() */ +/* TurboJPEG 3: TJCompressor.compress12() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress12 (JNIEnv *env, jobject obj, jshortArray src, jint x, jint y, jint width, jint pitch, jint height, jint pf, jbyteArray dst) @@ -295,7 +297,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress12 height, pf, dst); } -/* TurboJPEG 3: TJCompressor::compress16() */ +/* TurboJPEG 3: TJCompressor.compress16() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress16 (JNIEnv *env, jobject obj, jshortArray src, jint x, jint y, jint width, jint pitch, jint height, jint pf, jbyteArray dst) @@ -304,7 +306,7 @@ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress16 height, pf, dst); } -/* TurboJPEG 3: TJCompressor::compress8() int source */ +/* TurboJPEG 3: TJCompressor.compress8() int source */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compress8___3IIIIIII_3B (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, jint stride, jint height, jint pf, jbyteArray dst) @@ -321,7 +323,7 @@ bailout: return 0; } -/* TurboJPEG 3: TJCompressor::compressFromYUV8() */ +/* TurboJPEG 3: TJCompressor.compressFromYUV8() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_compressFromYUV8 (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, jint width, jintArray jSrcStrides, jint height, jbyteArray dst) @@ -502,7 +504,7 @@ bailout: SAFE_RELEASE(jDstPlanes[i], dstPlanesTmp[i]); } -/* TurboJPEG 3: TJCompressor::encodeYUV8() byte source */ +/* TurboJPEG 3: TJCompressor.encodeYUV8() byte source */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV8___3BIIIIII_3_3B_3I_3I (JNIEnv *env, jobject obj, jbyteArray src, jint x, jint y, jint width, jint pitch, jint height, jint pf, jobjectArray dstobjs, @@ -512,7 +514,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV8__ dstobjs, jDstOffsets, jDstStrides); } -/* TurboJPEG 3: TJCompressor::encodeYUV8() int source */ +/* TurboJPEG 3: TJCompressor.encodeYUV8() int source */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_encodeYUV8___3IIIIIII_3_3B_3I_3I (JNIEnv *env, jobject obj, jintArray src, jint x, jint y, jint width, jint stride, jint height, jint pf, jobjectArray dstobjs, @@ -531,7 +533,7 @@ bailout: return; } -/* TurboJPEG 1.2.x: TJCompressor::destroy() */ +/* TurboJPEG 1.2.x: TJCompressor.destroy() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_destroy (JNIEnv *env, jobject obj) { @@ -546,7 +548,7 @@ bailout: return; } -/* TurboJPEG 1.2.x: TJDecompressor::init() */ +/* TurboJPEG 1.2.x: TJDecompressor.init() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_init (JNIEnv *env, jobject obj) { @@ -565,21 +567,21 @@ bailout: return; } -/* TurboJPEG 3: TJDecompressor::set() */ +/* TurboJPEG 3: TJDecompressor.set() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_set (JNIEnv *env, jobject obj, jint param, jint value) { Java_org_libjpegturbo_turbojpeg_TJCompressor_set(env, obj, param, value); } -/* TurboJPEG 3: TJDecompressor::get() */ +/* TurboJPEG 3: TJDecompressor.get() */ JNIEXPORT jint JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_get (JNIEnv *env, jobject obj, jint param) { return Java_org_libjpegturbo_turbojpeg_TJCompressor_get(env, obj, param); } -/* TurboJPEG 1.2.x: TJDecompressor::getScalingFactors() */ +/* TurboJPEG 1.2.x: TJDecompressor.getScalingFactors() */ JNIEXPORT jobjectArray JNICALL Java_org_libjpegturbo_turbojpeg_TJ_getScalingFactors (JNIEnv *env, jclass cls) { @@ -610,7 +612,7 @@ bailout: return sfjava; } -/* TurboJPEG 1.2.x: TJDecompressor::decompressHeader() */ +/* TurboJPEG 1.2.x: TJDecompressor.decompressHeader() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressHeader (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize) { @@ -633,7 +635,7 @@ bailout: SAFE_RELEASE(src, jpegBuf); } -/* TurboJPEG 3: TJDecompressor::setCroppingRegion() */ +/* TurboJPEG 3: TJDecompressor.setCroppingRegion() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_setCroppingRegion (JNIEnv *env, jobject obj) { @@ -783,7 +785,7 @@ bailout: SAFE_RELEASE(src, jpegBuf); } -/* TurboJPEG 3: TJDecompressor::decompress8() byte destination */ +/* TurboJPEG 3: TJDecompressor.decompress8() byte destination */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress8___3BI_3BIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jbyteArray dst, jint x, jint y, jint pitch, jint pf) @@ -792,7 +794,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress pf); } -/* TurboJPEG 3: TJDecompressor::decompress12() */ +/* TurboJPEG 3: TJDecompressor.decompress12() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress12 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jshortArray dst, jint x, jint y, jint pitch, jint pf) @@ -801,7 +803,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress pf); } -/* TurboJPEG 3: TJDecompressor::decompress16() */ +/* TurboJPEG 3: TJDecompressor.decompress16() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress16 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jshortArray dst, jint x, jint y, jint pitch, jint pf) @@ -810,7 +812,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress pf); } -/* TurboJPEG 3: TJDecompressor::decompress8() int destination */ +/* TurboJPEG 3: TJDecompressor.decompress8() int destination */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompress8___3BI_3IIIII (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jintArray dst, jint x, jint y, jint stride, jint pf) @@ -827,7 +829,7 @@ bailout: return; } -/* TurboJPEG 3: TJDecompressor::decompressToYUV8() */ +/* TurboJPEG 3: TJDecompressor.decompressToYUV8() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decompressToYUV8 (JNIEnv *env, jobject obj, jbyteArray src, jint jpegSize, jobjectArray dstobjs, jintArray jDstOffsets, jintArray jDstStrides) @@ -1015,7 +1017,7 @@ bailout: SAFE_RELEASE(jSrcPlanes[i], srcPlanesTmp[i]); } -/* TurboJPEG 3: TJDecompressor::decodeYUV8() byte destination */ +/* TurboJPEG 3: TJDecompressor.decodeYUV8() byte destination */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV8___3_3B_3I_3I_3BIIIIII (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, jintArray jSrcStrides, jbyteArray dst, jint x, jint y, jint width, @@ -1025,7 +1027,7 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV8 1, x, y, width, pitch, height, pf); } -/* TurboJPEG 3: TJDecompressor::decodeYUV8() int destination */ +/* TurboJPEG 3: TJDecompressor.decodeYUV8() int destination */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_decodeYUV8___3_3B_3I_3I_3IIIIIII (JNIEnv *env, jobject obj, jobjectArray srcobjs, jintArray jSrcOffsets, jintArray jSrcStrides, jintArray dst, jint x, jint y, jint width, @@ -1044,7 +1046,7 @@ bailout: return; } -/* TurboJPEG 1.2.x: TJTransformer::init() */ +/* TurboJPEG 1.2.x: TJTransformer.init() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_init (JNIEnv *env, jobject obj) { @@ -1128,7 +1130,7 @@ bailout: return -1; } -/* TurboJPEG 1.2.x: TJTransformer::transform() */ +/* TurboJPEG 1.2.x: TJTransformer.transform() */ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transform (JNIEnv *env, jobject obj, jbyteArray jsrcBuf, jint jpegSize, jobjectArray dstobjs, jobjectArray tobjs) @@ -1139,7 +1141,7 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf size_t *dstSizes = NULL; tjtransform *t = NULL; jbyteArray *jdstBufs = NULL; - int i, jpegWidth = 0, jpegHeight = 0, jpegSubsamp; + int i, jpegWidth = 0, jpegHeight = 0, srcSubsamp; jintArray jdstSizes = 0; jint *dstSizesi = NULL; JNICustomFilterParams *params = NULL; @@ -1152,8 +1154,7 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf THROW_ARG("JPEG header has not yet been read"); if ((jpegHeight = tj3Get(handle, TJPARAM_JPEGHEIGHT)) == -1) THROW_ARG("JPEG header has not yet been read"); - if ((jpegSubsamp = tj3Get(handle, TJPARAM_SUBSAMP)) == TJSAMP_UNKNOWN) - THROW_ARG("TJPARAM_SUBSAMP must be specified"); + srcSubsamp = tj3Get(handle, TJPARAM_SUBSAMP); n = (*env)->GetArrayLength(env, dstobjs); if (n != (*env)->GetArrayLength(env, tobjs)) @@ -1212,16 +1213,21 @@ JNIEXPORT jintArray JNICALL Java_org_libjpegturbo_turbojpeg_TJTransformer_transf for (i = 0; i < n; i++) { int w = jpegWidth, h = jpegHeight; + int dstSubsamp = (t[i].options & TJXOPT_GRAY) ? TJSAMP_GRAY : srcSubsamp; if (t[i].op == TJXOP_TRANSPOSE || t[i].op == TJXOP_TRANSVERSE || t[i].op == TJXOP_ROT90 || t[i].op == TJXOP_ROT270) { w = jpegHeight; h = jpegWidth; + if (dstSubsamp == TJSAMP_422) dstSubsamp = TJSAMP_440; + else if (dstSubsamp == TJSAMP_440) dstSubsamp = TJSAMP_422; + else if (dstSubsamp == TJSAMP_411) dstSubsamp = TJSAMP_441; + else if (dstSubsamp == TJSAMP_441) dstSubsamp = TJSAMP_411; } if (t[i].r.w != 0) w = t[i].r.w; if (t[i].r.h != 0) h = t[i].r.h; BAILIF0(jdstBufs[i] = (*env)->GetObjectArrayElement(env, dstobjs, i)); if ((size_t)(*env)->GetArrayLength(env, jdstBufs[i]) < - tj3JPEGBufSize(w, h, jpegSubsamp)) + tj3JPEGBufSize(w, h, dstSubsamp)) THROW_ARG("Destination buffer is not large enough"); } BAILIF0NOEC(jpegBuf = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); @@ -1260,7 +1266,7 @@ bailout: return jdstSizes; } -/* TurboJPEG 1.2.x: TJDecompressor::destroy() */ +/* TurboJPEG 1.2.x: TJDecompressor.destroy() */ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_destroy (JNIEnv *env, jobject obj) { @@ -1274,7 +1280,8 @@ JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_loadImage { tjhandle handle = NULL; void *dstBuf = NULL, *jdstPtr; - int width, *warr, height, *harr, pixelFormat, *pfarr, n; + int width, *warr, height, *harr, pixelFormat, *pfarr; + jsize arraySize, pitch; const char *filename = NULL; jboolean isCopy; jobject jdstBuf = NULL; @@ -1331,13 +1338,14 @@ JNIEXPORT jobject JNICALL Java_org_libjpegturbo_turbojpeg_TJCompressor_loadImage pfarr[0] = pixelFormat; (*env)->ReleasePrimitiveArrayCritical(env, jpixelFormat, pfarr, 0); - n = width * height * tjPixelSize[pixelFormat]; + pitch = PAD(width * tjPixelSize[pixelFormat], align); + arraySize = pitch * height; if (precision == 8) - jdstBuf = (*env)->NewByteArray(env, n); + jdstBuf = (*env)->NewByteArray(env, arraySize); else - jdstBuf = (*env)->NewShortArray(env, n); + jdstBuf = (*env)->NewShortArray(env, arraySize); BAILIF0NOEC(jdstPtr = (*env)->GetPrimitiveArrayCritical(env, jdstBuf, 0)); - memcpy(jdstPtr, dstBuf, n * (precision > 8 ? 2 : 1)); + memcpy(jdstPtr, dstBuf, arraySize * (precision > 8 ? 2 : 1)); (*env)->ReleasePrimitiveArrayCritical(env, jdstBuf, jdstPtr, 0); bailout: @@ -1354,29 +1362,33 @@ JNIEXPORT void JNICALL Java_org_libjpegturbo_turbojpeg_TJDecompressor_saveImage tjhandle handle = NULL; void *srcBuf = NULL, *jsrcPtr; const char *filename = NULL; - int n; + jsize arraySize, actualPitch; jboolean isCopy; GET_HANDLE(); if ((precision != 8 && precision != 12 && precision != 16) || - jfilename == NULL || jsrcBuf == NULL || width < 1 || height < 1 || - pixelFormat < 0 || pixelFormat >= TJ_NUMPF) + jfilename == NULL || jsrcBuf == NULL || width < 1 || pitch < 0 || + height < 1 || pixelFormat < 0 || + pixelFormat >= org_libjpegturbo_turbojpeg_TJ_NUMPF) THROW_ARG("Invalid argument in saveImage()"); + if (org_libjpegturbo_turbojpeg_TJ_NUMPF != TJ_NUMPF) + THROW_ARG("Mismatch between Java and C API"); if ((unsigned long long)width * (unsigned long long)height * (unsigned long long)tjPixelSize[pixelFormat] > (unsigned long long)((unsigned int)-1)) THROW_ARG("Image is too large"); - n = width * height * tjPixelSize[pixelFormat]; - if ((*env)->GetArrayLength(env, jsrcBuf) < n) + actualPitch = (pitch == 0) ? width * tjPixelSize[pixelFormat] : pitch; + arraySize = actualPitch * height; + if ((*env)->GetArrayLength(env, jsrcBuf) < arraySize) THROW_ARG("Source buffer is not large enough"); - if ((srcBuf = malloc(n * (precision > 8 ? 2 : 1))) == NULL) + if ((srcBuf = malloc(arraySize * (precision > 8 ? 2 : 1))) == NULL) THROW_MEM(); BAILIF0NOEC(jsrcPtr = (*env)->GetPrimitiveArrayCritical(env, jsrcBuf, 0)); - memcpy(srcBuf, jsrcPtr, n * (precision > 8 ? 2 : 1)); + memcpy(srcBuf, jsrcPtr, arraySize * (precision > 8 ? 2 : 1)); (*env)->ReleasePrimitiveArrayCritical(env, jsrcBuf, jsrcPtr, 0); BAILIF0(filename = (*env)->GetStringUTFChars(env, jfilename, &isCopy)); diff --git a/turbojpeg-mp.c b/turbojpeg-mp.c index 5699869..d4b3c74 100644 --- a/turbojpeg-mp.c +++ b/turbojpeg-mp.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2009-2024 D. R. Commander. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -125,10 +125,10 @@ DLLEXPORT int GET_NAME(tj3Compress, BITS_IN_JSAMPLE) jpeg_finish_compress(cinfo); bailout: - if (cinfo->global_state > CSTATE_START) { - if (alloc) (*cinfo->dest->term_destination) (cinfo); + if (cinfo->global_state > CSTATE_START && alloc) + (*cinfo->dest->term_destination) (cinfo); + if (cinfo->global_state > CSTATE_START || retval == -1) jpeg_abort_compress(cinfo); - } free(row_pointer); if (this->jerr.warning) retval = -1; return retval; @@ -167,16 +167,22 @@ DLLEXPORT int GET_NAME(tj3Decompress, BITS_IN_JSAMPLE) } else dinfo->progress = NULL; + dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval = -1; goto bailout; } - if (dinfo->global_state <= DSTATE_START) { + if (dinfo->global_state <= DSTATE_INHEADER) { jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); jpeg_read_header(dinfo, TRUE); } setDecompParameters(this); + if (this->maxPixels && + (unsigned long long)this->jpegWidth * this->jpegHeight > + (unsigned long long)this->maxPixels) + THROW("Image is too large"); this->dinfo.out_color_space = pf2cs[pixelFormat]; #if BITS_IN_JSAMPLE != 16 scaledWidth = TJSCALED(dinfo->image_width, this->scalingFactor); @@ -342,11 +348,11 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE) } else THROW("Unsupported file type"); + cinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + src->input_file = file; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* Refuse to load images larger than 1 Megapixel when fuzzing. */ + /* Refuse to load images larger than the specified size. */ src->max_pixels = this->maxPixels; -#endif (*src->start_input) (cinfo, src); if (tempc == 'B') { if (cinfo->X_density && cinfo->Y_density) { @@ -361,8 +367,11 @@ DLLEXPORT _JSAMPLE *GET_NAME(tj3LoadImage, BITS_IN_JSAMPLE) *pixelFormat = cs2pf[cinfo->in_color_space]; pitch = PAD((*width) * tjPixelSize[*pixelFormat], align); - if ((unsigned long long)pitch * (unsigned long long)(*height) > + if ( +#if ULLONG_MAX > SIZE_MAX + (unsigned long long)pitch * (unsigned long long)(*height) > (unsigned long long)((size_t)-1) || +#endif (dstBuf = (_JSAMPLE *)malloc(pitch * (*height) * sizeof(_JSAMPLE))) == NULL) THROW("Memory allocation failure"); @@ -480,6 +489,8 @@ DLLEXPORT int GET_NAME(tj3SaveImage, BITS_IN_JSAMPLE) invert = this->bottomUp; } + dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + dst->output_file = file; (*dst->start_output) (dinfo, dst); (*dinfo->mem->realize_virt_arrays) ((j_common_ptr)dinfo); diff --git a/turbojpeg.c b/turbojpeg.c index b75d414..766a6d1 100644 --- a/turbojpeg.c +++ b/turbojpeg.c @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2023 D. R. Commander. All Rights Reserved. + * Copyright (C)2009-2024 D. R. Commander. All Rights Reserved. * Copyright (C)2021 Alex Richardson. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,9 @@ #include #include +#if !defined(_MSC_VER) || _MSC_VER > 1600 +#include +#endif #include #define JPEG_INTERNALS #include @@ -109,9 +112,6 @@ typedef struct _tjinstance { char errStr[JMSG_LENGTH_MAX]; boolean isInstanceError; /* Parameters */ -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - int maxPixels; -#endif boolean bottomUp; boolean noRealloc; int quality; @@ -136,6 +136,8 @@ typedef struct _tjinstance { int densityUnits; tjscalingfactor scalingFactor; tjregion croppingRegion; + int maxMemory; + int maxPixels; } tjinstance; static tjhandle _tjInitCompress(tjinstance *this); @@ -335,6 +337,7 @@ static void setCompDefaults(tjinstance *this, int pixelFormat) this->cinfo.X_density = (UINT16)this->xDensity; this->cinfo.Y_density = (UINT16)this->yDensity; this->cinfo.density_unit = (UINT8)this->densityUnits; + this->cinfo.mem->max_memory_to_use = (long)this->maxMemory * 1048576L; if (this->lossless) { #ifdef C_LOSSLESS_SUPPORTED @@ -370,7 +373,8 @@ static void setCompDefaults(tjinstance *this, int pixelFormat) jpeg_set_colorspace(&this->cinfo, JCS_YCbCr); } - this->cinfo.optimize_coding = this->optimize; + if (this->cinfo.data_precision == 8) + this->cinfo.optimize_coding = this->optimize; #ifdef C_PROGRESSIVE_SUPPORTED if (this->progressive) jpeg_simple_progression(&this->cinfo); #endif @@ -569,6 +573,83 @@ bailout: } +/* TurboJPEG 3+ */ +DLLEXPORT void tj3Destroy(tjhandle handle) +{ + tjinstance *this = (tjinstance *)handle; + j_compress_ptr cinfo = NULL; + j_decompress_ptr dinfo = NULL; + + if (!this) return; + + cinfo = &this->cinfo; dinfo = &this->dinfo; + this->jerr.warning = FALSE; + this->isInstanceError = FALSE; + + if (setjmp(this->jerr.setjmp_buffer)) return; + if (this->init & COMPRESS) jpeg_destroy_compress(cinfo); + if (this->init & DECOMPRESS) jpeg_destroy_decompress(dinfo); + free(this); +} + +/* TurboJPEG 1.0+ */ +DLLEXPORT int tjDestroy(tjhandle handle) +{ + static const char FUNCTION_NAME[] = "tjDestroy"; + int retval = 0; + + if (!handle) THROWG("Invalid handle", -1); + + SNPRINTF(errStr, JMSG_LENGTH_MAX, "No error"); + tj3Destroy(handle); + if (strcmp(errStr, "No error")) retval = -1; + +bailout: + return retval; +} + + +/* TurboJPEG 3+ */ +DLLEXPORT char *tj3GetErrorStr(tjhandle handle) +{ + tjinstance *this = (tjinstance *)handle; + + if (this && this->isInstanceError) { + this->isInstanceError = FALSE; + return this->errStr; + } else + return errStr; +} + +/* TurboJPEG 2.0+ */ +DLLEXPORT char *tjGetErrorStr2(tjhandle handle) +{ + return tj3GetErrorStr(handle); +} + +/* TurboJPEG 1.0+ */ +DLLEXPORT char *tjGetErrorStr(void) +{ + return errStr; +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3GetErrorCode(tjhandle handle) +{ + tjinstance *this = (tjinstance *)handle; + + if (this && this->jerr.warning) return TJERR_WARNING; + else return TJERR_FATAL; +} + +/* TurboJPEG 2.0+ */ +DLLEXPORT int tjGetErrorCode(tjhandle handle) +{ + return tj3GetErrorCode(handle); +} + + #define SET_PARAM(field, minValue, maxValue) { \ if (value < minValue || (maxValue > 0 && value > maxValue)) \ THROW("Parameter value out of range"); \ @@ -590,11 +671,6 @@ DLLEXPORT int tj3Set(tjhandle handle, int param, int value) GET_TJINSTANCE(handle, -1); switch (param) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - case TJPARAM_MAXPIXELS: - SET_PARAM(maxPixels, 0, -1); - break; -#endif case TJPARAM_STOPONWARNING: SET_BOOL_PARAM(jerr.stopOnWarning); break; @@ -704,6 +780,12 @@ DLLEXPORT int tj3Set(tjhandle handle, int param, int value) THROW("TJPARAM_DENSITYUNITS is read-only in decompression instances."); SET_PARAM(densityUnits, 0, 2); break; + case TJPARAM_MAXMEMORY: + SET_PARAM(maxMemory, 0, (int)(min(LONG_MAX / 1048576L, (long)INT_MAX))); + break; + case TJPARAM_MAXPIXELS: + SET_PARAM(maxPixels, 0, -1); + break; default: THROW("Invalid parameter"); } @@ -766,111 +848,25 @@ DLLEXPORT int tj3Get(tjhandle handle, int param) return this->yDensity; case TJPARAM_DENSITYUNITS: return this->densityUnits; + case TJPARAM_MAXMEMORY: + return this->maxMemory; + case TJPARAM_MAXPIXELS: + return this->maxPixels; } return -1; } -/* TurboJPEG 3+ */ -DLLEXPORT char *tj3GetErrorStr(tjhandle handle) -{ - tjinstance *this = (tjinstance *)handle; - - if (this && this->isInstanceError) { - this->isInstanceError = FALSE; - return this->errStr; - } else - return errStr; -} - -/* TurboJPEG 2.0+ */ -DLLEXPORT char *tjGetErrorStr2(tjhandle handle) -{ - return tj3GetErrorStr(handle); -} - -/* TurboJPEG 1.0+ */ -DLLEXPORT char *tjGetErrorStr(void) -{ - return errStr; -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3GetErrorCode(tjhandle handle) -{ - tjinstance *this = (tjinstance *)handle; - - if (this && this->jerr.warning) return TJERR_WARNING; - else return TJERR_FATAL; -} - -/* TurboJPEG 2.0+ */ -DLLEXPORT int tjGetErrorCode(tjhandle handle) -{ - return tj3GetErrorCode(handle); -} - - -/* TurboJPEG 3+ */ -DLLEXPORT void tj3Destroy(tjhandle handle) -{ - tjinstance *this = (tjinstance *)handle; - j_compress_ptr cinfo = NULL; - j_decompress_ptr dinfo = NULL; - - if (!this) return; - - cinfo = &this->cinfo; dinfo = &this->dinfo; - this->jerr.warning = FALSE; - this->isInstanceError = FALSE; - - if (setjmp(this->jerr.setjmp_buffer)) return; - if (this->init & COMPRESS) jpeg_destroy_compress(cinfo); - if (this->init & DECOMPRESS) jpeg_destroy_decompress(dinfo); - free(this); -} - -/* TurboJPEG 1.0+ */ -DLLEXPORT int tjDestroy(tjhandle handle) -{ - static const char FUNCTION_NAME[] = "tjDestroy"; - int retval = 0; - - if (!handle) THROWG("Invalid handle", -1); - - SNPRINTF(errStr, JMSG_LENGTH_MAX, "No error"); - tj3Destroy(handle); - if (strcmp(errStr, "No error")) retval = -1; - -bailout: - return retval; -} - - /* These are exposed mainly because Windows can't malloc() and free() across DLL boundaries except when the CRT DLL is used, and we don't use the CRT DLL with turbojpeg.dll for compatibility reasons. However, these functions can potentially be used for other purposes by different implementations. */ -/* TurboJPEG 3+ */ -DLLEXPORT void tj3Free(void *buf) -{ - free(buf); -} - -/* TurboJPEG 1.2+ */ -DLLEXPORT void tjFree(unsigned char *buf) -{ - tj3Free(buf); -} - - /* TurboJPEG 3+ */ DLLEXPORT void *tj3Alloc(size_t bytes) { - return malloc(bytes); + return MALLOC(bytes); } /* TurboJPEG 1.2+ */ @@ -880,42 +876,16 @@ DLLEXPORT unsigned char *tjAlloc(int bytes) } -/******************************** Compressor *********************************/ - -static tjhandle _tjInitCompress(tjinstance *this) +/* TurboJPEG 3+ */ +DLLEXPORT void tj3Free(void *buf) { - static unsigned char buffer[1]; - unsigned char *buf = buffer; - size_t size = 1; - - /* This is also straight out of example.c */ - this->cinfo.err = jpeg_std_error(&this->jerr.pub); - this->jerr.pub.error_exit = my_error_exit; - this->jerr.pub.output_message = my_output_message; - this->jerr.emit_message = this->jerr.pub.emit_message; - this->jerr.pub.emit_message = my_emit_message; - this->jerr.pub.addon_message_table = turbojpeg_message_table; - this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE; - this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE; - - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - free(this); - return NULL; - } - - jpeg_create_compress(&this->cinfo); - /* Make an initial call so it will create the destination manager */ - jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); - - this->init |= COMPRESS; - return (tjhandle)this; + free(buf); } -/* TurboJPEG 1.0+ */ -DLLEXPORT tjhandle tjInitCompress(void) +/* TurboJPEG 1.2+ */ +DLLEXPORT void tjFree(unsigned char *buf) { - return tj3Init(TJINIT_COMPRESS); + tj3Free(buf); } @@ -940,8 +910,10 @@ DLLEXPORT size_t tj3JPEGBufSize(int width, int height, int jpegSubsamp) mcuh = tjMCUHeight[jpegSubsamp]; chromasf = jpegSubsamp == TJSAMP_GRAY ? 0 : 4 * 64 / (mcuw * mcuh); retval = PAD(width, mcuw) * PAD(height, mcuh) * (2ULL + chromasf) + 2048ULL; +#if ULLONG_MAX > ULONG_MAX if (retval > (unsigned long long)((unsigned long)-1)) THROWG("Image is too large", 0); +#endif bailout: return (size_t)retval; @@ -975,8 +947,10 @@ DLLEXPORT unsigned long TJBUFSIZE(int width, int height) larger than the uncompressed input (we wouldn't mention it if it hadn't happened before.) */ retval = PAD(width, 16) * PAD(height, 16) * 6ULL + 2048ULL; +#if ULLONG_MAX > ULONG_MAX if (retval > (unsigned long long)((unsigned long)-1)) THROWG("Image is too large", (unsigned long)-1); +#endif bailout: return (unsigned long)retval; @@ -1002,8 +976,10 @@ DLLEXPORT size_t tj3YUVBufSize(int width, int align, int height, int subsamp) if (pw == 0 || ph == 0) return 0; else retval += (unsigned long long)stride * ph; } +#if ULLONG_MAX > ULONG_MAX if (retval > (unsigned long long)((unsigned long)-1)) THROWG("Image is too large", 0); +#endif bailout: return (size_t)retval; @@ -1031,34 +1007,71 @@ DLLEXPORT unsigned long TJBUFSIZEYUV(int width, int height, int subsamp) /* TurboJPEG 3+ */ -DLLEXPORT int tj3YUVPlaneWidth(int componentID, int width, int subsamp) +DLLEXPORT size_t tj3YUVPlaneSize(int componentID, int width, int stride, + int height, int subsamp) { - static const char FUNCTION_NAME[] = "tj3YUVPlaneWidth"; - unsigned long long pw, retval = 0; - int nc; + static const char FUNCTION_NAME[] = "tj3YUVPlaneSize"; + unsigned long long retval = 0; + int pw, ph; - if (width < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROWG("Invalid argument", 0); - nc = (subsamp == TJSAMP_GRAY ? 1 : 3); - if (componentID < 0 || componentID >= nc) + if (width < 1 || height < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) THROWG("Invalid argument", 0); - pw = PAD((unsigned long long)width, tjMCUWidth[subsamp] / 8); - if (componentID == 0) - retval = pw; - else - retval = pw * 8 / tjMCUWidth[subsamp]; + pw = tj3YUVPlaneWidth(componentID, width, subsamp); + ph = tj3YUVPlaneHeight(componentID, height, subsamp); + if (pw == 0 || ph == 0) return 0; - if (retval > (unsigned long long)INT_MAX) - THROWG("Width is too large", 0); + if (stride == 0) stride = pw; + else stride = abs(stride); + + retval = (unsigned long long)stride * (ph - 1) + pw; +#if ULLONG_MAX > ULONG_MAX + if (retval > (unsigned long long)((unsigned long)-1)) + THROWG("Image is too large", 0); +#endif bailout: - return (int)retval; + return (size_t)retval; } /* TurboJPEG 1.4+ */ -DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp) -{ +DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride, + int height, int subsamp) +{ + size_t retval = tj3YUVPlaneSize(componentID, width, stride, height, subsamp); + return (retval == 0) ? -1 : (unsigned long)retval; +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3YUVPlaneWidth(int componentID, int width, int subsamp) +{ + static const char FUNCTION_NAME[] = "tj3YUVPlaneWidth"; + unsigned long long pw, retval = 0; + int nc; + + if (width < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) + THROWG("Invalid argument", 0); + nc = (subsamp == TJSAMP_GRAY ? 1 : 3); + if (componentID < 0 || componentID >= nc) + THROWG("Invalid argument", 0); + + pw = PAD((unsigned long long)width, tjMCUWidth[subsamp] / 8); + if (componentID == 0) + retval = pw; + else + retval = pw * 8 / tjMCUWidth[subsamp]; + + if (retval > (unsigned long long)INT_MAX) + THROWG("Width is too large", 0); + +bailout: + return (int)retval; +} + +/* TurboJPEG 1.4+ */ +DLLEXPORT int tjPlaneWidth(int componentID, int width, int subsamp) +{ int retval = tj3YUVPlaneWidth(componentID, width, subsamp); return (retval == 0) ? -1 : retval; } @@ -1098,38 +1111,42 @@ DLLEXPORT int tjPlaneHeight(int componentID, int height, int subsamp) } -/* TurboJPEG 3+ */ -DLLEXPORT size_t tj3YUVPlaneSize(int componentID, int width, int stride, - int height, int subsamp) -{ - static const char FUNCTION_NAME[] = "tj3YUVPlaneSize"; - unsigned long long retval = 0; - int pw, ph; +/******************************** Compressor *********************************/ - if (width < 1 || height < 1 || subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROWG("Invalid argument", 0); +static tjhandle _tjInitCompress(tjinstance *this) +{ + static unsigned char buffer[1]; + unsigned char *buf = buffer; + size_t size = 1; - pw = tj3YUVPlaneWidth(componentID, width, subsamp); - ph = tj3YUVPlaneHeight(componentID, height, subsamp); - if (pw == 0 || ph == 0) return 0; + /* This is also straight out of example.c */ + this->cinfo.err = jpeg_std_error(&this->jerr.pub); + this->jerr.pub.error_exit = my_error_exit; + this->jerr.pub.output_message = my_output_message; + this->jerr.emit_message = this->jerr.pub.emit_message; + this->jerr.pub.emit_message = my_emit_message; + this->jerr.pub.addon_message_table = turbojpeg_message_table; + this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE; + this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE; - if (stride == 0) stride = pw; - else stride = abs(stride); + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + free(this); + return NULL; + } - retval = (unsigned long long)stride * (ph - 1) + pw; - if (retval > (unsigned long long)((unsigned long)-1)) - THROWG("Image is too large", 0); + jpeg_create_compress(&this->cinfo); + /* Make an initial call so it will create the destination manager */ + jpeg_mem_dest_tj(&this->cinfo, &buf, &size, 0); -bailout: - return (size_t)retval; + this->init |= COMPRESS; + return (tjhandle)this; } -/* TurboJPEG 1.4+ */ -DLLEXPORT unsigned long tjPlaneSizeYUV(int componentID, int width, int stride, - int height, int subsamp) +/* TurboJPEG 1.0+ */ +DLLEXPORT tjhandle tjInitCompress(void) { - size_t retval = tj3YUVPlaneSize(componentID, width, stride, height, subsamp); - return (retval == 0) ? -1 : (unsigned long)retval; + return tj3Init(TJINIT_COMPRESS); } @@ -1198,43 +1215,39 @@ DLLEXPORT int tjCompress(tjhandle handle, unsigned char *srcBuf, int width, /* TurboJPEG 3+ */ -DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, - int pixelFormat, unsigned char **dstPlanes, - int *strides) +DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle, + const unsigned char * const *srcPlanes, + int width, const int *strides, + int height, unsigned char **jpegBuf, + size_t *jpegSize) { - static const char FUNCTION_NAME[] = "tj3EncodeYUVPlanes8"; - JSAMPROW *row_pointer = NULL; - JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; - JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; - JSAMPROW *outbuf[MAX_COMPONENTS]; - int i, retval = 0, row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; - JSAMPLE *ptr; - jpeg_component_info *compptr; + static const char FUNCTION_NAME[] = "tj3CompressFromYUVPlanes8"; + int i, row, retval = 0; + boolean alloc = TRUE; + int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], + tmpbufsize = 0, usetmpbuf = 0, th[MAX_COMPONENTS]; + JSAMPLE *_tmpbuf = NULL, *ptr; + JSAMPROW *inbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; GET_CINSTANCE(handle) for (i = 0; i < MAX_COMPONENTS; i++) { - tmpbuf[i] = NULL; _tmpbuf[i] = NULL; - tmpbuf2[i] = NULL; _tmpbuf2[i] = NULL; outbuf[i] = NULL; + tmpbuf[i] = NULL; inbuf[i] = NULL; } if ((this->init & COMPRESS) == 0) THROW("Instance has not been initialized for compression"); - if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || - pixelFormat < 0 || pixelFormat >= TJ_NUMPF || !dstPlanes || - !dstPlanes[0]) + if (!srcPlanes || !srcPlanes[0] || width <= 0 || height <= 0 || + jpegBuf == NULL || jpegSize == NULL) THROW("Invalid argument"); - if (this->subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) + if (this->subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) THROW("Invalid argument"); + if (this->quality == -1) + THROW("TJPARAM_QUALITY must be specified"); if (this->subsamp == TJSAMP_UNKNOWN) THROW("TJPARAM_SUBSAMP must be specified"); - if (pixelFormat == TJPF_CMYK) - THROW("Cannot generate YUV images from packed-pixel CMYK images"); - - if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ @@ -1245,319 +1258,58 @@ DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, cinfo->image_height = height; cinfo->data_precision = 8; - setCompDefaults(this, pixelFormat); - - /* Execute only the parts of jpeg_start_compress() that we need. If we - were to call the whole jpeg_start_compress() function, then it would try - to write the file headers, which could overflow the output buffer if the - YUV image were very small. */ - if (cinfo->global_state != CSTATE_START) - THROW("libjpeg API is in the wrong state"); - (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo); - jinit_c_master_control(cinfo, FALSE); - jinit_color_converter(cinfo); - jinit_downsampler(cinfo); - (*cinfo->cconvert->start_pass) (cinfo); - - pw0 = PAD(width, cinfo->max_h_samp_factor); - ph0 = PAD(height, cinfo->max_v_samp_factor); - - if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL) - THROW("Memory allocation failure"); - for (i = 0; i < height; i++) { - if (this->bottomUp) - row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; - else - row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch]; + if (this->noRealloc) { + alloc = FALSE; *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); } - if (height < ph0) - for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1]; + jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); + setCompDefaults(this, TJPF_RGB); + cinfo->raw_data_in = TRUE; + jpeg_start_compress(cinfo, TRUE); for (i = 0; i < cinfo->num_components; i++) { - compptr = &cinfo->comp_info[i]; - _tmpbuf[i] = (JSAMPLE *)malloc( - PAD((compptr->width_in_blocks * cinfo->max_h_samp_factor * DCTSIZE) / - compptr->h_samp_factor, 32) * - cinfo->max_v_samp_factor + 32); - if (!_tmpbuf[i]) - THROW("Memory allocation failure"); - tmpbuf[i] = - (JSAMPROW *)malloc(sizeof(JSAMPROW) * cinfo->max_v_samp_factor); - if (!tmpbuf[i]) - THROW("Memory allocation failure"); - for (row = 0; row < cinfo->max_v_samp_factor; row++) { - unsigned char *_tmpbuf_aligned = - (unsigned char *)PAD((JUINTPTR)_tmpbuf[i], 32); - - tmpbuf[i][row] = &_tmpbuf_aligned[ - PAD((compptr->width_in_blocks * cinfo->max_h_samp_factor * DCTSIZE) / - compptr->h_samp_factor, 32) * row]; - } - _tmpbuf2[i] = - (JSAMPLE *)malloc(PAD(compptr->width_in_blocks * DCTSIZE, 32) * - compptr->v_samp_factor + 32); - if (!_tmpbuf2[i]) - THROW("Memory allocation failure"); - tmpbuf2[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor); - if (!tmpbuf2[i]) - THROW("Memory allocation failure"); - for (row = 0; row < compptr->v_samp_factor; row++) { - unsigned char *_tmpbuf2_aligned = - (unsigned char *)PAD((JUINTPTR)_tmpbuf2[i], 32); + jpeg_component_info *compptr = &cinfo->comp_info[i]; + int ih; - tmpbuf2[i][row] = - &_tmpbuf2_aligned[PAD(compptr->width_in_blocks * DCTSIZE, 32) * row]; - } - pw[i] = pw0 * compptr->h_samp_factor / cinfo->max_h_samp_factor; - ph[i] = ph0 * compptr->v_samp_factor / cinfo->max_v_samp_factor; - outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); - if (!outbuf[i]) + iw[i] = compptr->width_in_blocks * DCTSIZE; + ih = compptr->height_in_blocks * DCTSIZE; + pw[i] = PAD(cinfo->image_width, cinfo->max_h_samp_factor) * + compptr->h_samp_factor / cinfo->max_h_samp_factor; + ph[i] = PAD(cinfo->image_height, cinfo->max_v_samp_factor) * + compptr->v_samp_factor / cinfo->max_v_samp_factor; + if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1; + th[i] = compptr->v_samp_factor * DCTSIZE; + tmpbufsize += iw[i] * th[i]; + if ((inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) THROW("Memory allocation failure"); - ptr = dstPlanes[i]; + ptr = (JSAMPLE *)srcPlanes[i]; for (row = 0; row < ph[i]; row++) { - outbuf[i][row] = ptr; + inbuf[i][row] = ptr; ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; } } + if (usetmpbuf) { + if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) + THROW("Memory allocation failure"); + ptr = _tmpbuf; + for (i = 0; i < cinfo->num_components; i++) { + if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) + THROW("Memory allocation failure"); + for (row = 0; row < th[i]; row++) { + tmpbuf[i][row] = ptr; + ptr += iw[i]; + } + } + } if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval = -1; goto bailout; } - for (row = 0; row < ph0; row += cinfo->max_v_samp_factor) { - (*cinfo->cconvert->color_convert) (cinfo, &row_pointer[row], tmpbuf, 0, - cinfo->max_v_samp_factor); - (cinfo->downsample->downsample) (cinfo, tmpbuf, 0, tmpbuf2, 0); - for (i = 0, compptr = cinfo->comp_info; i < cinfo->num_components; - i++, compptr++) - jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], - row * compptr->v_samp_factor / cinfo->max_v_samp_factor, - compptr->v_samp_factor, pw[i]); - } - cinfo->next_scanline += height; - jpeg_abort_compress(cinfo); - -bailout: - if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); - free(row_pointer); - for (i = 0; i < MAX_COMPONENTS; i++) { - free(tmpbuf[i]); - free(_tmpbuf[i]); - free(tmpbuf2[i]); - free(_tmpbuf2[i]); - free(outbuf[i]); - } - if (this->jerr.warning) retval = -1; - return retval; -} - -/* TurboJPEG 1.4+ */ -DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, - int pixelFormat, unsigned char **dstPlanes, - int *strides, int subsamp, int flags) -{ - static const char FUNCTION_NAME[] = "tjEncodeYUVPlanes"; - int retval = 0; - - GET_TJINSTANCE(handle, -1); - - if (subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROW("Invalid argument"); - - this->subsamp = subsamp; - processFlags(handle, flags, COMPRESS); - - return tj3EncodeYUVPlanes8(handle, srcBuf, width, pitch, height, pixelFormat, - dstPlanes, strides); - -bailout: - return retval; -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, int pixelFormat, - unsigned char *dstBuf, int align) -{ - static const char FUNCTION_NAME[] = "tj3EncodeYUV8"; - unsigned char *dstPlanes[3]; - int pw0, ph0, strides[3], retval = -1; - - GET_TJINSTANCE(handle, -1); - - if (width <= 0 || height <= 0 || dstBuf == NULL || align < 1 || - !IS_POW2(align)) - THROW("Invalid argument"); - - if (this->subsamp == TJSAMP_UNKNOWN) - THROW("TJPARAM_SUBSAMP must be specified"); - - pw0 = tj3YUVPlaneWidth(0, width, this->subsamp); - ph0 = tj3YUVPlaneHeight(0, height, this->subsamp); - dstPlanes[0] = dstBuf; - strides[0] = PAD(pw0, align); - if (this->subsamp == TJSAMP_GRAY) { - strides[1] = strides[2] = 0; - dstPlanes[1] = dstPlanes[2] = NULL; - } else { - int pw1 = tj3YUVPlaneWidth(1, width, this->subsamp); - int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp); - - strides[1] = strides[2] = PAD(pw1, align); - dstPlanes[1] = dstPlanes[0] + strides[0] * ph0; - dstPlanes[2] = dstPlanes[1] + strides[1] * ph1; - } - - return tj3EncodeYUVPlanes8(handle, srcBuf, width, pitch, height, pixelFormat, - dstPlanes, strides); - -bailout: - return retval; -} - -/* TurboJPEG 1.4+ */ -DLLEXPORT int tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, int pixelFormat, - unsigned char *dstBuf, int align, int subsamp, - int flags) -{ - static const char FUNCTION_NAME[] = "tjEncodeYUV3"; - int retval = 0; - - GET_TJINSTANCE(handle, -1); - - if (subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROW("Invalid argument"); - - this->subsamp = subsamp; - processFlags(handle, flags, COMPRESS); - - return tj3EncodeYUV8(handle, srcBuf, width, pitch, height, pixelFormat, - dstBuf, align); - -bailout: - return retval; -} - -/* TurboJPEG 1.2+ */ -DLLEXPORT int tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, int width, - int pitch, int height, int pixelFormat, - unsigned char *dstBuf, int subsamp, int flags) -{ - return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat, - dstBuf, 4, subsamp, flags); -} - -/* TurboJPEG 1.1+ */ -DLLEXPORT int tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, int width, - int pitch, int height, int pixelSize, - unsigned char *dstBuf, int subsamp, int flags) -{ - return tjEncodeYUV2(handle, srcBuf, width, pitch, height, - getPixelFormat(pixelSize, flags), dstBuf, subsamp, - flags); -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle, - const unsigned char * const *srcPlanes, - int width, const int *strides, - int height, unsigned char **jpegBuf, - size_t *jpegSize) -{ - static const char FUNCTION_NAME[] = "tj3CompressFromYUVPlanes8"; - int i, row, retval = 0; - boolean alloc = TRUE; - int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], - tmpbufsize = 0, usetmpbuf = 0, th[MAX_COMPONENTS]; - JSAMPLE *_tmpbuf = NULL, *ptr; - JSAMPROW *inbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; - - GET_CINSTANCE(handle) - - for (i = 0; i < MAX_COMPONENTS; i++) { - tmpbuf[i] = NULL; inbuf[i] = NULL; - } - - if ((this->init & COMPRESS) == 0) - THROW("Instance has not been initialized for compression"); - - if (!srcPlanes || !srcPlanes[0] || width <= 0 || height <= 0 || - jpegBuf == NULL || jpegSize == NULL) - THROW("Invalid argument"); - if (this->subsamp != TJSAMP_GRAY && (!srcPlanes[1] || !srcPlanes[2])) - THROW("Invalid argument"); - - if (this->quality == -1) - THROW("TJPARAM_QUALITY must be specified"); - if (this->subsamp == TJSAMP_UNKNOWN) - THROW("TJPARAM_SUBSAMP must be specified"); - - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - cinfo->image_width = width; - cinfo->image_height = height; - cinfo->data_precision = 8; - - if (this->noRealloc) { - alloc = FALSE; *jpegSize = tj3JPEGBufSize(width, height, this->subsamp); - } - jpeg_mem_dest_tj(cinfo, jpegBuf, jpegSize, alloc); - setCompDefaults(this, TJPF_RGB); - cinfo->raw_data_in = TRUE; - - jpeg_start_compress(cinfo, TRUE); - for (i = 0; i < cinfo->num_components; i++) { - jpeg_component_info *compptr = &cinfo->comp_info[i]; - int ih; - - iw[i] = compptr->width_in_blocks * DCTSIZE; - ih = compptr->height_in_blocks * DCTSIZE; - pw[i] = PAD(cinfo->image_width, cinfo->max_h_samp_factor) * - compptr->h_samp_factor / cinfo->max_h_samp_factor; - ph[i] = PAD(cinfo->image_height, cinfo->max_v_samp_factor) * - compptr->v_samp_factor / cinfo->max_v_samp_factor; - if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1; - th[i] = compptr->v_samp_factor * DCTSIZE; - tmpbufsize += iw[i] * th[i]; - if ((inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) - THROW("Memory allocation failure"); - ptr = (JSAMPLE *)srcPlanes[i]; - for (row = 0; row < ph[i]; row++) { - inbuf[i][row] = ptr; - ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; - } - } - if (usetmpbuf) { - if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) - THROW("Memory allocation failure"); - ptr = _tmpbuf; - for (i = 0; i < cinfo->num_components; i++) { - if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) - THROW("Memory allocation failure"); - for (row = 0; row < th[i]; row++) { - tmpbuf[i][row] = ptr; - ptr += iw[i]; - } - } - } - - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - for (row = 0; row < (int)cinfo->image_height; - row += cinfo->max_v_samp_factor * DCTSIZE) { - JSAMPARRAY yuvptr[MAX_COMPONENTS]; - int crow[MAX_COMPONENTS]; + for (row = 0; row < (int)cinfo->image_height; + row += cinfo->max_v_samp_factor * DCTSIZE) { + JSAMPARRAY yuvptr[MAX_COMPONENTS]; + int crow[MAX_COMPONENTS]; for (i = 0; i < cinfo->num_components; i++) { jpeg_component_info *compptr = &cinfo->comp_info[i]; @@ -1584,10 +1336,10 @@ DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle, jpeg_finish_compress(cinfo); bailout: - if (cinfo->global_state > CSTATE_START) { - if (alloc) (*cinfo->dest->term_destination) (cinfo); + if (cinfo->global_state > CSTATE_START && alloc) + (*cinfo->dest->term_destination) (cinfo); + if (cinfo->global_state > CSTATE_START || retval == -1) jpeg_abort_compress(cinfo); - } for (i = 0; i < MAX_COMPONENTS; i++) { free(tmpbuf[i]); free(inbuf[i]); @@ -1661,6 +1413,11 @@ DLLEXPORT int tj3CompressFromYUV8(tjhandle handle, int ph1 = tjPlaneHeight(1, height, this->subsamp); strides[1] = strides[2] = PAD(pw1, align); + if ((unsigned long long)strides[0] * (unsigned long long)ph0 > + (unsigned long long)INT_MAX || + (unsigned long long)strides[1] * (unsigned long long)ph1 > + (unsigned long long)INT_MAX) + THROW("Image or row alignment is too large"); srcPlanes[1] = srcPlanes[0] + strides[0] * ph0; srcPlanes[2] = srcPlanes[1] + strides[1] * ph1; } @@ -1702,182 +1459,452 @@ bailout: } -/******************************* Decompressor ********************************/ - -static tjhandle _tjInitDecompress(tjinstance *this) +/* TurboJPEG 3+ */ +DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, + int pixelFormat, unsigned char **dstPlanes, + int *strides) { - static unsigned char buffer[1]; + static const char FUNCTION_NAME[] = "tj3EncodeYUVPlanes8"; + JSAMPROW *row_pointer = NULL; + JSAMPLE *_tmpbuf[MAX_COMPONENTS], *_tmpbuf2[MAX_COMPONENTS]; + JSAMPROW *tmpbuf[MAX_COMPONENTS], *tmpbuf2[MAX_COMPONENTS]; + JSAMPROW *outbuf[MAX_COMPONENTS]; + int i, retval = 0, row, pw0, ph0, pw[MAX_COMPONENTS], ph[MAX_COMPONENTS]; + JSAMPLE *ptr; + jpeg_component_info *compptr; - /* This is also straight out of example.c */ - this->dinfo.err = jpeg_std_error(&this->jerr.pub); - this->jerr.pub.error_exit = my_error_exit; - this->jerr.pub.output_message = my_output_message; - this->jerr.emit_message = this->jerr.pub.emit_message; - this->jerr.pub.emit_message = my_emit_message; - this->jerr.pub.addon_message_table = turbojpeg_message_table; - this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE; - this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE; + GET_CINSTANCE(handle) - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - free(this); - return NULL; + for (i = 0; i < MAX_COMPONENTS; i++) { + tmpbuf[i] = NULL; _tmpbuf[i] = NULL; + tmpbuf2[i] = NULL; _tmpbuf2[i] = NULL; outbuf[i] = NULL; } - jpeg_create_decompress(&this->dinfo); - /* Make an initial call so it will create the source manager */ - jpeg_mem_src_tj(&this->dinfo, buffer, 1); - - this->init |= DECOMPRESS; - return (tjhandle)this; -} + if ((this->init & COMPRESS) == 0) + THROW("Instance has not been initialized for compression"); -/* TurboJPEG 1.0+ */ -DLLEXPORT tjhandle tjInitDecompress(void) -{ - return tj3Init(TJINIT_DECOMPRESS); -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3DecompressHeader(tjhandle handle, - const unsigned char *jpegBuf, - size_t jpegSize) -{ - static const char FUNCTION_NAME[] = "tj3DecompressHeader"; - int retval = 0; + if (srcBuf == NULL || width <= 0 || pitch < 0 || height <= 0 || + pixelFormat < 0 || pixelFormat >= TJ_NUMPF || !dstPlanes || + !dstPlanes[0]) + THROW("Invalid argument"); + if (this->subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) + THROW("Invalid argument"); - GET_DINSTANCE(handle); - if ((this->init & DECOMPRESS) == 0) - THROW("Instance has not been initialized for decompression"); + if (this->subsamp == TJSAMP_UNKNOWN) + THROW("TJPARAM_SUBSAMP must be specified"); + if (pixelFormat == TJPF_CMYK) + THROW("Cannot generate YUV images from packed-pixel CMYK images"); - if (jpegBuf == NULL || jpegSize <= 0) - THROW("Invalid argument"); + if (pitch == 0) pitch = width * tjPixelSize[pixelFormat]; if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ - return -1; + retval = -1; goto bailout; } - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + cinfo->image_width = width; + cinfo->image_height = height; + cinfo->data_precision = 8; - /* jpeg_read_header() calls jpeg_abort() and returns JPEG_HEADER_TABLES_ONLY - if the datastream is a tables-only datastream. Since we aren't using a - suspending data source, the only other value it can return is - JPEG_HEADER_OK. */ - if (jpeg_read_header(dinfo, FALSE) == JPEG_HEADER_TABLES_ONLY) - return 0; + setCompDefaults(this, pixelFormat); - setDecompParameters(this); + /* Execute only the parts of jpeg_start_compress() that we need. If we + were to call the whole jpeg_start_compress() function, then it would try + to write the file headers, which could overflow the output buffer if the + YUV image were very small. */ + if (cinfo->global_state != CSTATE_START) + THROW("libjpeg API is in the wrong state"); + (*cinfo->err->reset_error_mgr) ((j_common_ptr)cinfo); + jinit_c_master_control(cinfo, FALSE); + jinit_color_converter(cinfo); + jinit_downsampler(cinfo); + (*cinfo->cconvert->start_pass) (cinfo); - jpeg_abort_decompress(dinfo); + pw0 = PAD(width, cinfo->max_h_samp_factor); + ph0 = PAD(height, cinfo->max_v_samp_factor); - if (this->colorspace < 0) - THROW("Could not determine colorspace of JPEG image"); - if (this->jpegWidth < 1 || this->jpegHeight < 1) - THROW("Invalid data returned in header"); + if ((row_pointer = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph0)) == NULL) + THROW("Memory allocation failure"); + for (i = 0; i < height; i++) { + if (this->bottomUp) + row_pointer[i] = (JSAMPROW)&srcBuf[(height - i - 1) * (size_t)pitch]; + else + row_pointer[i] = (JSAMPROW)&srcBuf[i * (size_t)pitch]; + } + if (height < ph0) + for (i = height; i < ph0; i++) row_pointer[i] = row_pointer[height - 1]; + + for (i = 0; i < cinfo->num_components; i++) { + compptr = &cinfo->comp_info[i]; + _tmpbuf[i] = (JSAMPLE *)MALLOC( + PAD((compptr->width_in_blocks * cinfo->max_h_samp_factor * DCTSIZE) / + compptr->h_samp_factor, 32) * + cinfo->max_v_samp_factor + 32); + if (!_tmpbuf[i]) + THROW("Memory allocation failure"); + tmpbuf[i] = + (JSAMPROW *)malloc(sizeof(JSAMPROW) * cinfo->max_v_samp_factor); + if (!tmpbuf[i]) + THROW("Memory allocation failure"); + for (row = 0; row < cinfo->max_v_samp_factor; row++) { + unsigned char *_tmpbuf_aligned = + (unsigned char *)PAD((JUINTPTR)_tmpbuf[i], 32); + + tmpbuf[i][row] = &_tmpbuf_aligned[ + PAD((compptr->width_in_blocks * cinfo->max_h_samp_factor * DCTSIZE) / + compptr->h_samp_factor, 32) * row]; + } + _tmpbuf2[i] = + (JSAMPLE *)MALLOC(PAD(compptr->width_in_blocks * DCTSIZE, 32) * + compptr->v_samp_factor + 32); + if (!_tmpbuf2[i]) + THROW("Memory allocation failure"); + tmpbuf2[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * compptr->v_samp_factor); + if (!tmpbuf2[i]) + THROW("Memory allocation failure"); + for (row = 0; row < compptr->v_samp_factor; row++) { + unsigned char *_tmpbuf2_aligned = + (unsigned char *)PAD((JUINTPTR)_tmpbuf2[i], 32); + + tmpbuf2[i][row] = + &_tmpbuf2_aligned[PAD(compptr->width_in_blocks * DCTSIZE, 32) * row]; + } + pw[i] = pw0 * compptr->h_samp_factor / cinfo->max_h_samp_factor; + ph[i] = ph0 * compptr->v_samp_factor / cinfo->max_v_samp_factor; + outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); + if (!outbuf[i]) + THROW("Memory allocation failure"); + ptr = dstPlanes[i]; + for (row = 0; row < ph[i]; row++) { + outbuf[i][row] = ptr; + ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; + } + } + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + for (row = 0; row < ph0; row += cinfo->max_v_samp_factor) { + (*cinfo->cconvert->color_convert) (cinfo, &row_pointer[row], tmpbuf, 0, + cinfo->max_v_samp_factor); + (cinfo->downsample->downsample) (cinfo, tmpbuf, 0, tmpbuf2, 0); + for (i = 0, compptr = cinfo->comp_info; i < cinfo->num_components; + i++, compptr++) + jcopy_sample_rows(tmpbuf2[i], 0, outbuf[i], + row * compptr->v_samp_factor / cinfo->max_v_samp_factor, + compptr->v_samp_factor, pw[i]); + } + cinfo->next_scanline += height; + jpeg_abort_compress(cinfo); bailout: + if (cinfo->global_state > CSTATE_START) jpeg_abort_compress(cinfo); + free(row_pointer); + for (i = 0; i < MAX_COMPONENTS; i++) { + free(tmpbuf[i]); + free(_tmpbuf[i]); + free(tmpbuf2[i]); + free(_tmpbuf2[i]); + free(outbuf[i]); + } if (this->jerr.warning) retval = -1; return retval; } /* TurboJPEG 1.4+ */ -DLLEXPORT int tjDecompressHeader3(tjhandle handle, - const unsigned char *jpegBuf, - unsigned long jpegSize, int *width, - int *height, int *jpegSubsamp, - int *jpegColorspace) +DLLEXPORT int tjEncodeYUVPlanes(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, + int pixelFormat, unsigned char **dstPlanes, + int *strides, int subsamp, int flags) { - static const char FUNCTION_NAME[] = "tjDecompressHeader3"; + static const char FUNCTION_NAME[] = "tjEncodeYUVPlanes"; int retval = 0; GET_TJINSTANCE(handle, -1); - if (width == NULL || height == NULL || jpegSubsamp == NULL || - jpegColorspace == NULL) + if (subsamp < 0 || subsamp >= TJ_NUMSAMP) THROW("Invalid argument"); - retval = tj3DecompressHeader(handle, jpegBuf, jpegSize); + this->subsamp = subsamp; + processFlags(handle, flags, COMPRESS); - *width = tj3Get(handle, TJPARAM_JPEGWIDTH); - *height = tj3Get(handle, TJPARAM_JPEGHEIGHT); - *jpegSubsamp = tj3Get(handle, TJPARAM_SUBSAMP); - if (*jpegSubsamp == TJSAMP_UNKNOWN) - THROW("Could not determine subsampling level of JPEG image"); - *jpegColorspace = tj3Get(handle, TJPARAM_COLORSPACE); + return tj3EncodeYUVPlanes8(handle, srcBuf, width, pitch, height, pixelFormat, + dstPlanes, strides); bailout: return retval; } -/* TurboJPEG 1.1+ */ -DLLEXPORT int tjDecompressHeader2(tjhandle handle, unsigned char *jpegBuf, - unsigned long jpegSize, int *width, - int *height, int *jpegSubsamp) -{ - int jpegColorspace; - - return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height, - jpegSubsamp, &jpegColorspace); -} -/* TurboJPEG 1.0+ */ -DLLEXPORT int tjDecompressHeader(tjhandle handle, unsigned char *jpegBuf, - unsigned long jpegSize, int *width, - int *height) +/* TurboJPEG 3+ */ +DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int align) { - int jpegSubsamp; + static const char FUNCTION_NAME[] = "tj3EncodeYUV8"; + unsigned char *dstPlanes[3]; + int pw0, ph0, strides[3], retval = -1; - return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, - &jpegSubsamp); -} + GET_TJINSTANCE(handle, -1); + if (width <= 0 || height <= 0 || dstBuf == NULL || align < 1 || + !IS_POW2(align)) + THROW("Invalid argument"); -/* TurboJPEG 3+ */ -DLLEXPORT tjscalingfactor *tj3GetScalingFactors(int *numScalingFactors) -{ - static const char FUNCTION_NAME[] = "tj3GetScalingFactors"; - tjscalingfactor *retval = (tjscalingfactor *)sf; + if (this->subsamp == TJSAMP_UNKNOWN) + THROW("TJPARAM_SUBSAMP must be specified"); - if (numScalingFactors == NULL) - THROWG("Invalid argument", NULL); + pw0 = tj3YUVPlaneWidth(0, width, this->subsamp); + ph0 = tj3YUVPlaneHeight(0, height, this->subsamp); + dstPlanes[0] = dstBuf; + strides[0] = PAD(pw0, align); + if (this->subsamp == TJSAMP_GRAY) { + strides[1] = strides[2] = 0; + dstPlanes[1] = dstPlanes[2] = NULL; + } else { + int pw1 = tj3YUVPlaneWidth(1, width, this->subsamp); + int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp); - *numScalingFactors = NUMSF; + strides[1] = strides[2] = PAD(pw1, align); + if ((unsigned long long)strides[0] * (unsigned long long)ph0 > + (unsigned long long)INT_MAX || + (unsigned long long)strides[1] * (unsigned long long)ph1 > + (unsigned long long)INT_MAX) + THROW("Image or row alignment is too large"); + dstPlanes[1] = dstPlanes[0] + strides[0] * ph0; + dstPlanes[2] = dstPlanes[1] + strides[1] * ph1; + } + + return tj3EncodeYUVPlanes8(handle, srcBuf, width, pitch, height, pixelFormat, + dstPlanes, strides); bailout: return retval; } -/* TurboJPEG 1.2+ */ -DLLEXPORT tjscalingfactor *tjGetScalingFactors(int *numScalingFactors) -{ - return tj3GetScalingFactors(numScalingFactors); -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3SetScalingFactor(tjhandle handle, - tjscalingfactor scalingFactor) +/* TurboJPEG 1.4+ */ +DLLEXPORT int tjEncodeYUV3(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int align, int subsamp, + int flags) { - static const char FUNCTION_NAME[] = "tj3SetScalingFactor"; - int i, retval = 0; + static const char FUNCTION_NAME[] = "tjEncodeYUV3"; + int retval = 0; GET_TJINSTANCE(handle, -1); - if ((this->init & DECOMPRESS) == 0) - THROW("Instance has not been initialized for decompression"); - for (i = 0; i < NUMSF; i++) { - if (scalingFactor.num == sf[i].num && scalingFactor.denom == sf[i].denom) - break; - } - if (i >= NUMSF) - THROW("Unsupported scaling factor"); + if (subsamp < 0 || subsamp >= TJ_NUMSAMP) + THROW("Invalid argument"); - this->scalingFactor = scalingFactor; + this->subsamp = subsamp; + processFlags(handle, flags, COMPRESS); -bailout: - return retval; + return tj3EncodeYUV8(handle, srcBuf, width, pitch, height, pixelFormat, + dstBuf, align); + +bailout: + return retval; +} + +/* TurboJPEG 1.2+ */ +DLLEXPORT int tjEncodeYUV2(tjhandle handle, unsigned char *srcBuf, int width, + int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int subsamp, int flags) +{ + return tjEncodeYUV3(handle, srcBuf, width, pitch, height, pixelFormat, + dstBuf, 4, subsamp, flags); +} + +/* TurboJPEG 1.1+ */ +DLLEXPORT int tjEncodeYUV(tjhandle handle, unsigned char *srcBuf, int width, + int pitch, int height, int pixelSize, + unsigned char *dstBuf, int subsamp, int flags) +{ + return tjEncodeYUV2(handle, srcBuf, width, pitch, height, + getPixelFormat(pixelSize, flags), dstBuf, subsamp, + flags); +} + + +/******************************* Decompressor ********************************/ + +static tjhandle _tjInitDecompress(tjinstance *this) +{ + static unsigned char buffer[1]; + + /* This is also straight out of example.c */ + this->dinfo.err = jpeg_std_error(&this->jerr.pub); + this->jerr.pub.error_exit = my_error_exit; + this->jerr.pub.output_message = my_output_message; + this->jerr.emit_message = this->jerr.pub.emit_message; + this->jerr.pub.emit_message = my_emit_message; + this->jerr.pub.addon_message_table = turbojpeg_message_table; + this->jerr.pub.first_addon_message = JMSG_FIRSTADDONCODE; + this->jerr.pub.last_addon_message = JMSG_LASTADDONCODE; + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + free(this); + return NULL; + } + + jpeg_create_decompress(&this->dinfo); + /* Make an initial call so it will create the source manager */ + jpeg_mem_src_tj(&this->dinfo, buffer, 1); + + this->init |= DECOMPRESS; + return (tjhandle)this; +} + +/* TurboJPEG 1.0+ */ +DLLEXPORT tjhandle tjInitDecompress(void) +{ + return tj3Init(TJINIT_DECOMPRESS); +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3DecompressHeader(tjhandle handle, + const unsigned char *jpegBuf, + size_t jpegSize) +{ + static const char FUNCTION_NAME[] = "tj3DecompressHeader"; + int retval = 0; + + GET_DINSTANCE(handle); + if ((this->init & DECOMPRESS) == 0) + THROW("Instance has not been initialized for decompression"); + + if (jpegBuf == NULL || jpegSize <= 0) + THROW("Invalid argument"); + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + return -1; + } + + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + + /* jpeg_read_header() calls jpeg_abort() and returns JPEG_HEADER_TABLES_ONLY + if the datastream is a tables-only datastream. Since we aren't using a + suspending data source, the only other value it can return is + JPEG_HEADER_OK. */ + if (jpeg_read_header(dinfo, FALSE) == JPEG_HEADER_TABLES_ONLY) + return 0; + + setDecompParameters(this); + + jpeg_abort_decompress(dinfo); + + if (this->colorspace < 0) + THROW("Could not determine colorspace of JPEG image"); + if (this->jpegWidth < 1 || this->jpegHeight < 1) + THROW("Invalid data returned in header"); + +bailout: + if (this->jerr.warning) retval = -1; + return retval; +} + +/* TurboJPEG 1.4+ */ +DLLEXPORT int tjDecompressHeader3(tjhandle handle, + const unsigned char *jpegBuf, + unsigned long jpegSize, int *width, + int *height, int *jpegSubsamp, + int *jpegColorspace) +{ + static const char FUNCTION_NAME[] = "tjDecompressHeader3"; + int retval = 0; + + GET_TJINSTANCE(handle, -1); + + if (width == NULL || height == NULL || jpegSubsamp == NULL || + jpegColorspace == NULL) + THROW("Invalid argument"); + + retval = tj3DecompressHeader(handle, jpegBuf, jpegSize); + + *width = tj3Get(handle, TJPARAM_JPEGWIDTH); + *height = tj3Get(handle, TJPARAM_JPEGHEIGHT); + *jpegSubsamp = tj3Get(handle, TJPARAM_SUBSAMP); + if (*jpegSubsamp == TJSAMP_UNKNOWN) + THROW("Could not determine subsampling level of JPEG image"); + *jpegColorspace = tj3Get(handle, TJPARAM_COLORSPACE); + +bailout: + return retval; +} + +/* TurboJPEG 1.1+ */ +DLLEXPORT int tjDecompressHeader2(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, int *width, + int *height, int *jpegSubsamp) +{ + int jpegColorspace; + + return tjDecompressHeader3(handle, jpegBuf, jpegSize, width, height, + jpegSubsamp, &jpegColorspace); +} + +/* TurboJPEG 1.0+ */ +DLLEXPORT int tjDecompressHeader(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, int *width, + int *height) +{ + int jpegSubsamp; + + return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, + &jpegSubsamp); +} + + +/* TurboJPEG 3+ */ +DLLEXPORT tjscalingfactor *tj3GetScalingFactors(int *numScalingFactors) +{ + static const char FUNCTION_NAME[] = "tj3GetScalingFactors"; + tjscalingfactor *retval = (tjscalingfactor *)sf; + + if (numScalingFactors == NULL) + THROWG("Invalid argument", NULL); + + *numScalingFactors = NUMSF; + +bailout: + return retval; +} + +/* TurboJPEG 1.2+ */ +DLLEXPORT tjscalingfactor *tjGetScalingFactors(int *numScalingFactors) +{ + return tj3GetScalingFactors(numScalingFactors); +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3SetScalingFactor(tjhandle handle, + tjscalingfactor scalingFactor) +{ + static const char FUNCTION_NAME[] = "tj3SetScalingFactor"; + int i, retval = 0; + + GET_TJINSTANCE(handle, -1); + if ((this->init & DECOMPRESS) == 0) + THROW("Instance has not been initialized for decompression"); + + for (i = 0; i < NUMSF; i++) { + if (scalingFactor.num == sf[i].num && scalingFactor.denom == sf[i].denom) + break; + } + if (i >= NUMSF) + THROW("Unsupported scaling factor"); + + this->scalingFactor = scalingFactor; + +bailout: + return retval; } @@ -1913,34 +1940,375 @@ DLLEXPORT int tj3SetCroppingRegion(tjhandle handle, tjregion croppingRegion) if (croppingRegion.x % TJSCALED(tjMCUWidth[this->subsamp], this->scalingFactor) != 0) THROWI("The left boundary of the cropping region (%d) is not\n" - "divisible by the scaled MCU width (%d)", + "divisible by the scaled iMCU width (%d)", croppingRegion.x, TJSCALED(tjMCUWidth[this->subsamp], this->scalingFactor)); if (croppingRegion.w == 0) croppingRegion.w = scaledWidth - croppingRegion.x; if (croppingRegion.h == 0) croppingRegion.h = scaledHeight - croppingRegion.y; - if (croppingRegion.w < 0 || croppingRegion.h < 0 || + if (croppingRegion.w <= 0 || croppingRegion.h <= 0 || croppingRegion.x + croppingRegion.w > scaledWidth || croppingRegion.y + croppingRegion.h > scaledHeight) THROW("The cropping region exceeds the scaled image dimensions"); - this->croppingRegion = croppingRegion; + this->croppingRegion = croppingRegion; + +bailout: + return retval; +} + + +/* tj3Decompress*() is implemented in turbojpeg-mp.c */ + +/* TurboJPEG 1.2+ */ +DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, + int flags) +{ + static const char FUNCTION_NAME[] = "tjDecompress2"; + int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; + + GET_DINSTANCE(handle); + if ((this->init & DECOMPRESS) == 0) + THROW("Instance has not been initialized for decompression"); + + if (jpegBuf == NULL || jpegSize <= 0 || width < 0 || height < 0) + THROW("Invalid argument"); + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + jpeg_read_header(dinfo, TRUE); + jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; + if (width == 0) width = jpegwidth; + if (height == 0) height = jpegheight; + for (i = 0; i < NUMSF; i++) { + scaledw = TJSCALED(jpegwidth, sf[i]); + scaledh = TJSCALED(jpegheight, sf[i]); + if (scaledw <= width && scaledh <= height) + break; + } + if (i >= NUMSF) + THROW("Could not scale down to desired image dimensions"); + + processFlags(handle, flags, DECOMPRESS); + + if (tj3SetScalingFactor(handle, sf[i]) == -1) + return -1; + if (tj3SetCroppingRegion(handle, TJUNCROPPED) == -1) + return -1; + return tj3Decompress8(handle, jpegBuf, jpegSize, dstBuf, pitch, pixelFormat); + +bailout: + if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + if (this->jerr.warning) retval = -1; + return retval; +} + +/* TurboJPEG 1.0+ */ +DLLEXPORT int tjDecompress(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelSize, + int flags) +{ + if (flags & TJ_YUV) + return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); + else + return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, + height, getPixelFormat(pixelSize, flags), flags); +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3DecompressToYUVPlanes8(tjhandle handle, + const unsigned char *jpegBuf, + size_t jpegSize, + unsigned char **dstPlanes, + int *strides) +{ + static const char FUNCTION_NAME[] = "tj3DecompressToYUVPlanes8"; + int i, row, retval = 0; + int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], + tmpbufsize = 0, usetmpbuf = 0, th[MAX_COMPONENTS]; + JSAMPLE *_tmpbuf = NULL, *ptr; + JSAMPROW *outbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; + int dctsize; + struct my_progress_mgr progress; + + GET_DINSTANCE(handle); + + for (i = 0; i < MAX_COMPONENTS; i++) { + tmpbuf[i] = NULL; outbuf[i] = NULL; + } + + if ((this->init & DECOMPRESS) == 0) + THROW("Instance has not been initialized for decompression"); + + if (jpegBuf == NULL || jpegSize <= 0 || !dstPlanes || !dstPlanes[0]) + THROW("Invalid argument"); + + if (this->scanLimit) { + memset(&progress, 0, sizeof(struct my_progress_mgr)); + progress.pub.progress_monitor = my_progress_monitor; + progress.this = this; + dinfo->progress = &progress.pub; + } else + dinfo->progress = NULL; + + dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + if (dinfo->global_state <= DSTATE_INHEADER) { + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + jpeg_read_header(dinfo, TRUE); + } + setDecompParameters(this); + if (this->maxPixels && + (unsigned long long)this->jpegWidth * this->jpegHeight > + (unsigned long long)this->maxPixels) + THROW("Image is too large"); + if (this->subsamp == TJSAMP_UNKNOWN) + THROW("Could not determine subsampling level of JPEG image"); + + if (this->subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) + THROW("Invalid argument"); + + if (dinfo->num_components > 3) + THROW("JPEG image must have 3 or fewer components"); + + dinfo->scale_num = this->scalingFactor.num; + dinfo->scale_denom = this->scalingFactor.denom; + jpeg_calc_output_dimensions(dinfo); + + dctsize = DCTSIZE * this->scalingFactor.num / this->scalingFactor.denom; + + for (i = 0; i < dinfo->num_components; i++) { + jpeg_component_info *compptr = &dinfo->comp_info[i]; + int ih; + + iw[i] = compptr->width_in_blocks * dctsize; + ih = compptr->height_in_blocks * dctsize; + pw[i] = tj3YUVPlaneWidth(i, dinfo->output_width, this->subsamp); + ph[i] = tj3YUVPlaneHeight(i, dinfo->output_height, this->subsamp); + if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1; + th[i] = compptr->v_samp_factor * dctsize; + tmpbufsize += iw[i] * th[i]; + if ((outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) + THROW("Memory allocation failure"); + ptr = dstPlanes[i]; + for (row = 0; row < ph[i]; row++) { + outbuf[i][row] = ptr; + ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; + } + } + if (usetmpbuf) { + if ((_tmpbuf = (JSAMPLE *)MALLOC(sizeof(JSAMPLE) * tmpbufsize)) == NULL) + THROW("Memory allocation failure"); + ptr = _tmpbuf; + for (i = 0; i < dinfo->num_components; i++) { + if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) + THROW("Memory allocation failure"); + for (row = 0; row < th[i]; row++) { + tmpbuf[i][row] = ptr; + ptr += iw[i]; + } + } + } + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + dinfo->do_fancy_upsampling = !this->fastUpsample; + dinfo->dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; + dinfo->raw_data_out = TRUE; + + dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + + jpeg_start_decompress(dinfo); + for (row = 0; row < (int)dinfo->output_height; + row += dinfo->max_v_samp_factor * dinfo->_min_DCT_scaled_size) { + JSAMPARRAY yuvptr[MAX_COMPONENTS]; + int crow[MAX_COMPONENTS]; + + for (i = 0; i < dinfo->num_components; i++) { + jpeg_component_info *compptr = &dinfo->comp_info[i]; + + if (this->subsamp == TJSAMP_420) { + /* When 4:2:0 subsampling is used with IDCT scaling, libjpeg will try + to be clever and use the IDCT to perform upsampling on the U and V + planes. For instance, if the output image is to be scaled by 1/2 + relative to the JPEG image, then the scaling factor and upsampling + effectively cancel each other, so a normal 8x8 IDCT can be used. + However, this is not desirable when using the decompress-to-YUV + functionality in TurboJPEG, since we want to output the U and V + planes in their subsampled form. Thus, we have to override some + internal libjpeg parameters to force it to use the "scaled" IDCT + functions on the U and V planes. */ + compptr->_DCT_scaled_size = dctsize; + compptr->MCU_sample_width = tjMCUWidth[this->subsamp] * + this->scalingFactor.num / this->scalingFactor.denom * + compptr->v_samp_factor / dinfo->max_v_samp_factor; + dinfo->idct->inverse_DCT[i] = dinfo->idct->inverse_DCT[0]; + } + crow[i] = row * compptr->v_samp_factor / dinfo->max_v_samp_factor; + if (usetmpbuf) yuvptr[i] = tmpbuf[i]; + else yuvptr[i] = &outbuf[i][crow[i]]; + } + jpeg_read_raw_data(dinfo, yuvptr, + dinfo->max_v_samp_factor * dinfo->_min_DCT_scaled_size); + if (usetmpbuf) { + int j; + + for (i = 0; i < dinfo->num_components; i++) { + for (j = 0; j < MIN(th[i], ph[i] - crow[i]); j++) { + memcpy(outbuf[i][crow[i] + j], tmpbuf[i][j], pw[i]); + } + } + } + } + jpeg_finish_decompress(dinfo); + +bailout: + if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + for (i = 0; i < MAX_COMPONENTS; i++) { + free(tmpbuf[i]); + free(outbuf[i]); + } + free(_tmpbuf); + if (this->jerr.warning) retval = -1; + return retval; +} + +/* TurboJPEG 1.4+ */ +DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, + const unsigned char *jpegBuf, + unsigned long jpegSize, + unsigned char **dstPlanes, int width, + int *strides, int height, int flags) +{ + static const char FUNCTION_NAME[] = "tjDecompressToYUVPlanes"; + int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; + + GET_DINSTANCE(handle); + if ((this->init & DECOMPRESS) == 0) + THROW("Instance has not been initialized for decompression"); + + if (jpegBuf == NULL || jpegSize <= 0 || width < 0 || height < 0) + THROW("Invalid argument"); + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + jpeg_read_header(dinfo, TRUE); + jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; + if (width == 0) width = jpegwidth; + if (height == 0) height = jpegheight; + for (i = 0; i < NUMSF; i++) { + scaledw = TJSCALED(jpegwidth, sf[i]); + scaledh = TJSCALED(jpegheight, sf[i]); + if (scaledw <= width && scaledh <= height) + break; + } + if (i >= NUMSF) + THROW("Could not scale down to desired image dimensions"); + + processFlags(handle, flags, DECOMPRESS); + + if (tj3SetScalingFactor(handle, sf[i]) == -1) + return -1; + return tj3DecompressToYUVPlanes8(handle, jpegBuf, jpegSize, dstPlanes, + strides); + +bailout: + if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + if (this->jerr.warning) retval = -1; + return retval; +} + + +/* TurboJPEG 3+ */ +DLLEXPORT int tj3DecompressToYUV8(tjhandle handle, + const unsigned char *jpegBuf, + size_t jpegSize, + unsigned char *dstBuf, int align) +{ + static const char FUNCTION_NAME[] = "tj3DecompressToYUV8"; + unsigned char *dstPlanes[3]; + int pw0, ph0, strides[3], retval = -1; + int width, height; + + GET_DINSTANCE(handle); + + if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || align < 1 || + !IS_POW2(align)) + THROW("Invalid argument"); + + if (setjmp(this->jerr.setjmp_buffer)) { + /* If we get here, the JPEG code has signaled an error. */ + retval = -1; goto bailout; + } + + if (dinfo->global_state <= DSTATE_INHEADER) { + jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); + jpeg_read_header(dinfo, TRUE); + } + setDecompParameters(this); + if (this->subsamp == TJSAMP_UNKNOWN) + THROW("Could not determine subsampling level of JPEG image"); + + width = TJSCALED(dinfo->image_width, this->scalingFactor); + height = TJSCALED(dinfo->image_height, this->scalingFactor); + + pw0 = tj3YUVPlaneWidth(0, width, this->subsamp); + ph0 = tj3YUVPlaneHeight(0, height, this->subsamp); + dstPlanes[0] = dstBuf; + strides[0] = PAD(pw0, align); + if (this->subsamp == TJSAMP_GRAY) { + strides[1] = strides[2] = 0; + dstPlanes[1] = dstPlanes[2] = NULL; + } else { + int pw1 = tj3YUVPlaneWidth(1, width, this->subsamp); + int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp); + + strides[1] = strides[2] = PAD(pw1, align); + if ((unsigned long long)strides[0] * (unsigned long long)ph0 > + (unsigned long long)INT_MAX || + (unsigned long long)strides[1] * (unsigned long long)ph1 > + (unsigned long long)INT_MAX) + THROW("Image or row alignment is too large"); + dstPlanes[1] = dstPlanes[0] + strides[0] * ph0; + dstPlanes[2] = dstPlanes[1] + strides[1] * ph1; + } + + return tj3DecompressToYUVPlanes8(handle, jpegBuf, jpegSize, dstPlanes, + strides); bailout: + if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + if (this->jerr.warning) retval = -1; return retval; } - -/* tj3Decompress*() is implemented in turbojpeg-mp.c */ - -/* TurboJPEG 1.2+ */ -DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, - unsigned long jpegSize, unsigned char *dstBuf, - int width, int pitch, int height, int pixelFormat, - int flags) +/* TurboJPEG 1.4+ */ +DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int width, int align, int height, int flags) { - static const char FUNCTION_NAME[] = "tjDecompress2"; + static const char FUNCTION_NAME[] = "tjDecompressToYUV2"; int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; GET_DINSTANCE(handle); @@ -1969,13 +2337,13 @@ DLLEXPORT int tjDecompress2(tjhandle handle, const unsigned char *jpegBuf, if (i >= NUMSF) THROW("Could not scale down to desired image dimensions"); + width = scaledw; height = scaledh; + processFlags(handle, flags, DECOMPRESS); if (tj3SetScalingFactor(handle, sf[i]) == -1) return -1; - if (tj3SetCroppingRegion(handle, TJUNCROPPED) == -1) - return -1; - return tj3Decompress8(handle, jpegBuf, jpegSize, dstBuf, pitch, pixelFormat); + return tj3DecompressToYUV8(handle, jpegBuf, (size_t)jpegSize, dstBuf, align); bailout: if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); @@ -1983,17 +2351,12 @@ bailout: return retval; } -/* TurboJPEG 1.0+ */ -DLLEXPORT int tjDecompress(tjhandle handle, unsigned char *jpegBuf, - unsigned long jpegSize, unsigned char *dstBuf, - int width, int pitch, int height, int pixelSize, - int flags) +/* TurboJPEG 1.1+ */ +DLLEXPORT int tjDecompressToYUV(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, + int flags) { - if (flags & TJ_YUV) - return tjDecompressToYUV(handle, jpegBuf, jpegSize, dstBuf, flags); - else - return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, - height, getPixelFormat(pixelSize, flags), flags); + return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, flags); } @@ -2033,6 +2396,8 @@ static void setDecodeDefaults(tjinstance *this, int pixelFormat) this->dinfo.quant_tbl_ptrs[i] = jpeg_alloc_quant_table((j_common_ptr)&this->dinfo); } + + this->dinfo.mem->max_memory_to_use = (long)this->maxMemory * 1048576L; } @@ -2142,464 +2507,146 @@ DLLEXPORT int tj3DecodeYUVPlanes8(tjhandle handle, tmpbuf[i][row] = &_tmpbuf_aligned[PAD(compptr->width_in_blocks * DCTSIZE, 32) * row]; - } - pw[i] = pw0 * compptr->h_samp_factor / dinfo->max_h_samp_factor; - ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor; - inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); - if (!inbuf[i]) - THROW("Memory allocation failure"); - ptr = (JSAMPLE *)srcPlanes[i]; - for (row = 0; row < ph[i]; row++) { - inbuf[i][row] = ptr; - ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; - } - } - - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - for (row = 0; row < ph0; row += dinfo->max_v_samp_factor) { - JDIMENSION inrow = 0, outrow = 0; - - for (i = 0, compptr = dinfo->comp_info; i < dinfo->num_components; - i++, compptr++) - jcopy_sample_rows(inbuf[i], - row * compptr->v_samp_factor / dinfo->max_v_samp_factor, tmpbuf[i], 0, - compptr->v_samp_factor, pw[i]); - (dinfo->upsample->upsample) (dinfo, tmpbuf, &inrow, - dinfo->max_v_samp_factor, &row_pointer[row], - &outrow, dinfo->max_v_samp_factor); - } - jpeg_abort_decompress(dinfo); - -bailout: - if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - free(row_pointer); - for (i = 0; i < MAX_COMPONENTS; i++) { - free(tmpbuf[i]); - free(_tmpbuf[i]); - free(inbuf[i]); - } - if (this->jerr.warning) retval = -1; - return retval; -} - -/* TurboJPEG 1.4+ */ -DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, - const unsigned char **srcPlanes, - const int *strides, int subsamp, - unsigned char *dstBuf, int width, int pitch, - int height, int pixelFormat, int flags) -{ - static const char FUNCTION_NAME[] = "tjDecodeYUVPlanes"; - int retval = 0; - - GET_TJINSTANCE(handle, -1); - - if (subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROW("Invalid argument"); - - this->subsamp = subsamp; - processFlags(handle, flags, DECOMPRESS); - - return tj3DecodeYUVPlanes8(handle, srcPlanes, strides, dstBuf, width, pitch, - height, pixelFormat); - -bailout: - return retval; -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf, - int align, unsigned char *dstBuf, int width, - int pitch, int height, int pixelFormat) -{ - static const char FUNCTION_NAME[] = "tj3DecodeYUV8"; - const unsigned char *srcPlanes[3]; - int pw0, ph0, strides[3], retval = -1; - - GET_TJINSTANCE(handle, -1); - - if (srcBuf == NULL || align < 1 || !IS_POW2(align) || width <= 0 || - height <= 0) - THROW("Invalid argument"); - - if (this->subsamp == TJSAMP_UNKNOWN) - THROW("TJPARAM_SUBSAMP must be specified"); - - pw0 = tj3YUVPlaneWidth(0, width, this->subsamp); - ph0 = tj3YUVPlaneHeight(0, height, this->subsamp); - srcPlanes[0] = srcBuf; - strides[0] = PAD(pw0, align); - if (this->subsamp == TJSAMP_GRAY) { - strides[1] = strides[2] = 0; - srcPlanes[1] = srcPlanes[2] = NULL; - } else { - int pw1 = tj3YUVPlaneWidth(1, width, this->subsamp); - int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp); - - strides[1] = strides[2] = PAD(pw1, align); - srcPlanes[1] = srcPlanes[0] + strides[0] * ph0; - srcPlanes[2] = srcPlanes[1] + strides[1] * ph1; - } - - return tj3DecodeYUVPlanes8(handle, srcPlanes, strides, dstBuf, width, pitch, - height, pixelFormat); - -bailout: - return retval; -} - -/* TurboJPEG 1.4+ */ -DLLEXPORT int tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, - int align, int subsamp, unsigned char *dstBuf, - int width, int pitch, int height, int pixelFormat, - int flags) -{ - static const char FUNCTION_NAME[] = "tjDecodeYUV"; - int retval = -1; - - GET_TJINSTANCE(handle, -1); - - if (subsamp < 0 || subsamp >= TJ_NUMSAMP) - THROW("Invalid argument"); - - this->subsamp = subsamp; - processFlags(handle, flags, DECOMPRESS); - - return tj3DecodeYUV8(handle, srcBuf, align, dstBuf, width, pitch, height, - pixelFormat); - -bailout: - return retval; -} - - -/* TurboJPEG 3+ */ -DLLEXPORT int tj3DecompressToYUVPlanes8(tjhandle handle, - const unsigned char *jpegBuf, - size_t jpegSize, - unsigned char **dstPlanes, - int *strides) -{ - static const char FUNCTION_NAME[] = "tj3DecompressToYUVPlanes8"; - int i, row, retval = 0; - int pw[MAX_COMPONENTS], ph[MAX_COMPONENTS], iw[MAX_COMPONENTS], - tmpbufsize = 0, usetmpbuf = 0, th[MAX_COMPONENTS]; - JSAMPLE *_tmpbuf = NULL, *ptr; - JSAMPROW *outbuf[MAX_COMPONENTS], *tmpbuf[MAX_COMPONENTS]; - int dctsize; - struct my_progress_mgr progress; - - GET_DINSTANCE(handle); - - for (i = 0; i < MAX_COMPONENTS; i++) { - tmpbuf[i] = NULL; outbuf[i] = NULL; - } - - if ((this->init & DECOMPRESS) == 0) - THROW("Instance has not been initialized for decompression"); - - if (jpegBuf == NULL || jpegSize <= 0 || !dstPlanes || !dstPlanes[0]) - THROW("Invalid argument"); - - if (this->scanLimit) { - memset(&progress, 0, sizeof(struct my_progress_mgr)); - progress.pub.progress_monitor = my_progress_monitor; - progress.this = this; - dinfo->progress = &progress.pub; - } else - dinfo->progress = NULL; - - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - if (dinfo->global_state <= DSTATE_START) { - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); - } - setDecompParameters(this); - if (this->subsamp == TJSAMP_UNKNOWN) - THROW("Could not determine subsampling level of JPEG image"); - - if (this->subsamp != TJSAMP_GRAY && (!dstPlanes[1] || !dstPlanes[2])) - THROW("Invalid argument"); - - if (dinfo->num_components > 3) - THROW("JPEG image must have 3 or fewer components"); - - dinfo->scale_num = this->scalingFactor.num; - dinfo->scale_denom = this->scalingFactor.denom; - jpeg_calc_output_dimensions(dinfo); - - dctsize = DCTSIZE * this->scalingFactor.num / this->scalingFactor.denom; - - for (i = 0; i < dinfo->num_components; i++) { - jpeg_component_info *compptr = &dinfo->comp_info[i]; - int ih; - - iw[i] = compptr->width_in_blocks * dctsize; - ih = compptr->height_in_blocks * dctsize; - pw[i] = tj3YUVPlaneWidth(i, dinfo->output_width, this->subsamp); - ph[i] = tj3YUVPlaneHeight(i, dinfo->output_height, this->subsamp); - if (iw[i] != pw[i] || ih != ph[i]) usetmpbuf = 1; - th[i] = compptr->v_samp_factor * dctsize; - tmpbufsize += iw[i] * th[i]; - if ((outbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i])) == NULL) + } + pw[i] = pw0 * compptr->h_samp_factor / dinfo->max_h_samp_factor; + ph[i] = ph0 * compptr->v_samp_factor / dinfo->max_v_samp_factor; + inbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * ph[i]); + if (!inbuf[i]) THROW("Memory allocation failure"); - ptr = dstPlanes[i]; + ptr = (JSAMPLE *)srcPlanes[i]; for (row = 0; row < ph[i]; row++) { - outbuf[i][row] = ptr; + inbuf[i][row] = ptr; ptr += (strides && strides[i] != 0) ? strides[i] : pw[i]; } } - if (usetmpbuf) { - if ((_tmpbuf = (JSAMPLE *)malloc(sizeof(JSAMPLE) * tmpbufsize)) == NULL) - THROW("Memory allocation failure"); - ptr = _tmpbuf; - for (i = 0; i < dinfo->num_components; i++) { - if ((tmpbuf[i] = (JSAMPROW *)malloc(sizeof(JSAMPROW) * th[i])) == NULL) - THROW("Memory allocation failure"); - for (row = 0; row < th[i]; row++) { - tmpbuf[i][row] = ptr; - ptr += iw[i]; - } - } - } if (setjmp(this->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ retval = -1; goto bailout; } - dinfo->do_fancy_upsampling = !this->fastUpsample; - dinfo->dct_method = this->fastDCT ? JDCT_FASTEST : JDCT_ISLOW; - dinfo->raw_data_out = TRUE; - - jpeg_start_decompress(dinfo); - for (row = 0; row < (int)dinfo->output_height; - row += dinfo->max_v_samp_factor * dinfo->_min_DCT_scaled_size) { - JSAMPARRAY yuvptr[MAX_COMPONENTS]; - int crow[MAX_COMPONENTS]; - - for (i = 0; i < dinfo->num_components; i++) { - jpeg_component_info *compptr = &dinfo->comp_info[i]; - - if (this->subsamp == TJSAMP_420) { - /* When 4:2:0 subsampling is used with IDCT scaling, libjpeg will try - to be clever and use the IDCT to perform upsampling on the U and V - planes. For instance, if the output image is to be scaled by 1/2 - relative to the JPEG image, then the scaling factor and upsampling - effectively cancel each other, so a normal 8x8 IDCT can be used. - However, this is not desirable when using the decompress-to-YUV - functionality in TurboJPEG, since we want to output the U and V - planes in their subsampled form. Thus, we have to override some - internal libjpeg parameters to force it to use the "scaled" IDCT - functions on the U and V planes. */ - compptr->_DCT_scaled_size = dctsize; - compptr->MCU_sample_width = tjMCUWidth[this->subsamp] * - this->scalingFactor.num / this->scalingFactor.denom * - compptr->v_samp_factor / dinfo->max_v_samp_factor; - dinfo->idct->inverse_DCT[i] = dinfo->idct->inverse_DCT[0]; - } - crow[i] = row * compptr->v_samp_factor / dinfo->max_v_samp_factor; - if (usetmpbuf) yuvptr[i] = tmpbuf[i]; - else yuvptr[i] = &outbuf[i][crow[i]]; - } - jpeg_read_raw_data(dinfo, yuvptr, - dinfo->max_v_samp_factor * dinfo->_min_DCT_scaled_size); - if (usetmpbuf) { - int j; + for (row = 0; row < ph0; row += dinfo->max_v_samp_factor) { + JDIMENSION inrow = 0, outrow = 0; - for (i = 0; i < dinfo->num_components; i++) { - for (j = 0; j < MIN(th[i], ph[i] - crow[i]); j++) { - memcpy(outbuf[i][crow[i] + j], tmpbuf[i][j], pw[i]); - } - } - } + for (i = 0, compptr = dinfo->comp_info; i < dinfo->num_components; + i++, compptr++) + jcopy_sample_rows(inbuf[i], + row * compptr->v_samp_factor / dinfo->max_v_samp_factor, tmpbuf[i], 0, + compptr->v_samp_factor, pw[i]); + (dinfo->upsample->upsample) (dinfo, tmpbuf, &inrow, + dinfo->max_v_samp_factor, &row_pointer[row], + &outrow, dinfo->max_v_samp_factor); } - jpeg_finish_decompress(dinfo); + jpeg_abort_decompress(dinfo); bailout: if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); + free(row_pointer); for (i = 0; i < MAX_COMPONENTS; i++) { free(tmpbuf[i]); - free(outbuf[i]); + free(_tmpbuf[i]); + free(inbuf[i]); } - free(_tmpbuf); if (this->jerr.warning) retval = -1; return retval; } /* TurboJPEG 1.4+ */ -DLLEXPORT int tjDecompressToYUVPlanes(tjhandle handle, - const unsigned char *jpegBuf, - unsigned long jpegSize, - unsigned char **dstPlanes, int width, - int *strides, int height, int flags) +DLLEXPORT int tjDecodeYUVPlanes(tjhandle handle, + const unsigned char **srcPlanes, + const int *strides, int subsamp, + unsigned char *dstBuf, int width, int pitch, + int height, int pixelFormat, int flags) { - static const char FUNCTION_NAME[] = "tjDecompressToYUVPlanes"; - int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; + static const char FUNCTION_NAME[] = "tjDecodeYUVPlanes"; + int retval = 0; - GET_DINSTANCE(handle); - if ((this->init & DECOMPRESS) == 0) - THROW("Instance has not been initialized for decompression"); + GET_TJINSTANCE(handle, -1); - if (jpegBuf == NULL || jpegSize <= 0 || width < 0 || height < 0) + if (subsamp < 0 || subsamp >= TJ_NUMSAMP) THROW("Invalid argument"); - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); - jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; - if (width == 0) width = jpegwidth; - if (height == 0) height = jpegheight; - for (i = 0; i < NUMSF; i++) { - scaledw = TJSCALED(jpegwidth, sf[i]); - scaledh = TJSCALED(jpegheight, sf[i]); - if (scaledw <= width && scaledh <= height) - break; - } - if (i >= NUMSF) - THROW("Could not scale down to desired image dimensions"); - + this->subsamp = subsamp; processFlags(handle, flags, DECOMPRESS); - if (tj3SetScalingFactor(handle, sf[i]) == -1) - return -1; - return tj3DecompressToYUVPlanes8(handle, jpegBuf, jpegSize, dstPlanes, - strides); + return tj3DecodeYUVPlanes8(handle, srcPlanes, strides, dstBuf, width, pitch, + height, pixelFormat); bailout: - if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (this->jerr.warning) retval = -1; return retval; } /* TurboJPEG 3+ */ -DLLEXPORT int tj3DecompressToYUV8(tjhandle handle, - const unsigned char *jpegBuf, - size_t jpegSize, - unsigned char *dstBuf, int align) +DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf, + int align, unsigned char *dstBuf, int width, + int pitch, int height, int pixelFormat) { - static const char FUNCTION_NAME[] = "tj3DecompressToYUV8"; - unsigned char *dstPlanes[3]; + static const char FUNCTION_NAME[] = "tj3DecodeYUV8"; + const unsigned char *srcPlanes[3]; int pw0, ph0, strides[3], retval = -1; - int width, height; - GET_DINSTANCE(handle); + GET_TJINSTANCE(handle, -1); - if (jpegBuf == NULL || jpegSize <= 0 || dstBuf == NULL || align < 1 || - !IS_POW2(align)) + if (srcBuf == NULL || align < 1 || !IS_POW2(align) || width <= 0 || + height <= 0) THROW("Invalid argument"); - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - if (dinfo->global_state <= DSTATE_START) { - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); - } - setDecompParameters(this); if (this->subsamp == TJSAMP_UNKNOWN) - THROW("Could not determine subsampling level of JPEG image"); - - width = TJSCALED(dinfo->image_width, this->scalingFactor); - height = TJSCALED(dinfo->image_height, this->scalingFactor); + THROW("TJPARAM_SUBSAMP must be specified"); pw0 = tj3YUVPlaneWidth(0, width, this->subsamp); ph0 = tj3YUVPlaneHeight(0, height, this->subsamp); - dstPlanes[0] = dstBuf; + srcPlanes[0] = srcBuf; strides[0] = PAD(pw0, align); if (this->subsamp == TJSAMP_GRAY) { strides[1] = strides[2] = 0; - dstPlanes[1] = dstPlanes[2] = NULL; + srcPlanes[1] = srcPlanes[2] = NULL; } else { int pw1 = tj3YUVPlaneWidth(1, width, this->subsamp); int ph1 = tj3YUVPlaneHeight(1, height, this->subsamp); strides[1] = strides[2] = PAD(pw1, align); - dstPlanes[1] = dstPlanes[0] + strides[0] * ph0; - dstPlanes[2] = dstPlanes[1] + strides[1] * ph1; + if ((unsigned long long)strides[0] * (unsigned long long)ph0 > + (unsigned long long)INT_MAX || + (unsigned long long)strides[1] * (unsigned long long)ph1 > + (unsigned long long)INT_MAX) + THROW("Image or row alignment is too large"); + srcPlanes[1] = srcPlanes[0] + strides[0] * ph0; + srcPlanes[2] = srcPlanes[1] + strides[1] * ph1; } - return tj3DecompressToYUVPlanes8(handle, jpegBuf, jpegSize, dstPlanes, - strides); + return tj3DecodeYUVPlanes8(handle, srcPlanes, strides, dstBuf, width, pitch, + height, pixelFormat); bailout: - if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (this->jerr.warning) retval = -1; return retval; } /* TurboJPEG 1.4+ */ -DLLEXPORT int tjDecompressToYUV2(tjhandle handle, const unsigned char *jpegBuf, - unsigned long jpegSize, unsigned char *dstBuf, - int width, int align, int height, int flags) +DLLEXPORT int tjDecodeYUV(tjhandle handle, const unsigned char *srcBuf, + int align, int subsamp, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, + int flags) { - static const char FUNCTION_NAME[] = "tjDecompressToYUV2"; - int i, retval = 0, jpegwidth, jpegheight, scaledw, scaledh; + static const char FUNCTION_NAME[] = "tjDecodeYUV"; + int retval = -1; - GET_DINSTANCE(handle); - if ((this->init & DECOMPRESS) == 0) - THROW("Instance has not been initialized for decompression"); + GET_TJINSTANCE(handle, -1); - if (jpegBuf == NULL || jpegSize <= 0 || width < 0 || height < 0) + if (subsamp < 0 || subsamp >= TJ_NUMSAMP) THROW("Invalid argument"); - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); - jpegwidth = dinfo->image_width; jpegheight = dinfo->image_height; - if (width == 0) width = jpegwidth; - if (height == 0) height = jpegheight; - for (i = 0; i < NUMSF; i++) { - scaledw = TJSCALED(jpegwidth, sf[i]); - scaledh = TJSCALED(jpegheight, sf[i]); - if (scaledw <= width && scaledh <= height) - break; - } - if (i >= NUMSF) - THROW("Could not scale down to desired image dimensions"); - - width = scaledw; height = scaledh; - + this->subsamp = subsamp; processFlags(handle, flags, DECOMPRESS); - if (tj3SetScalingFactor(handle, sf[i]) == -1) - return -1; - return tj3DecompressToYUV8(handle, jpegBuf, (size_t)jpegSize, dstBuf, align); + return tj3DecodeYUV8(handle, srcBuf, align, dstBuf, width, pitch, height, + pixelFormat); bailout: - if (dinfo->global_state > DSTATE_START) jpeg_abort_decompress(dinfo); - if (this->jerr.warning) retval = -1; return retval; } -/* TurboJPEG 1.1+ */ -DLLEXPORT int tjDecompressToYUV(tjhandle handle, unsigned char *jpegBuf, - unsigned long jpegSize, unsigned char *dstBuf, - int flags) -{ - return tjDecompressToYUV2(handle, jpegBuf, jpegSize, dstBuf, 0, 4, 0, flags); -} - /******************************** Transformer ********************************/ @@ -2618,7 +2665,7 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, static const char FUNCTION_NAME[] = "tj3Transform"; jpeg_transform_info *xinfo = NULL; jvirt_barray_ptr *srccoefs, *dstcoefs; - int retval = 0, i, saveMarkers = 0; + int retval = 0, i, saveMarkers = 0, srcSubsamp; boolean alloc = TRUE; struct my_progress_mgr progress; @@ -2638,6 +2685,8 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, } else dinfo->progress = NULL; + dinfo->mem->max_memory_to_use = (long)this->maxMemory * 1048576L; + if ((xinfo = (jpeg_transform_info *)malloc(sizeof(jpeg_transform_info) * n)) == NULL) THROW("Memory allocation failure"); @@ -2648,10 +2697,12 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, retval = -1; goto bailout; } - if (dinfo->global_state <= DSTATE_START) + if (dinfo->global_state <= DSTATE_INHEADER) jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); for (i = 0; i < n; i++) { + if (t[i].op < 0 || t[i].op >= TJ_NUMXOP) + THROW("Invalid transform operation"); xinfo[i].transform = xformtypes[t[i].op]; xinfo[i].perfect = (t[i].options & TJXOPT_PERFECT) ? 1 : 0; xinfo[i].trim = (t[i].options & TJXOPT_TRIM) ? 1 : 0; @@ -2661,6 +2712,8 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, else xinfo[i].slow_hflip = 0; if (xinfo[i].crop) { + if (t[i].r.x < 0 || t[i].r.y < 0 || t[i].r.w < 0 || t[i].r.h < 0) + THROW("Invalid cropping region"); xinfo[i].crop_xoffset = t[i].r.x; xinfo[i].crop_xoffset_set = JCROP_POS; xinfo[i].crop_yoffset = t[i].r.y; xinfo[i].crop_yoffset_set = JCROP_POS; if (t[i].r.w != 0) { @@ -2676,41 +2729,70 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, } jcopy_markers_setup(dinfo, saveMarkers ? JCOPYOPT_ALL : JCOPYOPT_NONE); - if (dinfo->global_state <= DSTATE_START) + if (dinfo->global_state <= DSTATE_INHEADER) jpeg_read_header(dinfo, TRUE); - this->subsamp = getSubsamp(&this->dinfo); + if (this->maxPixels && + (unsigned long long)dinfo->image_width * dinfo->image_height > + (unsigned long long)this->maxPixels) + THROW("Image is too large"); + srcSubsamp = getSubsamp(&this->dinfo); for (i = 0; i < n; i++) { if (!jtransform_request_workspace(dinfo, &xinfo[i])) THROW("Transform is not perfect"); if (xinfo[i].crop) { - if (this->subsamp == TJSAMP_UNKNOWN) - THROW("Could not determine subsampling level of JPEG image"); - if ((t[i].r.x % tjMCUWidth[this->subsamp]) != 0 || - (t[i].r.y % tjMCUHeight[this->subsamp]) != 0) + int dstSubsamp = (t[i].options & TJXOPT_GRAY) ? TJSAMP_GRAY : srcSubsamp; + + if (t[i].op == TJXOP_TRANSPOSE || t[i].op == TJXOP_TRANSVERSE || + t[i].op == TJXOP_ROT90 || t[i].op == TJXOP_ROT270) { + if (dstSubsamp == TJSAMP_422) dstSubsamp = TJSAMP_440; + else if (dstSubsamp == TJSAMP_440) dstSubsamp = TJSAMP_422; + else if (dstSubsamp == TJSAMP_411) dstSubsamp = TJSAMP_441; + else if (dstSubsamp == TJSAMP_441) dstSubsamp = TJSAMP_411; + } + if (dstSubsamp == TJSAMP_UNKNOWN) + THROW("Could not determine subsampling level of destination image"); + if ((t[i].r.x % tjMCUWidth[dstSubsamp]) != 0 || + (t[i].r.y % tjMCUHeight[dstSubsamp]) != 0) THROWI("To crop this JPEG image, x must be a multiple of %d\n" - "and y must be a multiple of %d.", tjMCUWidth[this->subsamp], - tjMCUHeight[this->subsamp]); + "and y must be a multiple of %d.", tjMCUWidth[dstSubsamp], + tjMCUHeight[dstSubsamp]); } } srccoefs = jpeg_read_coefficients(dinfo); for (i = 0; i < n; i++) { - int w, h; + JDIMENSION dstWidth = dinfo->image_width, dstHeight = dinfo->image_height; + + if (t[i].op == TJXOP_TRANSPOSE || t[i].op == TJXOP_TRANSVERSE || + t[i].op == TJXOP_ROT90 || t[i].op == TJXOP_ROT270) { + dstWidth = dinfo->image_height; dstHeight = dinfo->image_width; + } + + if (xinfo[i].crop) { + if ((JDIMENSION)t[i].r.x >= dstWidth || + t[i].r.x + xinfo[i].crop_width > dstWidth || + (JDIMENSION)t[i].r.y >= dstHeight || + t[i].r.y + xinfo[i].crop_height > dstHeight) + THROW("The cropping region exceeds the destination image dimensions"); + dstWidth = xinfo[i].crop_width; dstHeight = xinfo[i].crop_height; + } + if (this->noRealloc) { + int dstSubsamp = (t[i].options & TJXOPT_GRAY) ? TJSAMP_GRAY : srcSubsamp; - if (!xinfo[i].crop) { - w = dinfo->image_width; h = dinfo->image_height; if (t[i].op == TJXOP_TRANSPOSE || t[i].op == TJXOP_TRANSVERSE || t[i].op == TJXOP_ROT90 || t[i].op == TJXOP_ROT270) { - w = dinfo->image_height; h = dinfo->image_width; + if (dstSubsamp == TJSAMP_422) dstSubsamp = TJSAMP_440; + else if (dstSubsamp == TJSAMP_440) dstSubsamp = TJSAMP_422; + else if (dstSubsamp == TJSAMP_411) dstSubsamp = TJSAMP_441; + else if (dstSubsamp == TJSAMP_441) dstSubsamp = TJSAMP_411; } - } else { - w = xinfo[i].crop_width; h = xinfo[i].crop_height; - } - if (this->noRealloc) { - alloc = FALSE; dstSizes[i] = tj3JPEGBufSize(w, h, this->subsamp); + if (dstSubsamp == TJSAMP_UNKNOWN) + THROW("Could not determine subsampling level of destination image"); + alloc = FALSE; + dstSizes[i] = tj3JPEGBufSize(dstWidth, dstHeight, dstSubsamp); } if (!(t[i].options & TJXOPT_NOOUTPUT)) jpeg_mem_dest_tj(cinfo, &dstBufs[i], &dstSizes[i], alloc); @@ -2788,22 +2870,13 @@ DLLEXPORT int tjTransform(tjhandle handle, const unsigned char *jpegBuf, int i, retval = 0; size_t *sizes = NULL; - GET_DINSTANCE(handle); + GET_TJINSTANCE(handle, -1); if ((this->init & DECOMPRESS) == 0) THROW("Instance has not been initialized for decompression"); if (n < 1 || dstSizes == NULL) THROW("Invalid argument"); - if (setjmp(this->jerr.setjmp_buffer)) { - /* If we get here, the JPEG code has signaled an error. */ - retval = -1; goto bailout; - } - - jpeg_mem_src_tj(dinfo, jpegBuf, jpegSize); - jpeg_read_header(dinfo, TRUE); - if (getSubsamp(dinfo) == TJSAMP_UNKNOWN) - THROW("Could not determine subsampling level of JPEG image"); processFlags(handle, flags, COMPRESS); if ((sizes = (size_t *)malloc(n * sizeof(size_t))) == NULL) diff --git a/turbojpeg.h b/turbojpeg.h index 12efcbc..0d505df 100644 --- a/turbojpeg.h +++ b/turbojpeg.h @@ -1,5 +1,5 @@ /* - * Copyright (C)2009-2015, 2017, 2020-2023 D. R. Commander. + * Copyright (C)2009-2015, 2017, 2020-2024 D. R. Commander. * All Rights Reserved. * * Redistribution and use in source and binary forms, with or without @@ -85,7 +85,7 @@ #define TJ_NUMINIT 3 /** - * Initialization options. + * Initialization options */ enum TJINIT { /** @@ -110,80 +110,110 @@ enum TJINIT { #define TJ_NUMSAMP 7 /** - * Chrominance subsampling options. + * Chrominance subsampling options + * * When pixels are converted from RGB to YCbCr (see #TJCS_YCbCr) or from CMYK * to YCCK (see #TJCS_YCCK) as part of the JPEG compression process, some of * the Cb and Cr (chrominance) components can be discarded or averaged together - * to produce a smaller image with little perceptible loss of image clarity. + * to produce a smaller image with little perceptible loss of image quality. * (The human eye is more sensitive to small changes in brightness than to * small changes in color.) This is called "chrominance subsampling". */ enum TJSAMP { /** - * 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG or - * YUV image will contain one chrominance component for every pixel in the - * source image. + * 4:4:4 chrominance subsampling (no chrominance subsampling) + * + * The JPEG or YUV image will contain one chrominance component for every + * pixel in the source image. */ TJSAMP_444, /** - * 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 2x1 block of pixels in the source image. + * 4:2:2 chrominance subsampling + * + * The JPEG or YUV image will contain one chrominance component for every 2x1 + * block of pixels in the source image. */ TJSAMP_422, /** - * 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 2x2 block of pixels in the source image. + * 4:2:0 chrominance subsampling + * + * The JPEG or YUV image will contain one chrominance component for every 2x2 + * block of pixels in the source image. */ TJSAMP_420, /** - * Grayscale. The JPEG or YUV image will contain no chrominance components. + * Grayscale + * + * The JPEG or YUV image will contain no chrominance components. */ TJSAMP_GRAY, /** - * 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 1x2 block of pixels in the source image. + * 4:4:0 chrominance subsampling + * + * The JPEG or YUV image will contain one chrominance component for every 1x2 + * block of pixels in the source image. * * @note 4:4:0 subsampling is not fully accelerated in libjpeg-turbo. */ TJSAMP_440, /** - * 4:1:1 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 4x1 block of pixels in the source image. - * JPEG images compressed with 4:1:1 subsampling will be almost exactly the - * same size as those compressed with 4:2:0 subsampling, and in the - * aggregate, both subsampling methods produce approximately the same - * perceptual quality. However, 4:1:1 is better able to reproduce sharp - * horizontal features. + * 4:1:1 chrominance subsampling + * + * The JPEG or YUV image will contain one chrominance component for every 4x1 + * block of pixels in the source image. All else being equal, a JPEG image + * with 4:1:1 subsampling is almost exactly the same size as a JPEG image + * with 4:2:0 subsampling, and in the aggregate, both subsampling methods + * produce approximately the same perceptual quality. However, 4:1:1 is + * better able to reproduce sharp horizontal features. * * @note 4:1:1 subsampling is not fully accelerated in libjpeg-turbo. */ TJSAMP_411, /** - * 4:4:1 chrominance subsampling. The JPEG or YUV image will contain one - * chrominance component for every 1x4 block of pixels in the source image. - * JPEG images compressed with 4:4:1 subsampling will be almost exactly the - * same size as those compressed with 4:2:0 subsampling, and in the - * aggregate, both subsampling methods produce approximately the same - * perceptual quality. However, 4:4:1 is better able to reproduce sharp - * vertical features. + * 4:4:1 chrominance subsampling + * + * The JPEG or YUV image will contain one chrominance component for every 1x4 + * block of pixels in the source image. All else being equal, a JPEG image + * with 4:4:1 subsampling is almost exactly the same size as a JPEG image + * with 4:2:0 subsampling, and in the aggregate, both subsampling methods + * produce approximately the same perceptual quality. However, 4:4:1 is + * better able to reproduce sharp vertical features. * * @note 4:4:1 subsampling is not fully accelerated in libjpeg-turbo. */ TJSAMP_441, /** - * Unknown subsampling. The JPEG image uses an unusual type of chrominance - * subsampling. Such images can be decompressed into packed-pixel images, - * but they cannot be + * Unknown subsampling + * + * The JPEG image uses an unusual type of chrominance subsampling. Such + * images can be decompressed into packed-pixel images, but they cannot be * - decompressed into planar YUV images, - * - losslessly transformed if #TJXOPT_CROP is specified, or + * - losslessly transformed if #TJXOPT_CROP is specified and #TJXOPT_GRAY is + * not specified, or * - partially decompressed using a cropping region. */ TJSAMP_UNKNOWN = -1 }; /** - * MCU block width (in pixels) for a given level of chrominance subsampling. - * MCU block sizes: + * iMCU width (in pixels) for a given level of chrominance subsampling + * + * In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + * component are interleaved in a single scan. If the image uses chrominance + * subsampling, then multiple luminance blocks are stored together, followed by + * a single block for each chrominance component. The minimum set of + * full-resolution luminance block(s) and corresponding (possibly subsampled) + * chrominance blocks necessary to represent at least one DCT block per + * component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + * in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + * two luminance blocks followed by one block for each chrominance component.) + * In a non-interleaved lossy JPEG image, each component is stored in a + * separate scan, and an MCU is a single DCT block, so we use the term "iMCU" + * (interleaved MCU) to refer to the equivalent of an MCU in an interleaved + * JPEG image. For the common case of interleaved JPEG images, an iMCU is the + * same as an MCU. + * + * iMCU sizes: * - 8x8 for no subsampling or grayscale * - 16x8 for 4:2:2 * - 8x16 for 4:4:0 @@ -194,8 +224,24 @@ enum TJSAMP { static const int tjMCUWidth[TJ_NUMSAMP] = { 8, 16, 16, 8, 8, 32, 8 }; /** - * MCU block height (in pixels) for a given level of chrominance subsampling. - * MCU block sizes: + * iMCU height (in pixels) for a given level of chrominance subsampling + * + * In a typical lossy JPEG image, 8x8 blocks of DCT coefficients for each + * component are interleaved in a single scan. If the image uses chrominance + * subsampling, then multiple luminance blocks are stored together, followed by + * a single block for each chrominance component. The minimum set of + * full-resolution luminance block(s) and corresponding (possibly subsampled) + * chrominance blocks necessary to represent at least one DCT block per + * component is called a "Minimum Coded Unit" or "MCU". (For example, an MCU + * in an interleaved lossy JPEG image that uses 4:2:2 subsampling consists of + * two luminance blocks followed by one block for each chrominance component.) + * In a non-interleaved lossy JPEG image, each component is stored in a + * separate scan, and an MCU is a single DCT block, so we use the term "iMCU" + * (interleaved MCU) to refer to the equivalent of an MCU in an interleaved + * JPEG image. For the common case of interleaved JPEG images, an iMCU is the + * same as an MCU. + * + * iMCU sizes: * - 8x8 for no subsampling or grayscale * - 16x8 for 4:2:2 * - 8x16 for 4:4:0 @@ -216,138 +262,168 @@ static const int tjMCUHeight[TJ_NUMSAMP] = { 8, 8, 16, 8, 16, 8, 32 }; */ enum TJPF { /** - * RGB pixel format. The red, green, and blue components in the image are - * stored in 3-sample pixels in the order R, G, B from lowest to highest - * memory address within each pixel. + * RGB pixel format + * + * The red, green, and blue components in the image are stored in 3-sample + * pixels in the order R, G, B from lowest to highest memory address within + * each pixel. */ TJPF_RGB, /** - * BGR pixel format. The red, green, and blue components in the image are - * stored in 3-sample pixels in the order B, G, R from lowest to highest - * memory address within each pixel. + * BGR pixel format + * + * The red, green, and blue components in the image are stored in 3-sample + * pixels in the order B, G, R from lowest to highest memory address within + * each pixel. */ TJPF_BGR, /** - * RGBX pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order R, G, B from lowest to highest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * RGBX pixel format + * + * The red, green, and blue components in the image are stored in 4-sample + * pixels in the order R, G, B from lowest to highest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ TJPF_RGBX, /** - * BGRX pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order B, G, R from lowest to highest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * BGRX pixel format + * + * The red, green, and blue components in the image are stored in 4-sample + * pixels in the order B, G, R from lowest to highest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ TJPF_BGRX, /** - * XBGR pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order R, G, B from highest to lowest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * XBGR pixel format + * + * The red, green, and blue components in the image are stored in 4-sample + * pixels in the order R, G, B from highest to lowest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ TJPF_XBGR, /** - * XRGB pixel format. The red, green, and blue components in the image are - * stored in 4-sample pixels in the order B, G, R from highest to lowest - * memory address within each pixel. The X component is ignored when - * compressing and undefined when decompressing. + * XRGB pixel format + * + * The red, green, and blue components in the image are stored in 4-sample + * pixels in the order B, G, R from highest to lowest memory address within + * each pixel. The X component is ignored when compressing/encoding and + * undefined when decompressing/decoding. */ TJPF_XRGB, /** - * Grayscale pixel format. Each 1-sample pixel represents a luminance - * (brightness) level from 0 to the maximum sample value (255 for 8-bit - * samples, 4095 for 12-bit samples, and 65535 for 16-bit samples.) + * Grayscale pixel format + * + * Each 1-sample pixel represents a luminance (brightness) level from 0 to + * the maximum sample value (255 for 8-bit samples, 4095 for 12-bit samples, + * and 65535 for 16-bit samples.) */ TJPF_GRAY, /** - * RGBA pixel format. This is the same as @ref TJPF_RGBX, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * RGBA pixel format + * + * This is the same as @ref TJPF_RGBX, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ TJPF_RGBA, /** - * BGRA pixel format. This is the same as @ref TJPF_BGRX, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * BGRA pixel format + * + * This is the same as @ref TJPF_BGRX, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ TJPF_BGRA, /** - * ABGR pixel format. This is the same as @ref TJPF_XBGR, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * ABGR pixel format + * + * This is the same as @ref TJPF_XBGR, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ TJPF_ABGR, /** - * ARGB pixel format. This is the same as @ref TJPF_XRGB, except that when - * decompressing, the X component is guaranteed to be equal to the maximum - * sample value, which can be interpreted as an opaque alpha channel. + * ARGB pixel format + * + * This is the same as @ref TJPF_XRGB, except that when + * decompressing/decoding, the X component is guaranteed to be equal to the + * maximum sample value, which can be interpreted as an opaque alpha channel. */ TJPF_ARGB, /** - * CMYK pixel format. Unlike RGB, which is an additive color model used - * primarily for display, CMYK (Cyan/Magenta/Yellow/Key) is a subtractive - * color model used primarily for printing. In the CMYK color model, the - * value of each color component typically corresponds to an amount of cyan, - * magenta, yellow, or black ink that is applied to a white background. In - * order to convert between CMYK and RGB, it is necessary to use a color - * management system (CMS.) A CMS will attempt to map colors within the - * printer's gamut to perceptually similar colors in the display's gamut and - * vice versa, but the mapping is typically not 1:1 or reversible, nor can it - * be defined with a simple formula. Thus, such a conversion is out of scope - * for a codec library. However, the TurboJPEG API allows for compressing - * packed-pixel CMYK images into YCCK JPEG images (see #TJCS_YCCK) and - * decompressing YCCK JPEG images into packed-pixel CMYK images. + * CMYK pixel format + * + * Unlike RGB, which is an additive color model used primarily for display, + * CMYK (Cyan/Magenta/Yellow/Key) is a subtractive color model used primarily + * for printing. In the CMYK color model, the value of each color component + * typically corresponds to an amount of cyan, magenta, yellow, or black ink + * that is applied to a white background. In order to convert between CMYK + * and RGB, it is necessary to use a color management system (CMS.) A CMS + * will attempt to map colors within the printer's gamut to perceptually + * similar colors in the display's gamut and vice versa, but the mapping is + * typically not 1:1 or reversible, nor can it be defined with a simple + * formula. Thus, such a conversion is out of scope for a codec library. + * However, the TurboJPEG API allows for compressing packed-pixel CMYK images + * into YCCK JPEG images (see #TJCS_YCCK) and decompressing YCCK JPEG images + * into packed-pixel CMYK images. */ TJPF_CMYK, /** - * Unknown pixel format. Currently this is only used by #tj3LoadImage8(), - * #tj3LoadImage12(), and #tj3LoadImage16(). + * Unknown pixel format + * + * Currently this is only used by #tj3LoadImage8(), #tj3LoadImage12(), and + * #tj3LoadImage16(). */ TJPF_UNKNOWN = -1 }; /** - * Red offset (in samples) for a given pixel format. This specifies the number - * of samples that the red component is offset from the start of the pixel. - * For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is stored - * in `unsigned char pixel[]`, then the red component will be - * `pixel[tjRedOffset[TJPF_BGRX]]`. This will be -1 if the pixel format does - * not have a red component. + * Red offset (in samples) for a given pixel format + * + * This specifies the number of samples that the red component is offset from + * the start of the pixel. For instance, if an 8-bit-per-component pixel of + * format TJPF_BGRX is stored in `unsigned char pixel[]`, then the red + * component is `pixel[tjRedOffset[TJPF_BGRX]]`. The offset is -1 if the pixel + * format does not have a red component. */ static const int tjRedOffset[TJ_NUMPF] = { 0, 2, 0, 2, 3, 1, -1, 0, 2, 3, 1, -1 }; /** - * Green offset (in samples) for a given pixel format. This specifies the - * number of samples that the green component is offset from the start of the - * pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is - * stored in `unsigned char pixel[]`, then the green component will be - * `pixel[tjGreenOffset[TJPF_BGRX]]`. This will be -1 if the pixel format does - * not have a green component. + * Green offset (in samples) for a given pixel format + * + * This specifies the number of samples that the green component is offset from + * the start of the pixel. For instance, if an 8-bit-per-component pixel of + * format TJPF_BGRX is stored in `unsigned char pixel[]`, then the green + * component is `pixel[tjGreenOffset[TJPF_BGRX]]`. The offset is -1 if the + * pixel format does not have a green component. */ static const int tjGreenOffset[TJ_NUMPF] = { 1, 1, 1, 1, 2, 2, -1, 1, 1, 2, 2, -1 }; /** - * Blue offset (in samples) for a given pixel format. This specifies the - * number of samples that the blue component is offset from the start of the - * pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRX is - * stored in `unsigned char pixel[]`, then the blue component will be - * `pixel[tjBlueOffset[TJPF_BGRX]]`. This will be -1 if the pixel format does - * not have a blue component. + * Blue offset (in samples) for a given pixel format + * + * This specifies the number of samples that the blue component is offset from + * the start of the pixel. For instance, if an 8-bit-per-component pixel of + * format TJPF_BGRX is stored in `unsigned char pixel[]`, then the blue + * component is `pixel[tjBlueOffset[TJPF_BGRX]]`. The offset is -1 if the + * pixel format does not have a blue component. */ static const int tjBlueOffset[TJ_NUMPF] = { 2, 0, 2, 0, 1, 3, -1, 2, 0, 1, 3, -1 }; /** - * Alpha offset (in samples) for a given pixel format. This specifies the - * number of samples that the alpha component is offset from the start of the - * pixel. For instance, if an 8-bit-per-component pixel of format TJPF_BGRA is - * stored in `unsigned char pixel[]`, then the alpha component will be - * `pixel[tjAlphaOffset[TJPF_BGRA]]`. This will be -1 if the pixel format does - * not have an alpha component. + * Alpha offset (in samples) for a given pixel format + * + * This specifies the number of samples that the alpha component is offset from + * the start of the pixel. For instance, if an 8-bit-per-component pixel of + * format TJPF_BGRA is stored in `unsigned char pixel[]`, then the alpha + * component is `pixel[tjAlphaOffset[TJPF_BGRA]]`. The offset is -1 if the + * pixel format does not have an alpha component. */ static const int tjAlphaOffset[TJ_NUMPF] = { -1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0, -1 @@ -370,73 +446,73 @@ static const int tjPixelSize[TJ_NUMPF] = { */ enum TJCS { /** - * RGB colorspace. When compressing the JPEG image, the R, G, and B - * components in the source image are reordered into image planes, but no - * colorspace conversion or subsampling is performed. RGB JPEG images can be - * compressed from and decompressed to packed-pixel images with any of the - * extended RGB or grayscale pixel formats, but they cannot be compressed - * from or decompressed to planar YUV images. + * RGB colorspace + * + * When generating the JPEG image, the R, G, and B components in the source + * image are reordered into image planes, but no colorspace conversion or + * subsampling is performed. RGB JPEG images can be generated from and + * decompressed to packed-pixel images with any of the extended RGB or + * grayscale pixel formats, but they cannot be generated from or + * decompressed to planar YUV images. */ TJCS_RGB, /** - * YCbCr colorspace. YCbCr is not an absolute colorspace but rather a - * mathematical transformation of RGB designed solely for storage and - * transmission. YCbCr images must be converted to RGB before they can - * actually be displayed. In the YCbCr colorspace, the Y (luminance) - * component represents the black & white portion of the original image, and - * the Cb and Cr (chrominance) components represent the color portion of the - * original image. Originally, the analog equivalent of this transformation - * allowed the same signal to drive both black & white and color televisions, - * but JPEG images use YCbCr primarily because it allows the color data to be - * optionally subsampled for the purposes of reducing network or disk usage. - * YCbCr is the most common JPEG colorspace, and YCbCr JPEG images can be - * compressed from and decompressed to packed-pixel images with any of the - * extended RGB or grayscale pixel formats. YCbCr JPEG images can also be - * compressed from and decompressed to planar YUV images. + * YCbCr colorspace + * + * YCbCr is not an absolute colorspace but rather a mathematical + * transformation of RGB designed solely for storage and transmission. YCbCr + * images must be converted to RGB before they can be displayed. In the + * YCbCr colorspace, the Y (luminance) component represents the black & white + * portion of the original image, and the Cb and Cr (chrominance) components + * represent the color portion of the original image. Historically, the + * analog equivalent of this transformation allowed the same signal to be + * displayed to both black & white and color televisions, but JPEG images use + * YCbCr primarily because it allows the color data to be optionally + * subsampled in order to reduce network and disk usage. YCbCr is the most + * common JPEG colorspace, and YCbCr JPEG images can be generated from and + * decompressed to packed-pixel images with any of the extended RGB or + * grayscale pixel formats. YCbCr JPEG images can also be generated from + * and decompressed to planar YUV images. */ TJCS_YCbCr, /** - * Grayscale colorspace. The JPEG image retains only the luminance data (Y - * component), and any color data from the source image is discarded. - * Grayscale JPEG images can be compressed from and decompressed to - * packed-pixel images with any of the extended RGB or grayscale pixel - * formats, or they can be compressed from and decompressed to planar YUV - * images. + * Grayscale colorspace + * + * The JPEG image retains only the luminance data (Y component), and any + * color data from the source image is discarded. Grayscale JPEG images can + * be generated from and decompressed to packed-pixel images with any of the + * extended RGB or grayscale pixel formats, or they can be generated from + * and decompressed to planar YUV images. */ TJCS_GRAY, /** - * CMYK colorspace. When compressing the JPEG image, the C, M, Y, and K - * components in the source image are reordered into image planes, but no - * colorspace conversion or subsampling is performed. CMYK JPEG images can - * only be compressed from and decompressed to packed-pixel images with the - * CMYK pixel format. + * CMYK colorspace + * + * When generating the JPEG image, the C, M, Y, and K components in the + * source image are reordered into image planes, but no colorspace conversion + * or subsampling is performed. CMYK JPEG images can only be generated from + * and decompressed to packed-pixel images with the CMYK pixel format. */ TJCS_CMYK, /** - * YCCK colorspace. YCCK (AKA "YCbCrK") is not an absolute colorspace but - * rather a mathematical transformation of CMYK designed solely for storage - * and transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be + * YCCK colorspace + * + * YCCK (AKA "YCbCrK") is not an absolute colorspace but rather a + * mathematical transformation of CMYK designed solely for storage and + * transmission. It is to CMYK as YCbCr is to RGB. CMYK pixels can be * reversibly transformed into YCCK, and as with YCbCr, the chrominance * components in the YCCK pixels can be subsampled without incurring major - * perceptual loss. YCCK JPEG images can only be compressed from and + * perceptual loss. YCCK JPEG images can only be generated from and * decompressed to packed-pixel images with the CMYK pixel format. */ TJCS_YCCK }; -/** - * The number of parameters - */ -#define TJ_NUMPARAM - /** * Parameters */ enum TJPARAM { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - TJPARAM_MAXPIXELS = -1, -#endif /** * Error handling behavior * @@ -524,7 +600,7 @@ enum TJPARAM { * * **Value** * - `0` *[default]* Use smooth upsampling when decompressing a JPEG image - * that was compressed using chrominance subsampling. This creates a smooth + * that was generated using chrominance subsampling. This creates a smooth * transition between neighboring chrominance components in order to reduce * upsampling artifacts in the decompressed image. * - `1` Use the fastest chrominance upsampling algorithm available, which @@ -549,13 +625,12 @@ enum TJPARAM { * - The difference in accuracy between the "fast" and "accurate" algorithms * is the most pronounced at JPEG quality levels above 90 and tends to be * more pronounced with decompression than with compression. - * - The "fast" algorithm degrades and is not fully accelerated for JPEG - * quality levels above 97, so it will be slower than the "accurate" - * algorithm. + * - For JPEG quality levels above 97, the "fast" algorithm degrades and is + * not fully accelerated, so it is slower than the "accurate" algorithm. */ TJPARAM_FASTDCT, /** - * Optimized baseline entropy coding [lossy compression only] + * Huffman table optimization [lossy compression, lossless transformation] * * **Value** * - `0` *[default]* The JPEG image will use the default Huffman tables. @@ -563,36 +638,46 @@ enum TJPARAM { * lossless transformation, this can also be specified using * #TJXOPT_OPTIMIZE. * - * Optimized baseline entropy coding will improve compression slightly - * (generally 5% or less), but it will reduce compression performance - * considerably. + * Huffman table optimization improves compression slightly (generally 5% or + * less), but it reduces compression performance considerably. */ TJPARAM_OPTIMIZE, /** - * Progressive entropy coding + * Progressive JPEG + * + * In a progressive JPEG image, the DCT coefficients are split across + * multiple "scans" of increasing quality. Thus, a low-quality scan + * containing the lowest-frequency DCT coefficients can be transmitted first + * and refined with subsequent higher-quality scans containing + * higher-frequency DCT coefficients. When using Huffman entropy coding, the + * progressive JPEG format also provides an "end-of-bands (EOB) run" feature + * that allows large groups of zeroes, potentially spanning multiple MCUs, + * to be represented using only a few bytes. * * **Value** * - `0` *[default for compression, lossless transformation]* The lossy JPEG - * image uses (decompression) or will use (compression, lossless - * transformation) baseline entropy coding. - * - `1` The lossy JPEG image uses (decompression) or will use (compression, - * lossless transformation) progressive entropy coding. For lossless - * transformation, this can also be specified using #TJXOPT_PROGRESSIVE. + * image is (decompression) or will be (compression, lossless transformation) + * single-scan. + * - `1` The lossy JPEG image is (decompression) or will be (compression, + * lossless transformation) progressive. For lossless transformation, this + * can also be specified using #TJXOPT_PROGRESSIVE. * - * Progressive entropy coding will generally improve compression relative to - * baseline entropy coding, but it will reduce compression and decompression - * performance considerably. Can be combined with #TJPARAM_ARITHMETIC. - * Implies #TJPARAM_OPTIMIZE unless #TJPARAM_ARITHMETIC is also set. + * Progressive JPEG images generally have better compression ratios than + * single-scan JPEG images (much better if the image has large areas of solid + * color), but progressive JPEG compression and decompression is considerably + * slower than single-scan JPEG compression and decompression. Can be + * combined with #TJPARAM_ARITHMETIC. Implies #TJPARAM_OPTIMIZE unless + * #TJPARAM_ARITHMETIC is also set. */ TJPARAM_PROGRESSIVE, /** * Progressive JPEG scan limit for lossy JPEG images [decompression, lossless * transformation] * - * Setting this parameter will cause the decompression and transform - * functions to return an error if the number of scans in a progressive JPEG - * image exceeds the specified limit. The primary purpose of this is to - * allow security-critical applications to guard against an exploit of the + * Setting this parameter causes the decompression and transform functions to + * return an error if the number of scans in a progressive JPEG image exceeds + * the specified limit. The primary purpose of this is to allow + * security-critical applications to guard against an exploit of the * progressive JPEG format described in * this report. * @@ -614,8 +699,8 @@ enum TJPARAM { * lossless transformation) arithmetic entropy coding. For lossless * transformation, this can also be specified using #TJXOPT_ARITHMETIC. * - * Arithmetic entropy coding will generally improve compression relative to - * Huffman entropy coding, but it will reduce compression and decompression + * Arithmetic entropy coding generally improves compression relative to + * Huffman entropy coding, but it reduces compression and decompression * performance considerably. Can be combined with #TJPARAM_PROGRESSIVE. */ TJPARAM_ARITHMETIC, @@ -628,17 +713,19 @@ enum TJPARAM { * - `1` The JPEG image is (decompression) or will be (compression) * lossless/predictive. * - * In most cases, compressing and decompressing lossless JPEG images is - * considerably slower than compressing and decompressing lossy JPEG images. - * Also note that the following features are not available with lossless JPEG - * images: + * In most cases, lossless JPEG compression and decompression is considerably + * slower than lossy JPEG compression and decompression, and lossless JPEG + * images are much larger than lossy JPEG images. Thus, lossless JPEG images + * are typically used only for applications that require mathematically + * lossless compression. Also note that the following features are not + * available with lossless JPEG images: * - Colorspace conversion (lossless JPEG images always use #TJCS_RGB, * #TJCS_GRAY, or #TJCS_CMYK, depending on the pixel format of the source * image) * - Chrominance subsampling (lossless JPEG images always use #TJSAMP_444) * - JPEG quality selection * - DCT/IDCT algorithm selection - * - Progressive entropy coding + * - Progressive JPEG * - Arithmetic entropy coding * - Compression from/decompression to planar YUV images * - Decompression scaling @@ -653,6 +740,30 @@ enum TJPARAM { * **Value** * - `1`-`7` *[default for compression: `1`]* * + * Lossless JPEG compression shares no algorithms with lossy JPEG + * compression. Instead, it uses differential pulse-code modulation (DPCM), + * an algorithm whereby each sample is encoded as the difference between the + * sample's value and a "predictor", which is based on the values of + * neighboring samples. If Ra is the sample immediately to the left of the + * current sample, Rb is the sample immediately above the current sample, and + * Rc is the sample diagonally to the left and above the current sample, then + * the relationship between the predictor selection value and the predictor + * is as follows: + * + * PSV | Predictor + * ----|---------- + * 1 | Ra + * 2 | Rb + * 3 | Rc + * 4 | Ra + Rb – Rc + * 5 | Ra + (Rb – Rc) / 2 + * 6 | Rb + (Ra – Rc) / 2 + * 7 | (Ra + Rb) / 2 + * + * Predictors 1-3 are 1-dimensional predictors, whereas Predictors 4-7 are + * 2-dimensional predictors. The best predictor for a particular image + * depends on the image. + * * @see #TJPARAM_LOSSLESS */ TJPARAM_LOSSLESSPSV, @@ -672,8 +783,7 @@ enum TJPARAM { */ TJPARAM_LOSSLESSPT, /** - * JPEG restart marker interval in MCU blocks (lossy) or samples (lossless) - * [compression only] + * JPEG restart marker interval in MCUs [lossy compression only] * * The nature of entropy coding is such that a corrupt JPEG image cannot * be decompressed beyond the point of corruption unless it contains restart @@ -683,22 +793,30 @@ enum TJPARAM { * tolerance of the JPEG image, but adding too many restart markers can * adversely affect the compression ratio and performance. * + * In typical JPEG images, an MCU (Minimum Coded Unit) is the minimum set of + * interleaved "data units" (8x8 DCT blocks if the image is lossy or samples + * if the image is lossless) necessary to represent at least one data unit + * per component. (For example, an MCU in an interleaved lossy JPEG image + * that uses 4:2:2 subsampling consists of two luminance blocks followed by + * one block for each chrominance component.) In single-component or + * non-interleaved JPEG images, an MCU is the same as a data unit. + * * **Value** - * - the number of MCU blocks or samples between each restart marker - * *[default: `0` (no restart markers)]* + * - the number of MCUs between each restart marker *[default: `0` (no + * restart markers)]* * * Setting this parameter to a non-zero value sets #TJPARAM_RESTARTROWS to 0. */ TJPARAM_RESTARTBLOCKS, /** - * JPEG restart marker interval in MCU rows (lossy) or sample rows (lossless) - * [compression only] + * JPEG restart marker interval in MCU rows [compression only] * - * See #TJPARAM_RESTARTBLOCKS for a description of restart markers. + * See #TJPARAM_RESTARTBLOCKS for a description of restart markers and MCUs. + * An MCU row is a row of MCUs spanning the entire width of the image. * * **Value** - * - the number of MCU rows or sample rows between each restart marker - * *[default: `0` (no restart markers)]* + * - the number of MCU rows between each restart marker *[default: `0` (no + * restart markers)]* * * Setting this parameter to a non-zero value sets #TJPARAM_RESTARTBLOCKS to * 0. @@ -715,10 +833,10 @@ enum TJPARAM { * the contents of the JPEG image. Note that this parameter is set by * #tj3LoadImage8() when loading a Windows BMP file that contains pixel * density information, and the value of this parameter is stored to a - * Windows BMP file by #tj3SaveImage8() if the value of #TJPARAM_DENSITYUNIT + * Windows BMP file by #tj3SaveImage8() if the value of #TJPARAM_DENSITYUNITS * is `2`. * - * @see TJPARAM_DENSITYUNIT + * @see TJPARAM_DENSITYUNITS */ TJPARAM_XDENSITY, /** @@ -732,10 +850,10 @@ enum TJPARAM { * the contents of the JPEG image. Note that this parameter is set by * #tj3LoadImage8() when loading a Windows BMP file that contains pixel * density information, and the value of this parameter is stored to a - * Windows BMP file by #tj3SaveImage8() if the value of #TJPARAM_DENSITYUNIT + * Windows BMP file by #tj3SaveImage8() if the value of #TJPARAM_DENSITYUNITS * is `2`. * - * @see TJPARAM_DENSITYUNIT + * @see TJPARAM_DENSITYUNITS */ TJPARAM_YDENSITY, /** @@ -758,7 +876,31 @@ enum TJPARAM { * * @see TJPARAM_XDENSITY, TJPARAM_YDENSITY */ - TJPARAM_DENSITYUNITS + TJPARAM_DENSITYUNITS, + /** + * Memory limit for intermediate buffers + * + * **Value** + * - the maximum amount of memory (in megabytes) that will be allocated for + * intermediate buffers, which are used with progressive JPEG compression and + * decompression, Huffman table optimization, lossless JPEG compression, and + * lossless transformation *[default: `0` (no limit)]* + */ + TJPARAM_MAXMEMORY, + /** + * Image size limit [decompression, lossless transformation, packed-pixel + * image loading] + * + * Setting this parameter causes the decompression, transform, and image + * loading functions to return an error if the number of pixels in the source + * image exceeds the specified limit. This allows security-critical + * applications to guard against excessive memory consumption. + * + * **Value** + * - maximum number of pixels that the decompression, transform, and image + * loading functions will process *[default: `0` (no limit)]* + */ + TJPARAM_MAXPIXELS }; @@ -793,17 +935,17 @@ enum TJERR { */ enum TJXOP { /** - * Do not transform the position of the image pixels + * Do not transform the position of the image pixels. */ TJXOP_NONE, /** * Flip (mirror) image horizontally. This transform is imperfect if there - * are any partial MCU blocks on the right edge (see #TJXOPT_PERFECT.) + * are any partial iMCUs on the right edge (see #TJXOPT_PERFECT.) */ TJXOP_HFLIP, /** * Flip (mirror) image vertically. This transform is imperfect if there are - * any partial MCU blocks on the bottom edge (see #TJXOPT_PERFECT.) + * any partial iMCUs on the bottom edge (see #TJXOPT_PERFECT.) */ TJXOP_VFLIP, /** @@ -813,92 +955,85 @@ enum TJXOP { TJXOP_TRANSPOSE, /** * Transverse transpose image (flip/mirror along upper right to lower left - * axis.) This transform is imperfect if there are any partial MCU blocks in - * the image (see #TJXOPT_PERFECT.) + * axis.) This transform is imperfect if there are any partial iMCUs in the + * image (see #TJXOPT_PERFECT.) */ TJXOP_TRANSVERSE, /** * Rotate image clockwise by 90 degrees. This transform is imperfect if - * there are any partial MCU blocks on the bottom edge (see - * #TJXOPT_PERFECT.) + * there are any partial iMCUs on the bottom edge (see #TJXOPT_PERFECT.) */ TJXOP_ROT90, /** * Rotate image 180 degrees. This transform is imperfect if there are any - * partial MCU blocks in the image (see #TJXOPT_PERFECT.) + * partial iMCUs in the image (see #TJXOPT_PERFECT.) */ TJXOP_ROT180, /** * Rotate image counter-clockwise by 90 degrees. This transform is imperfect - * if there are any partial MCU blocks on the right edge (see - * #TJXOPT_PERFECT.) + * if there are any partial iMCUs on the right edge (see #TJXOPT_PERFECT.) */ TJXOP_ROT270 }; /** - * This option will cause #tj3Transform() to return an error if the transform - * is not perfect. Lossless transforms operate on MCU blocks, whose size + * This option causes #tj3Transform() to return an error if the transform is + * not perfect. Lossless transforms operate on iMCUs, the size of which * depends on the level of chrominance subsampling used (see #tjMCUWidth and * #tjMCUHeight.) If the image's width or height is not evenly divisible by - * the MCU block size, then there will be partial MCU blocks on the right - * and/or bottom edges. It is not possible to move these partial MCU blocks to - * the top or left of the image, so any transform that would require that is - * "imperfect." If this option is not specified, then any partial MCU blocks - * that cannot be transformed will be left in place, which will create - * odd-looking strips on the right or bottom edge of the image. + * the iMCU size, then there will be partial iMCUs on the right and/or bottom + * edges. It is not possible to move these partial iMCUs to the top or left of + * the image, so any transform that would require that is "imperfect." If this + * option is not specified, then any partial iMCUs that cannot be transformed + * will be left in place, which will create odd-looking strips on the right or + * bottom edge of the image. */ #define TJXOPT_PERFECT (1 << 0) /** - * This option will cause #tj3Transform() to discard any partial MCU blocks - * that cannot be transformed. + * Discard any partial iMCUs that cannot be transformed. */ #define TJXOPT_TRIM (1 << 1) /** - * This option will enable lossless cropping. See #tj3Transform() for more - * information. + * Enable lossless cropping. See #tj3Transform() for more information. */ #define TJXOPT_CROP (1 << 2) /** - * This option will discard the color data in the source image and produce a - * grayscale destination image. + * Discard the color data in the source image, and generate a grayscale + * destination image. */ #define TJXOPT_GRAY (1 << 3) /** - * This option will prevent #tj3Transform() from outputting a JPEG image for - * this particular transform. (This can be used in conjunction with a custom - * filter to capture the transformed DCT coefficients without transcoding - * them.) + * Do not generate a destination image. (This can be used in conjunction with + * a custom filter to capture the transformed DCT coefficients without + * transcoding them.) */ #define TJXOPT_NOOUTPUT (1 << 4) /** - * This option will enable progressive entropy coding in the JPEG image - * generated by this particular transform. Progressive entropy coding will - * generally improve compression relative to baseline entropy coding (the - * default), but it will reduce decompression performance considerably. - * Can be combined with #TJXOPT_ARITHMETIC. Implies #TJXOPT_OPTIMIZE unless - * #TJXOPT_ARITHMETIC is also specified. + * Generate a progressive destination image instead of a single-scan + * destination image. Progressive JPEG images generally have better + * compression ratios than single-scan JPEG images (much better if the image + * has large areas of solid color), but progressive JPEG decompression is + * considerably slower than single-scan JPEG decompression. Can be combined + * with #TJXOPT_ARITHMETIC. Implies #TJXOPT_OPTIMIZE unless #TJXOPT_ARITHMETIC + * is also specified. */ #define TJXOPT_PROGRESSIVE (1 << 5) /** - * This option will prevent #tj3Transform() from copying any extra markers - * (including EXIF and ICC profile data) from the source image to the - * destination image. + * Do not copy any extra markers (including Exif and ICC profile data) from the + * source image to the destination image. */ #define TJXOPT_COPYNONE (1 << 6) /** - * This option will enable arithmetic entropy coding in the JPEG image - * generated by this particular transform. Arithmetic entropy coding will - * generally improve compression relative to Huffman entropy coding (the - * default), but it will reduce decompression performance considerably. Can be - * combined with #TJXOPT_PROGRESSIVE. + * Enable arithmetic entropy coding in the destination image. Arithmetic + * entropy coding generally improves compression relative to Huffman entropy + * coding (the default), but it reduces decompression performance considerably. + * Can be combined with #TJXOPT_PROGRESSIVE. */ #define TJXOPT_ARITHMETIC (1 << 7) /** - * This option will enable optimized baseline entropy coding in the JPEG image - * generated by this particular transform. Optimized baseline entropy coding - * will improve compression slightly (generally 5% or less.) + * Enable Huffman table optimization for the destination image. Huffman table + * optimization improves compression slightly (generally 5% or less.) */ #define TJXOPT_OPTIMIZE (1 << 8) @@ -922,13 +1057,16 @@ typedef struct { */ typedef struct { /** - * The left boundary of the cropping region. This must be evenly divisible - * by the MCU block width (see #tjMCUWidth.) + * The left boundary of the cropping region. For lossless transformation, + * this must be evenly divisible by the iMCU width (see #tjMCUWidth) of the + * destination image. For decompression, this must be evenly divisible by + * the scaled iMCU width of the source image. */ int x; /** * The upper boundary of the cropping region. For lossless transformation, - * this must be evenly divisible by the MCU block height (see #tjMCUHeight.) + * this must be evenly divisible by the iMCU height (see #tjMCUHeight) of the + * destination image. */ int y; /** @@ -977,7 +1115,7 @@ typedef struct tjtransform { * applied in the frequency domain. * * @param coeffs pointer to an array of transformed DCT coefficients. (NOTE: - * this pointer is not guaranteed to be valid once the callback returns, so + * This pointer is not guaranteed to be valid once the callback returns, so * applications wishing to hand off the DCT coefficients to another function * or library should make a copy of them within the body of the callback.) * @@ -1046,6 +1184,40 @@ extern "C" { DLLEXPORT tjhandle tj3Init(int initType); +/** + * Destroy a TurboJPEG instance. + * + * @param handle handle to a TurboJPEG instance. If the handle is NULL, then + * this function has no effect. + */ +DLLEXPORT void tj3Destroy(tjhandle handle); + + +/** + * Returns a descriptive error message explaining why the last command failed. + * + * @param handle handle to a TurboJPEG instance, or NULL if the error was + * generated by a global function (but note that retrieving the error message + * for a global function is thread-safe only on platforms that support + * thread-local storage.) + * + * @return a descriptive error message explaining why the last command failed. + */ +DLLEXPORT char *tj3GetErrorStr(tjhandle handle); + + +/** + * Returns a code indicating the severity of the last error. See + * @ref TJERR "Error codes". + * + * @param handle handle to a TurboJPEG instance + * + * @return a code indicating the severity of the last error. See + * @ref TJERR "Error codes". + */ +DLLEXPORT int tj3GetErrorCode(tjhandle handle); + + /** * Set the value of a parameter. * @@ -1073,6 +1245,145 @@ DLLEXPORT int tj3Set(tjhandle handle, int param, int value); DLLEXPORT int tj3Get(tjhandle handle, int param); +/** + * Allocate a byte buffer for use with TurboJPEG. You should always use this + * function to allocate the JPEG destination buffer(s) for the compression and + * transform functions unless you are disabling automatic buffer (re)allocation + * (by setting #TJPARAM_NOREALLOC.) + * + * @param bytes the number of bytes to allocate + * + * @return a pointer to a newly-allocated buffer with the specified number of + * bytes. + * + * @see tj3Free() + */ +DLLEXPORT void *tj3Alloc(size_t bytes); + + +/** + * Free a byte buffer previously allocated by TurboJPEG. You should always use + * this function to free JPEG destination buffer(s) that were automatically + * (re)allocated by the compression and transform functions or that were + * manually allocated using #tj3Alloc(). + * + * @param buffer address of the buffer to free. If the address is NULL, then + * this function has no effect. + * + * @see tj3Alloc() + */ +DLLEXPORT void tj3Free(void *buffer); + + +/** + * The maximum size of the buffer (in bytes) required to hold a JPEG image with + * the given parameters. The number of bytes returned by this function is + * larger than the size of the uncompressed source image. The reason for this + * is that the JPEG format uses 16-bit coefficients, so it is possible for a + * very high-quality source image with very high-frequency content to expand + * rather than compress when converted to the JPEG format. Such images + * represent very rare corner cases, but since there is no way to predict the + * size of a JPEG image prior to compression, the corner cases have to be + * handled. + * + * @param width width (in pixels) of the image + * + * @param height height (in pixels) of the image + * + * @param jpegSubsamp the level of chrominance subsampling to be used when + * generating the JPEG image (see @ref TJSAMP + * "Chrominance subsampling options".) #TJSAMP_UNKNOWN is treated like + * #TJSAMP_444, since a buffer large enough to hold a JPEG image with no + * subsampling should also be large enough to hold a JPEG image with an + * arbitrary level of subsampling. Note that lossless JPEG images always + * use #TJSAMP_444. + * + * @return the maximum size of the buffer (in bytes) required to hold the + * image, or 0 if the arguments are out of bounds. + */ +DLLEXPORT size_t tj3JPEGBufSize(int width, int height, int jpegSubsamp); + + +/** + * The size of the buffer (in bytes) required to hold a unified planar YUV + * image with the given parameters. + * + * @param width width (in pixels) of the image + * + * @param align row alignment (in bytes) of the image (must be a power of 2.) + * Setting this parameter to n specifies that each row in each plane of the + * image will be padded to the nearest multiple of n bytes (1 = unpadded.) + * + * @param height height (in pixels) of the image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the size of the buffer (in bytes) required to hold the image, or 0 + * if the arguments are out of bounds. + */ +DLLEXPORT size_t tj3YUVBufSize(int width, int align, int height, int subsamp); + + +/** + * The size of the buffer (in bytes) required to hold a YUV image plane with + * the given parameters. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param width width (in pixels) of the YUV image. NOTE: This is the width of + * the whole image, not the plane width. + * + * @param stride bytes per row in the image plane. Setting this to 0 is the + * equivalent of setting it to the plane width. + * + * @param height height (in pixels) of the YUV image. NOTE: This is the height + * of the whole image, not the plane height. + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the size of the buffer (in bytes) required to hold the YUV image + * plane, or 0 if the arguments are out of bounds. + */ +DLLEXPORT size_t tj3YUVPlaneSize(int componentID, int width, int stride, + int height, int subsamp); + + +/** + * The plane width of a YUV image plane with the given parameters. Refer to + * @ref YUVnotes "YUV Image Format Notes" for a description of plane width. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param width width (in pixels) of the YUV image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the plane width of a YUV image plane with the given parameters, or 0 + * if the arguments are out of bounds. + */ +DLLEXPORT int tj3YUVPlaneWidth(int componentID, int width, int subsamp); + + +/** + * The plane height of a YUV image plane with the given parameters. Refer to + * @ref YUVnotes "YUV Image Format Notes" for a description of plane height. + * + * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) + * + * @param height height (in pixels) of the YUV image + * + * @param subsamp level of chrominance subsampling in the image (see + * @ref TJSAMP "Chrominance subsampling options".) + * + * @return the plane height of a YUV image plane with the given parameters, or + * 0 if the arguments are out of bounds. + */ +DLLEXPORT int tj3YUVPlaneHeight(int componentID, int height, int subsamp); + + /** * Compress an 8-bit-per-sample packed-pixel RGB, grayscale, or CMYK image into * an 8-bit-per-sample JPEG image. @@ -1151,31 +1462,36 @@ DLLEXPORT int tj3Compress16(tjhandle handle, const unsigned short *srcBuf, /** - * Compress an 8-bit-per-sample unified planar YUV image into an - * 8-bit-per-sample JPEG image. + * Compress a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into + * an 8-bit-per-sample JPEG image. * * @param handle handle to a TurboJPEG instance that has been initialized for * compression * - * @param srcBuf pointer to a buffer containing a unified planar YUV source - * image to be compressed. The size of this buffer should match the value - * returned by #tj3YUVBufSize() for the given image width, height, row - * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The - * Y, U (Cb), and V (Cr) image planes should be stored sequentially in the - * buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) + * @param srcPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if compressing a grayscale image) that contain a YUV + * source image to be compressed. These planes can be contiguous or + * non-contiguous in memory. The size of each plane should match the value + * returned by #tj3YUVPlaneSize() for the given image width, height, strides, + * and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) Refer to + * @ref YUVnotes "YUV Image Format Notes" for more details. * * @param width width (in pixels) of the source image. If the width is not an - * even multiple of the MCU block width (see #tjMCUWidth), then an intermediate + * even multiple of the iMCU width (see #tjMCUWidth), then an intermediate * buffer copy will be performed. * - * @param align row alignment (in bytes) of the source image (must be a power - * of 2.) Setting this parameter to n indicates that each row in each plane of - * the source image is padded to the nearest multiple of n bytes - * (1 = unpadded.) + * @param strides an array of integers, each specifying the number of bytes per + * row in the corresponding plane of the YUV source image. Setting the stride + * for any plane to 0 is the same as setting it to the plane width (see + * @ref YUVnotes "YUV Image Format Notes".) If `strides` is NULL, then the + * strides for all planes will be set to their respective plane widths. You + * can adjust the strides in order to specify an arbitrary amount of row + * padding in each plane or to create a JPEG image from a subregion of a larger + * planar YUV image. * * @param height height (in pixels) of the source image. If the height is not - * an even multiple of the MCU block height (see #tjMCUHeight), then an - * intermediate buffer copy will be performed. + * an even multiple of the iMCU height (see #tjMCUHeight), then an intermediate + * buffer copy will be performed. * * @param jpegBuf address of a pointer to a byte buffer that will receive the * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to @@ -1203,43 +1519,39 @@ DLLEXPORT int tj3Compress16(tjhandle handle, const unsigned short *srcBuf, * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() * and #tj3GetErrorCode().) */ -DLLEXPORT int tj3CompressFromYUV8(tjhandle handle, - const unsigned char *srcBuf, int width, - int align, int height, - unsigned char **jpegBuf, size_t *jpegSize); +DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle, + const unsigned char * const *srcPlanes, + int width, const int *strides, + int height, unsigned char **jpegBuf, + size_t *jpegSize); /** - * Compress a set of 8-bit-per-sample Y, U (Cb), and V (Cr) image planes into - * an 8-bit-per-sample JPEG image. + * Compress an 8-bit-per-sample unified planar YUV image into an + * 8-bit-per-sample JPEG image. * * @param handle handle to a TurboJPEG instance that has been initialized for * compression * - * @param srcPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes - * (or just a Y plane, if compressing a grayscale image) that contain a YUV - * source image to be compressed. These planes can be contiguous or - * non-contiguous in memory. The size of each plane should match the value - * returned by #tj3YUVPlaneSize() for the given image width, height, strides, - * and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) Refer to - * @ref YUVnotes "YUV Image Format Notes" for more details. + * @param srcBuf pointer to a buffer containing a unified planar YUV source + * image to be compressed. The size of this buffer should match the value + * returned by #tj3YUVBufSize() for the given image width, height, row + * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The + * Y, U (Cb), and V (Cr) image planes should be stored sequentially in the + * buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) * * @param width width (in pixels) of the source image. If the width is not an - * even multiple of the MCU block width (see #tjMCUWidth), then an intermediate + * even multiple of the iMCU width (see #tjMCUWidth), then an intermediate * buffer copy will be performed. * - * @param strides an array of integers, each specifying the number of bytes per - * row in the corresponding plane of the YUV source image. Setting the stride - * for any plane to 0 is the same as setting it to the plane width (see - * @ref YUVnotes "YUV Image Format Notes".) If `strides` is NULL, then the - * strides for all planes will be set to their respective plane widths. You - * can adjust the strides in order to specify an arbitrary amount of row - * padding in each plane or to create a JPEG image from a subregion of a larger - * planar YUV image. + * @param align row alignment (in bytes) of the source image (must be a power + * of 2.) Setting this parameter to n indicates that each row in each plane of + * the source image is padded to the nearest multiple of n bytes + * (1 = unpadded.) * * @param height height (in pixels) of the source image. If the height is not - * an even multiple of the MCU block height (see #tjMCUHeight), then an - * intermediate buffer copy will be performed. + * an even multiple of the iMCU height (see #tjMCUHeight), then an intermediate + * buffer copy will be performed. * * @param jpegBuf address of a pointer to a byte buffer that will receive the * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer to @@ -1267,127 +1579,17 @@ DLLEXPORT int tj3CompressFromYUV8(tjhandle handle, * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() * and #tj3GetErrorCode().) */ -DLLEXPORT int tj3CompressFromYUVPlanes8(tjhandle handle, - const unsigned char * const *srcPlanes, - int width, const int *strides, - int height, unsigned char **jpegBuf, - size_t *jpegSize); - - -/** - * The maximum size of the buffer (in bytes) required to hold a JPEG image with - * the given parameters. The number of bytes returned by this function is - * larger than the size of the uncompressed source image. The reason for this - * is that the JPEG format uses 16-bit coefficients, so it is possible for a - * very high-quality source image with very high-frequency content to expand - * rather than compress when converted to the JPEG format. Such images - * represent very rare corner cases, but since there is no way to predict the - * size of a JPEG image prior to compression, the corner cases have to be - * handled. - * - * @param width width (in pixels) of the image - * - * @param height height (in pixels) of the image - * - * @param jpegSubsamp the level of chrominance subsampling to be used when - * generating the JPEG image (see @ref TJSAMP - * "Chrominance subsampling options".) #TJSAMP_UNKNOWN is treated like - * #TJSAMP_444, since a buffer large enough to hold a JPEG image with no - * subsampling should also be large enough to hold a JPEG image with an - * arbitrary level of subsampling. Note that lossless JPEG images always - * use #TJSAMP_444. - * - * @return the maximum size of the buffer (in bytes) required to hold the - * image, or 0 if the arguments are out of bounds. - */ -DLLEXPORT size_t tj3JPEGBufSize(int width, int height, int jpegSubsamp); - - -/** - * The size of the buffer (in bytes) required to hold a unified planar YUV - * image with the given parameters. - * - * @param width width (in pixels) of the image - * - * @param align row alignment (in bytes) of the image (must be a power of 2.) - * Setting this parameter to n specifies that each row in each plane of the - * image will be padded to the nearest multiple of n bytes (1 = unpadded.) - * - * @param height height (in pixels) of the image - * - * @param subsamp level of chrominance subsampling in the image (see - * @ref TJSAMP "Chrominance subsampling options".) - * - * @return the size of the buffer (in bytes) required to hold the image, or 0 - * if the arguments are out of bounds. - */ -DLLEXPORT size_t tj3YUVBufSize(int width, int align, int height, int subsamp); - - -/** - * The size of the buffer (in bytes) required to hold a YUV image plane with - * the given parameters. - * - * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) - * - * @param width width (in pixels) of the YUV image. NOTE: this is the width of - * the whole image, not the plane width. - * - * @param stride bytes per row in the image plane. Setting this to 0 is the - * equivalent of setting it to the plane width. - * - * @param height height (in pixels) of the YUV image. NOTE: this is the height - * of the whole image, not the plane height. - * - * @param subsamp level of chrominance subsampling in the image (see - * @ref TJSAMP "Chrominance subsampling options".) - * - * @return the size of the buffer (in bytes) required to hold the YUV image - * plane, or 0 if the arguments are out of bounds. - */ -DLLEXPORT size_t tj3YUVPlaneSize(int componentID, int width, int stride, - int height, int subsamp); - - -/** - * The plane width of a YUV image plane with the given parameters. Refer to - * @ref YUVnotes "YUV Image Format Notes" for a description of plane width. - * - * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) - * - * @param width width (in pixels) of the YUV image - * - * @param subsamp level of chrominance subsampling in the image (see - * @ref TJSAMP "Chrominance subsampling options".) - * - * @return the plane width of a YUV image plane with the given parameters, or 0 - * if the arguments are out of bounds. - */ -DLLEXPORT int tj3YUVPlaneWidth(int componentID, int width, int subsamp); - - -/** - * The plane height of a YUV image plane with the given parameters. Refer to - * @ref YUVnotes "YUV Image Format Notes" for a description of plane height. - * - * @param componentID ID number of the image plane (0 = Y, 1 = U/Cb, 2 = V/Cr) - * - * @param height height (in pixels) of the YUV image - * - * @param subsamp level of chrominance subsampling in the image (see - * @ref TJSAMP "Chrominance subsampling options".) - * - * @return the plane height of a YUV image plane with the given parameters, or - * 0 if the arguments are out of bounds. - */ -DLLEXPORT int tj3YUVPlaneHeight(int componentID, int height, int subsamp); +DLLEXPORT int tj3CompressFromYUV8(tjhandle handle, + const unsigned char *srcBuf, int width, + int align, int height, + unsigned char **jpegBuf, size_t *jpegSize); /** - * Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into an - * 8-bit-per-sample unified planar YUV image. This function performs color - * conversion (which is accelerated in the libjpeg-turbo implementation) but - * does not execute any of the other steps in the JPEG compression process. + * Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into separate + * 8-bit-per-sample Y, U (Cb), and V (Cr) image planes. This function performs + * color conversion (which is accelerated in the libjpeg-turbo implementation) + * but does not execute any of the other steps in the JPEG compression process. * * @param handle handle to a TurboJPEG instance that has been initialized for * compression @@ -1397,6 +1599,7 @@ DLLEXPORT int tj3YUVPlaneHeight(int componentID, int height, int subsamp); * bytes in size. However, you can also use this parameter to encode from a * specific region of a larger buffer. * + * * @param width width (in pixels) of the source image * * @param pitch bytes per row in the source image. Normally this should be @@ -1411,31 +1614,37 @@ DLLEXPORT int tj3YUVPlaneHeight(int componentID, int height, int subsamp); * @param pixelFormat pixel format of the source image (see @ref TJPF * "Pixel formats".) * - * @param dstBuf pointer to a buffer that will receive the unified planar YUV - * image. Use #tj3YUVBufSize() to determine the appropriate size for this - * buffer based on the image width, height, row alignment, and level of - * chrominance subsampling (see #TJPARAM_SUBSAMP.) The Y, U (Cb), and V (Cr) - * image planes will be stored sequentially in the buffer. (Refer to - * @ref YUVnotes "YUV Image Format Notes".) + * @param dstPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes + * (or just a Y plane, if generating a grayscale image) that will receive the + * encoded image. These planes can be contiguous or non-contiguous in memory. + * Use #tj3YUVPlaneSize() to determine the appropriate size for each plane + * based on the image width, height, strides, and level of chrominance + * subsampling (see #TJPARAM_SUBSAMP.) Refer to @ref YUVnotes + * "YUV Image Format Notes" for more details. * - * @param align row alignment (in bytes) of the YUV image (must be a power of - * 2.) Setting this parameter to n will cause each row in each plane of the - * YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.) - * To generate images suitable for X Video, `align` should be set to 4. + * @param strides an array of integers, each specifying the number of bytes per + * row in the corresponding plane of the YUV image. Setting the stride for any + * plane to 0 is the same as setting it to the plane width (see @ref YUVnotes + * "YUV Image Format Notes".) If `strides` is NULL, then the strides for all + * planes will be set to their respective plane widths. You can adjust the + * strides in order to add an arbitrary amount of row padding to each plane or + * to encode an RGB or grayscale image into a subregion of a larger planar YUV + * image. * * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() * and #tj3GetErrorCode().) */ -DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, int pixelFormat, - unsigned char *dstBuf, int align); +DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, + int pixelFormat, unsigned char **dstPlanes, + int *strides); /** - * Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into separate - * 8-bit-per-sample Y, U (Cb), and V (Cr) image planes. This function performs - * color conversion (which is accelerated in the libjpeg-turbo implementation) - * but does not execute any of the other steps in the JPEG compression process. + * Encode an 8-bit-per-sample packed-pixel RGB or grayscale image into an + * 8-bit-per-sample unified planar YUV image. This function performs color + * conversion (which is accelerated in the libjpeg-turbo implementation) but + * does not execute any of the other steps in the JPEG compression process. * * @param handle handle to a TurboJPEG instance that has been initialized for * compression @@ -1445,7 +1654,6 @@ DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, * bytes in size. However, you can also use this parameter to encode from a * specific region of a larger buffer. * - * * @param width width (in pixels) of the source image * * @param pitch bytes per row in the source image. Normally this should be @@ -1460,30 +1668,24 @@ DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, * @param pixelFormat pixel format of the source image (see @ref TJPF * "Pixel formats".) * - * @param dstPlanes an array of pointers to Y, U (Cb), and V (Cr) image planes - * (or just a Y plane, if generating a grayscale image) that will receive the - * encoded image. These planes can be contiguous or non-contiguous in memory. - * Use #tj3YUVPlaneSize() to determine the appropriate size for each plane - * based on the image width, height, strides, and level of chrominance - * subsampling (see #TJPARAM_SUBSAMP.) Refer to @ref YUVnotes - * "YUV Image Format Notes" for more details. + * @param dstBuf pointer to a buffer that will receive the unified planar YUV + * image. Use #tj3YUVBufSize() to determine the appropriate size for this + * buffer based on the image width, height, row alignment, and level of + * chrominance subsampling (see #TJPARAM_SUBSAMP.) The Y, U (Cb), and V (Cr) + * image planes will be stored sequentially in the buffer. (Refer to + * @ref YUVnotes "YUV Image Format Notes".) * - * @param strides an array of integers, each specifying the number of bytes per - * row in the corresponding plane of the YUV image. Setting the stride for any - * plane to 0 is the same as setting it to the plane width (see @ref YUVnotes - * "YUV Image Format Notes".) If `strides` is NULL, then the strides for all - * planes will be set to their respective plane widths. You can adjust the - * strides in order to add an arbitrary amount of row padding to each plane or - * to encode an RGB or grayscale image into a subregion of a larger planar YUV - * image. + * @param align row alignment (in bytes) of the YUV image (must be a power of + * 2.) Setting this parameter to n will cause each row in each plane of the + * YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.) + * To generate images suitable for X Video, `align` should be set to 4. * * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() * and #tj3GetErrorCode().) */ -DLLEXPORT int tj3EncodeYUVPlanes8(tjhandle handle, const unsigned char *srcBuf, - int width, int pitch, int height, - int pixelFormat, unsigned char **dstPlanes, - int *strides); +DLLEXPORT int tj3EncodeYUV8(tjhandle handle, const unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, + unsigned char *dstBuf, int align); /** @@ -1542,7 +1744,7 @@ DLLEXPORT tjscalingfactor *tj3GetScalingFactors(int *numScalingFactors); * #TJPARAM_JPEGHEIGHT) and the specified scaling factor. When decompressing * into a planar YUV image, an intermediate buffer copy will be performed if * the width or height of the scaled destination image is not an even multiple - * of the MCU block size (see #tjMCUWidth and #tjMCUHeight.) Note that + * of the iMCU size (see #tjMCUWidth and #tjMCUHeight.) Note that * decompression scaling is not available (and the specified scaling factor is * ignored) when decompressing lossless JPEG images (see #TJPARAM_LOSSLESS), * since the IDCT algorithm is not used with those images. Note also that @@ -1564,12 +1766,12 @@ DLLEXPORT int tj3SetScalingFactor(tjhandle handle, * @param croppingRegion #tjregion structure that specifies a subregion of the * JPEG image to decompress, or #TJUNCROPPED for no cropping. The * left boundary of the cropping region must be evenly divisible by the scaled - * MCU block width (#TJSCALED(#tjMCUWidth[subsamp], scalingFactor), - * where `subsamp` is the level of chrominance subsampling in the JPEG image - * (see #TJPARAM_SUBSAMP) and `scalingFactor` is the decompression scaling - * factor (see #tj3SetScalingFactor().) The cropping region should be - * specified relative to the scaled image dimensions. Unless `croppingRegion` - * is #TJUNCROPPED, the JPEG header must be read (see + * iMCU width-- #TJSCALED(#tjMCUWidth[subsamp], scalingFactor), where + * `subsamp` is the level of chrominance subsampling in the JPEG image (see + * #TJPARAM_SUBSAMP) and `scalingFactor` is the decompression scaling factor + * (see #tj3SetScalingFactor().) The cropping region should be specified + * relative to the scaled image dimensions. Unless `croppingRegion` is + * #TJUNCROPPED, the JPEG header must be read (see * #tj3DecompressHeader()) prior to calling this function. * * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr().) @@ -1644,43 +1846,6 @@ DLLEXPORT int tj3Decompress16(tjhandle handle, const unsigned char *jpegBuf, int pitch, int pixelFormat); -/** - * Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample unified - * planar YUV image. This function performs JPEG decompression but leaves out - * the color conversion step, so a planar YUV image is generated instead of a - * packed-pixel image. The @ref TJPARAM "parameters" that describe the JPEG - * image will be set when this function returns. - * - * @param handle handle to a TurboJPEG instance that has been initialized for - * decompression - * - * @param jpegBuf pointer to a byte buffer containing the JPEG image to - * decompress - * - * @param jpegSize size of the JPEG image (in bytes) - * - * @param dstBuf pointer to a buffer that will receive the unified planar YUV - * decompressed image. Use #tj3YUVBufSize() to determine the appropriate size - * for this buffer based on the scaled JPEG width and height (see #TJSCALED(), - * #TJPARAM_JPEGWIDTH, #TJPARAM_JPEGHEIGHT, and #tj3SetScalingFactor()), row - * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The - * Y, U (Cb), and V (Cr) image planes will be stored sequentially in the - * buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) - * - * @param align row alignment (in bytes) of the YUV image (must be a power of - * 2.) Setting this parameter to n will cause each row in each plane of the - * YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.) - * To generate images suitable for X Video, `align` should be set to 4. - * - * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() - * and #tj3GetErrorCode().) - */ -DLLEXPORT int tj3DecompressToYUV8(tjhandle handle, - const unsigned char *jpegBuf, - size_t jpegSize, - unsigned char *dstBuf, int align); - - /** * Decompress an 8-bit-per-sample JPEG image into separate 8-bit-per-sample Y, * U (Cb), and V (Cr) image planes. This function performs JPEG decompression @@ -1725,52 +1890,40 @@ DLLEXPORT int tj3DecompressToYUVPlanes8(tjhandle handle, /** - * Decode an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample - * packed-pixel RGB or grayscale image. This function performs color - * conversion (which is accelerated in the libjpeg-turbo implementation) but - * does not execute any of the other steps in the JPEG decompression process. + * Decompress an 8-bit-per-sample JPEG image into an 8-bit-per-sample unified + * planar YUV image. This function performs JPEG decompression but leaves out + * the color conversion step, so a planar YUV image is generated instead of a + * packed-pixel image. The @ref TJPARAM "parameters" that describe the JPEG + * image will be set when this function returns. * * @param handle handle to a TurboJPEG instance that has been initialized for * decompression * - * @param srcBuf pointer to a buffer containing a unified planar YUV source - * image to be decoded. The size of this buffer should match the value - * returned by #tj3YUVBufSize() for the given image width, height, row - * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The - * Y, U (Cb), and V (Cr) image planes should be stored sequentially in the - * source buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) - * - * @param align row alignment (in bytes) of the YUV source image (must be a - * power of 2.) Setting this parameter to n indicates that each row in each - * plane of the YUV source image is padded to the nearest multiple of n bytes - * (1 = unpadded.) - * - * @param dstBuf pointer to a buffer that will receive the packed-pixel decoded - * image. This buffer should normally be `pitch * height` bytes in size. - * However, you can also use this parameter to decode into a specific region of - * a larger buffer. - * - * @param width width (in pixels) of the source and destination images + * @param jpegBuf pointer to a byte buffer containing the JPEG image to + * decompress * - * @param pitch bytes per row in the destination image. Normally this should - * be set to width * #tjPixelSize[pixelFormat], if the destination - * image should be unpadded. (Setting this parameter to 0 is the equivalent of - * setting it to width * #tjPixelSize[pixelFormat].) However, you can - * also use this parameter to specify the row alignment/padding of the - * destination image, to skip rows, or to decode into a specific region of a - * larger buffer. + * @param jpegSize size of the JPEG image (in bytes) * - * @param height height (in pixels) of the source and destination images + * @param dstBuf pointer to a buffer that will receive the unified planar YUV + * decompressed image. Use #tj3YUVBufSize() to determine the appropriate size + * for this buffer based on the scaled JPEG width and height (see #TJSCALED(), + * #TJPARAM_JPEGWIDTH, #TJPARAM_JPEGHEIGHT, and #tj3SetScalingFactor()), row + * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The + * Y, U (Cb), and V (Cr) image planes will be stored sequentially in the + * buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) * - * @param pixelFormat pixel format of the destination image (see @ref TJPF - * "Pixel formats".) + * @param align row alignment (in bytes) of the YUV image (must be a power of + * 2.) Setting this parameter to n will cause each row in each plane of the + * YUV image to be padded to the nearest multiple of n bytes (1 = unpadded.) + * To generate images suitable for X Video, `align` should be set to 4. * * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() * and #tj3GetErrorCode().) */ -DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf, - int align, unsigned char *dstBuf, int width, - int pitch, int height, int pixelFormat); +DLLEXPORT int tj3DecompressToYUV8(tjhandle handle, + const unsigned char *jpegBuf, + size_t jpegSize, + unsigned char *dstBuf, int align); /** @@ -1829,6 +1982,55 @@ DLLEXPORT int tj3DecodeYUVPlanes8(tjhandle handle, int pixelFormat); +/** + * Decode an 8-bit-per-sample unified planar YUV image into an 8-bit-per-sample + * packed-pixel RGB or grayscale image. This function performs color + * conversion (which is accelerated in the libjpeg-turbo implementation) but + * does not execute any of the other steps in the JPEG decompression process. + * + * @param handle handle to a TurboJPEG instance that has been initialized for + * decompression + * + * @param srcBuf pointer to a buffer containing a unified planar YUV source + * image to be decoded. The size of this buffer should match the value + * returned by #tj3YUVBufSize() for the given image width, height, row + * alignment, and level of chrominance subsampling (see #TJPARAM_SUBSAMP.) The + * Y, U (Cb), and V (Cr) image planes should be stored sequentially in the + * source buffer. (Refer to @ref YUVnotes "YUV Image Format Notes".) + * + * @param align row alignment (in bytes) of the YUV source image (must be a + * power of 2.) Setting this parameter to n indicates that each row in each + * plane of the YUV source image is padded to the nearest multiple of n bytes + * (1 = unpadded.) + * + * @param dstBuf pointer to a buffer that will receive the packed-pixel decoded + * image. This buffer should normally be `pitch * height` bytes in size. + * However, you can also use this parameter to decode into a specific region of + * a larger buffer. + * + * @param width width (in pixels) of the source and destination images + * + * @param pitch bytes per row in the destination image. Normally this should + * be set to width * #tjPixelSize[pixelFormat], if the destination + * image should be unpadded. (Setting this parameter to 0 is the equivalent of + * setting it to width * #tjPixelSize[pixelFormat].) However, you can + * also use this parameter to specify the row alignment/padding of the + * destination image, to skip rows, or to decode into a specific region of a + * larger buffer. + * + * @param height height (in pixels) of the source and destination images + * + * @param pixelFormat pixel format of the destination image (see @ref TJPF + * "Pixel formats".) + * + * @return 0 if successful, or -1 if an error occurred (see #tj3GetErrorStr() + * and #tj3GetErrorCode().) + */ +DLLEXPORT int tj3DecodeYUV8(tjhandle handle, const unsigned char *srcBuf, + int align, unsigned char *dstBuf, int width, + int pitch, int height, int pixelFormat); + + /** * Losslessly transform a JPEG image into another JPEG image. Lossless * transforms work by moving the raw DCT coefficients from one JPEG image @@ -1863,13 +2065,15 @@ DLLEXPORT int tj3DecodeYUVPlanes8(tjhandle handle, * you, or * -# pre-allocate the buffer to a "worst case" size determined by calling * #tj3JPEGBufSize() with the transformed or cropped width and height and the - * level of subsampling used in the source image. Under normal circumstances, - * this should ensure that the buffer never has to be re-allocated. (Setting - * #TJPARAM_NOREALLOC guarantees that it won't be.) Note, however, that there - * are some rare cases (such as transforming images with a large amount of - * embedded EXIF or ICC profile data) in which the transformed JPEG image will - * be larger than the worst-case size, and #TJPARAM_NOREALLOC cannot be used in - * those cases. + * level of subsampling used in the destination image (taking into account + * grayscale conversion and transposition of the width and height.) Under + * normal circumstances, this should ensure that the buffer never has to be + * re-allocated. (Setting #TJPARAM_NOREALLOC guarantees that it won't be.) + * Note, however, that there are some rare cases (such as transforming images + * with a large amount of embedded Exif or ICC profile data) in which the + * transformed JPEG image will be larger than the worst-case size, and + * #TJPARAM_NOREALLOC cannot be used in those cases unless the embedded data is + * discarded using #TJXOPT_COPYNONE. * . * If you choose option 1, then `dstSizes[i]` should be set to the size of your * pre-allocated buffer. In any case, unless you have set #TJPARAM_NOREALLOC, @@ -1894,31 +2098,6 @@ DLLEXPORT int tj3Transform(tjhandle handle, const unsigned char *jpegBuf, size_t *dstSizes, const tjtransform *transforms); -/** - * Destroy a TurboJPEG instance. - * - * @param handle handle to a TurboJPEG instance. If the handle is NULL, then - * this function has no effect. - */ -DLLEXPORT void tj3Destroy(tjhandle handle); - - -/** - * Allocate a byte buffer for use with TurboJPEG. You should always use this - * function to allocate the JPEG destination buffer(s) for the compression and - * transform functions unless you are disabling automatic buffer (re)allocation - * (by setting #TJPARAM_NOREALLOC.) - * - * @param bytes the number of bytes to allocate - * - * @return a pointer to a newly-allocated buffer with the specified number of - * bytes. - * - * @see tj3Free() - */ -DLLEXPORT void *tj3Alloc(size_t bytes); - - /** * Load an 8-bit-per-sample packed-pixel image from disk into memory. * @@ -1943,7 +2122,7 @@ DLLEXPORT void *tj3Alloc(size_t bytes); * * @param pixelFormat pointer to an integer variable that specifies or will * receive the pixel format of the packed-pixel buffer. The behavior of this - * function will vary depending on the value of `*pixelFormat` passed to the + * function varies depending on the value of `*pixelFormat` passed to the * function: * - @ref TJPF_UNKNOWN : The packed-pixel buffer returned by this function will * use the most optimal pixel format for the file type, and `*pixelFormat` will @@ -2042,45 +2221,6 @@ DLLEXPORT int tj3SaveImage16(tjhandle handle, const char *filename, int pitch, int height, int pixelFormat); -/** - * Free a byte buffer previously allocated by TurboJPEG. You should always use - * this function to free JPEG destination buffer(s) that were automatically - * (re)allocated by the compression and transform functions or that were - * manually allocated using #tj3Alloc(). - * - * @param buffer address of the buffer to free. If the address is NULL, then - * this function has no effect. - * - * @see tj3Alloc() - */ -DLLEXPORT void tj3Free(void *buffer); - - -/** - * Returns a descriptive error message explaining why the last command failed. - * - * @param handle handle to a TurboJPEG instance, or NULL if the error was - * generated by a global function (but note that retrieving the error message - * for a global function is thread-safe only on platforms that support - * thread-local storage.) - * - * @return a descriptive error message explaining why the last command failed. - */ -DLLEXPORT char *tj3GetErrorStr(tjhandle handle); - - -/** - * Returns a code indicating the severity of the last error. See - * @ref TJERR "Error codes". - * - * @param handle handle to a TurboJPEG instance - * - * @return a code indicating the severity of the last error. See - * @ref TJERR "Error codes". - */ -DLLEXPORT int tj3GetErrorCode(tjhandle handle); - - /* Backward compatibility functions and macros (nothing to see here) */ /* TurboJPEG 1.0+ */ diff --git a/usage.txt b/usage.txt index c1bba4a..1bcea5f 100644 --- a/usage.txt +++ b/usage.txt @@ -1,5 +1,8 @@ -NOTE: This file was modified by The libjpeg-turbo Project to include only -information relevant to libjpeg-turbo and to wordsmith certain sections. +This file was part of the Independent JPEG Group's software: +Copyright (C) 1991-2020, Thomas G. Lane, Guido Vollbeding. +libjpeg-turbo Modifications: +Copyright (C) 2010, 2012, 2014-2017, 2020-2024, D. R. Commander. +For conditions of distribution and use, see the accompanying README.ijg file. USAGE instructions for the Independent JPEG Group's JPEG software ================================================================= @@ -50,9 +53,10 @@ or 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, and Targa. cjpeg recognizes the -input image format automatically, with the exception of some Targa files. You -have to tell djpeg which format to generate. +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. @@ -73,12 +77,12 @@ The basic command line switches for cjpeg are: (See below for more info.) -grayscale Create monochrome JPEG file from color input. By - saying -grayscale, you'll get a smaller JPEG file that - takes less time to process. + specifying -grayscale, you'll get a smaller JPEG file + that takes less time to process. - -rgb Create RGB JPEG file. - Using this switch suppresses the conversion from RGB - colorspace input to the default YCbCr JPEG colorspace. + -rgb Create RGB JPEG file. Using this switch suppresses the + conversion from RGB colorspace input to the default + YCbCr JPEG colorspace. -optimize Perform optimization of entropy encoding parameters. Without this, default encoding parameters are used. @@ -87,13 +91,15 @@ The basic command line switches for cjpeg are: memory. Image quality and speed of decompression are unaffected by -optimize. - -progressive Create progressive JPEG file (see below). + -progressive Create progressive JPEG file (see below). Implies + -optimize unless -arithmetic is also specified. - -targa Input file is Targa format. Targa files that contain - an "identification" field will not be automatically - recognized by cjpeg; for such files you must specify - -targa to make cjpeg treat the input as Targa format. - For most Targa files, you won't need this switch. + -targa Input file is Targa format [legacy feature]. Targa + files that contain an "identification" field will not + be automatically recognized by cjpeg. For such files, + you must specify -targa to make cjpeg treat the input + as Targa format. For most Targa files, you won't need + this switch. The -quality switch lets you trade off compressed file size against quality of the reconstructed image: the higher the quality setting, the larger the JPEG @@ -162,10 +168,22 @@ Switches for advanced users: -precision N Create JPEG file with N-bit data precision. N is 8, 12, or 16; default is 8. If N is 16, then - -lossless must also be specified. CAUTION: 12-bit and - 16-bit JPEG is not yet widely implemented, so many - decoders will be unable to view a 12-bit or 16-bit JPEG - file at all. + -lossless must also be specified. Note that only the + PBMPLUS input file format supports data precisions other + than 8. (For historical reasons, cjpeg allows GIF input + files to be converted into 12-bit-per-sample JPEG files, + but this is not a useful conversion.) Note also that + PBMPLUS input files are silently scaled to the target + data precision, even if it is lower than the precision + of the input file. Passing an argument of -verbose to + cjpeg will cause it to print information about the + precision of the input file. CAUTION: 12-bit and 16-bit + data precision is not yet widely implemented, so many + decoders will be unable to handle a 12-bit-per-sample or + 16-bit-per-sample JPEG file at all. + + "-precision 12" implies -optimize unless -arithmetic is + also specified. -lossless psv[,Pt] Create a lossless JPEG file using the specified predictor selection value (1 - 7) and optional point @@ -177,7 +195,11 @@ Switches for advanced users: number of bits, which is effectively a form of lossy color quantization.) CAUTION: lossless JPEG is not yet widely implemented, so many decoders will be unable to - view a lossless JPEG file at all. Note that the + handle a lossless JPEG file at all. In most cases, + compressing and decompressing a lossless JPEG file is + considerably slower than compressing and decompressing + a lossy JPEG file, and lossless JPEG files are much + larger than lossy JPEG files. Also note that the following features will be unavailable when compressing or decompressing a lossless JPEG file: * Quality/quantization table selection @@ -193,9 +215,9 @@ Switches for advanced users: Any switches used to enable or configure those features will be ignored. - -arithmetic Use arithmetic coding. CAUTION: arithmetic coded JPEG + -arithmetic Use arithmetic coding. CAUTION: arithmetic-coded JPEG is not yet widely implemented, so many decoders will - be unable to view an arithmetic coded JPEG file at + be unable to handle an arithmetic-coded JPEG file at all. -dct int Use accurate integer DCT method (default). @@ -236,10 +258,25 @@ Switches for advanced users: behavior, whereas the integer methods should give the same results on all machines. - -restart N Emit a JPEG restart marker every N MCU rows, or every - N MCU blocks (samples in lossless mode) if "B" is - attached to the number. -restart 0 (the default) means - no restart markers. + -icc FILE Embed ICC color management profile contained in the + specified file. + + -restart N Emit a JPEG restart marker every N MCU rows, or every N + MCUs if "B" is attached to the number. + + In typical JPEG images, an MCU (Minimum Coded Unit) is + the minimum set of interleaved "data units" (8x8 DCT + blocks if the image is lossy or samples if the image is + lossless) necessary to represent at least one data unit + per component. (For example, an MCU in an interleaved + lossy JPEG image that uses 4:2:2 subsampling consists + of two luminance blocks followed by one block for each + chrominance component.) In single-component or + non-interleaved JPEG images, an MCU is the same as a + data unit. An MCU row is a row of MCUs spanning the + entire width of the image. + + -restart 0 (the default) means no restart markers. -smooth N Smooth the input image to eliminate dithering noise. N, ranging from 1 to 100, indicates the strength of @@ -251,9 +288,23 @@ Switches for advanced users: For example, -max 4m selects 4000000 bytes. If more space is needed, an error will occur. - -verbose Enable debug printout. More -v's give more printout. + -memdst Compress to memory instead of a file. This feature was + implemented mainly as a way of testing the in-memory + destination manager (jpeg_mem_dest()), but it is also + useful for benchmarking, since it reduces the I/O + overhead. + + -report Report compression progress. + + -strict Treat all warnings as fatal. Enabling this option will + cause the compressor to abort if an LZW-compressed GIF + input image contains incomplete or corrupt image data. + + -verbose Enable debug printout. More -v's give more output. or -debug Also, version information is printed at startup. + -version Print version information and exit. + The -restart option inserts extra markers that allow a JPEG decoder to resynchronize after a transmission error. Without restart markers, any damage to a compressed file will usually ruin the image from the point of the error @@ -296,64 +347,78 @@ DJPEG DETAILS The basic command line switches for djpeg are: - -colors N Reduce image to at most N colors. This reduces the - or -quantize N number of colors used in the output image, so that it - can be displayed on a colormapped display or stored in - a colormapped file format. For example, if you have - an 8-bit display, you'd need to reduce to 256 or fewer - colors. (-colors is the recommended name, -quantize - is provided only for backwards compatibility.) - - -fast Select recommended processing options for fast, low - quality output. (The default options are chosen for - highest quality output.) Currently, this is equivalent - to "-dct fast -nosmooth -onepass -dither ordered". - - -grayscale Force grayscale output even if JPEG file is color. - Useful for viewing on monochrome displays; also, - djpeg runs noticeably faster in this mode. - - -rgb Force RGB output even if JPEG file is grayscale. - - -scale M/N Scale the output image by a factor M/N. Currently - the scale factor must be M/8, where M is an integer - between 1 and 16 inclusive, or any reduced fraction - thereof (such as 1/2, 3/4, etc. Scaling is handy if - the image is larger than your screen; also, djpeg runs - much faster when scaling down the output. + -colors N Reduce image to at most N colors [legacy feature]. + or -quantize N This reduces the number of colors used in the output + image so that it can be stored in a colormapped file + format. This feature cannot be used when decompressing + lossless JPEG images. (-colors is the recommended + name. -quantize is provided only for backward + compatibility.) + + -fast Select recommended processing options for low-quality + output [legacy feature]. (The default options are + chosen for highest-quality output.) Currently, this is + equivalent to "-dct fast -nosmooth -onepass -dither + ordered". On modern CPUs, these settings have little + or no performance benefit and are retained solely for + backward compatibility. + + -grayscale Force grayscale output even if JPEG file is full-color. + This feature cannot be used when decompressing + full-color lossless JPEG images. + + -rgb Force RGB output even if JPEG file is grayscale. This + feature cannot be used when decompressing grayscale + lossless JPEG images. + + -scale M/N Scale the output image by a factor M/N. Currently the + scale factor must be M/8, where M is an integer between + 1 and 16 inclusive, or any reduced fraction thereof + (such as 1/2, 3/4, etc.) Scaling is handy if the image + is larger than your screen. This feature cannot be + used when decompressing lossless JPEG images. -bmp Select BMP output format (Windows flavor). 8-bit colormapped format is emitted if -colors or -grayscale is specified, or if the JPEG file is grayscale; - otherwise, 24-bit full-color format is emitted. - - -gif Select GIF output format (LZW-compressed). Since GIF - does not support more than 256 colors, -colors 256 is - assumed (unless you specify a smaller number of - colors). If you specify -fast, the default number of - colors is 216. - - -gif0 Select GIF output format (uncompressed). Since GIF - does not support more than 256 colors, -colors 256 is - assumed (unless you specify a smaller number of - colors). If you specify -fast, the default number of - colors is 216. - - -os2 Select BMP output format (OS/2 1.x flavor). 8-bit - colormapped format is emitted if -colors or -grayscale - is specified, or if the JPEG file is grayscale; - otherwise, 24-bit full-color format is emitted. + otherwise, 24-bit full-color format is emitted. This + format can only be used when decompressing + 8-bit-per-sample JPEG images. + + -gif Select GIF output format (LZW-compressed) [legacy + feature]. Since GIF does not support more than 256 + colors, -colors 256 is assumed (unless you specify a + smaller number of colors). If you specify -fast, the + default number of colors is 216. This format can only + be used when decompressing 8-bit-per-sample or + 12-bit-per-sample lossy JPEG images. + + -gif0 Select GIF output format (uncompressed) [legacy + feature]. Since GIF does not support more than 256 + colors, -colors 256 is assumed (unless you specify a + smaller number of colors). If you specify -fast, the + default number of colors is 216. This format can only + be used when decompressing 8-bit-per-sample or + 12-bit-per-sample lossy JPEG images. + + -os2 Select BMP output format (OS/2 1.x flavor) [legacy + feature]. 8-bit colormapped format is emitted if + -colors or -grayscale 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. -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 is emitted. + grayscale or if -grayscale is specified; otherwise PPM + is emitted. - -targa Select Targa output format. Grayscale format is - emitted if the JPEG file is grayscale or if + -targa Select Targa output format [legacy feature]. Grayscale + format is emitted if the JPEG file is grayscale or if -grayscale is specified; otherwise, colormapped format is emitted if -colors is specified; otherwise, 24-bit - full-color format is emitted. + full-color format is emitted. This format can only be + used when decompressing 8-bit-per-sample JPEG images. Switches for advanced users: @@ -397,32 +462,39 @@ Switches for advanced users: behavior, whereas the integer methods should give the same results on all machines. - -dither fs Use Floyd-Steinberg dithering in color quantization. - -dither ordered Use ordered dithering in color quantization. - -dither none Do not use dithering in color quantization. - By default, Floyd-Steinberg dithering is applied when - quantizing colors; this is slow but usually produces - the best results. Ordered dither is a compromise - between speed and quality; no dithering is fast but - usually looks awful. Note that these switches have - no effect unless color quantization is being done. - Ordered dither is only available in -onepass mode. - - -map FILE Quantize to the colors used in the specified image - file. This is useful for producing multiple files - with identical color maps, or for forcing a predefined - set of colors to be used. The FILE must be a GIF - or PPM file. This option overrides -colors and - -onepass. + -dither fs Use Floyd-Steinberg dithering when quantizing colors + [legacy feature]. + -dither ordered Use ordered dithering when quantizing colors [legacy + feature]. + -dither none Do not use dithering when quantizing colors [legacy + feature]. By default, Floyd-Steinberg dithering is + applied when quantizing colors. This is slower but + usually produces the best results. Ordered dithering + is a compromise between speed and quality. No + dithering is faster but usually looks awful. Note that + these switches have no effect unless color quantization + is being done. Ordered dithering is only available in + -onepass mode. + + -icc FILE Extract ICC color management profile to the specified + file. + + -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 + forcing a predefined set of colors to be used. The + FILE must be a GIF or PPM file. This option overrides + -colors and -onepass. -nosmooth Use a faster, lower-quality upsampling routine. - -onepass Use one-pass instead of two-pass color quantization. - The one-pass method is faster and needs less memory, - but it produces a lower-quality image. -onepass is - ignored unless you also say -colors N. Also, - the one-pass method is always used for grayscale - output (the two-pass method is no improvement then). + -onepass Use one-pass instead of two-pass color quantization + [legacy feature]. The one-pass method needs less + memory, but it produces a lower-quality image. + -onepass is ignored unless you also specify -colors N. + Also, the one-pass method is always used for grayscale + output. (The two-pass method has no improvement in + that case.) -maxmemory N Set limit for amount of memory to use in processing large images. Value is in thousands of bytes, or @@ -430,18 +502,62 @@ Switches for advanced users: For example, -max 4m selects 4000000 bytes. If more space is needed, an error will occur. - -verbose Enable debug printout. More -v's give more printout. + -maxscans N Abort if the JPEG image contains more than N scans. + This feature demonstrates a method by which + applications can guard against denial-of-service + attacks instigated by specially-crafted malformed JPEG + images containing numerous scans with missing image + data or image data consisting only of "EOB runs" (a + feature of progressive JPEG images that allows + potentially hundreds of thousands of adjoining + zero-value pixels to be represented using only a few + bytes.) Attempting to decompress such malformed JPEG + images can cause excessive CPU activity, since the + decompressor must fully process each scan (even if the + scan is corrupt) before it can proceed to the next + scan. + + -memsrc Load input file into memory before decompressing. This + feature was implemented mainly as a way of testing the + in-memory source manager (jpeg_mem_src().) + + -report Report decompression progress. + + -skip Y0,Y1 Decompress all rows of the JPEG image except those + between Y0 and Y1 (inclusive.) Note that if + decompression scaling is being used, then Y0 and Y1 are + relative to the scaled image dimensions. + + -crop WxH+X+Y 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. + + -strict Treat all warnings as fatal. This feature also + demonstrates a method by which applications can guard + against attacks instigated by specially-crafted + malformed JPEG images. Enabling this option will cause + the decompressor to abort if the JPEG image contains + incomplete or corrupt image data. + + -verbose Enable debug printout. More -v's give more output. or -debug Also, version information is printed at startup. + -version Print version information and exit. + HINTS FOR CJPEG Color GIF files are not the ideal input for JPEG; JPEG is really intended for -compressing full-color (24-bit) images. In particular, don't try to convert -cartoons, line drawings, and other images that have only a few distinct -colors. GIF works great on these, JPEG does not. If you want to convert a -GIF to JPEG, you should experiment with cjpeg's -quality and -smooth options -to get a satisfactory conversion. -smooth 10 or so is often helpful. +compressing full-color (24-bit through 48-bit) images. In particular, don't +try to convert cartoons, line drawings, and other images that have only a few +distinct colors. GIF works great on these; JPEG does not. If you want to +convert a GIF to JPEG, you should experiment with cjpeg's -quality and -smooth +options to get a satisfactory conversion. -smooth 10 or so is often helpful. Avoid running an image through a series of JPEG compression/decompression cycles. Image quality loss will accumulate; after ten or so cycles the image @@ -456,20 +572,6 @@ is often a lot more than it is on larger files. (At present, -optimize mode is always selected when generating progressive JPEG files.) -HINTS FOR DJPEG - -To get a quick preview of an image, use the -grayscale and/or -scale switches. -"-grayscale -scale 1/8" is the fastest case. - -Several options are available that trade off image quality to gain speed. -"-fast" turns on the recommended settings. - -"-dct fast" and/or "-nosmooth" gain speed at a small sacrifice in quality. -When producing a color-quantized image, "-onepass -dither ordered" is fast but -much lower quality than the default behavior. "-dither none" may give -acceptable results in two-pass mode, but is seldom tolerable in one-pass mode. - - HINTS FOR BOTH PROGRAMS If the memory needed by cjpeg or djpeg exceeds the limit specified by @@ -485,12 +587,12 @@ explicit -maxmemory switch. JPEGTRAN -jpegtran performs various useful transformations of JPEG files. -It can translate the coded representation from one variant of JPEG to another, -for example from baseline JPEG to progressive JPEG or vice versa. It can also -perform some rearrangements of the image data, for example turning an image -from landscape to portrait format by rotation. For EXIF files and JPEG files -containing Exif data, you may prefer to use exiftran instead. +jpegtran performs various useful transformations of lossy (DCT-based) JPEG +files. It can translate the coded representation from one variant of JPEG to +another, for example from baseline JPEG to progressive JPEG or vice versa. It +can also perform some rearrangements of the image data, for example turning an +image from landscape to portrait format by rotation. For EXIF files and JPEG +files containing Exif data, you may prefer to use exiftran instead. jpegtran works by rearranging the compressed data (DCT coefficients), without ever fully decoding the image. Therefore, its transformations are lossless: @@ -514,7 +616,7 @@ jpegtran accepts a subset of the switches recognized by cjpeg: -progressive Create progressive JPEG file. -arithmetic Use arithmetic coding. -restart N Emit a JPEG restart marker every N MCU rows, or every - N MCU blocks if "B" is attached to the number. + N MCUs if "B" is attached to the number. -scans file Use the scan script given in the specified text file. See the previous discussion of cjpeg for more details about these switches. If you specify none of these switches, you get a plain baseline-JPEG output @@ -646,10 +748,15 @@ The default behavior is -copy comments. (Note: in IJG releases v6 and v6a, jpegtran always did the equivalent of -copy none.) Additional switches recognized by jpegtran are: - -outfile filename + -icc FILE -maxmemory N + -maxscans N + -outfile filename + -report + -strict -verbose -debug + -version These work the same as in cjpeg or djpeg.