diff --git a/.gitattributes b/.gitattributes
index bcae119cb..d702c28be 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12,10 +12,12 @@
*.jxl filter=lfs diff=lfs merge=lfs -text
*.pcx filter=lfs diff=lfs merge=lfs -text
*.pnm filter=lfs diff=lfs merge=lfs -text
+*.pgm filter=lfs diff=lfs merge=lfs -text
*.qoi filter=lfs diff=lfs merge=lfs -text
*.tga filter=lfs diff=lfs merge=lfs -text
*.webp filter=lfs diff=lfs merge=lfs -text
*.tif filter=lfs diff=lfs merge=lfs -text
+*.jbg filter=lfs diff=lfs merge=lfs -text
#
# Other Binary
@@ -67,3 +69,4 @@
*.lz filter=lfs diff=lfs merge=lfs -text
*.lzma filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
+*.tar filter=lfs diff=lfs merge=lfs -text
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 000000000..a7142660d
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+singe2
\ No newline at end of file
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 000000000..a55e7a179
--- /dev/null
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6e885d2c2..b60430f8b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,205 +18,225 @@
#
-cmake_minimum_required(VERSION 3.26)
+cmake_minimum_required(VERSION 3.22)
set(CMAKE_CXX_STANDARD 17)
project(singe2)
+if(NOT DEFINED KANGAROO_OS)
+ set(KANGAROO_OS linux)
+endif()
+if(NOT DEFINED KANGAROO_ARCH)
+ set(KANGAROO_ARCH x86_64)
+endif()
+
+set(BUILD_DIR ${CMAKE_SOURCE_DIR}/build/${KANGAROO_OS}/${KANGAROO_ARCH})
+
+
set(SINGE_SOURCE
- src/main.h
- src/singe.c
- src/singe.h
- src/util.h
- src/embedded.h
- src/frameFile.h
- src/main.c
- src/common.h
- src/videoPlayer.c
- src/stddclmr.h
- src/frameFile.c
- src/videoPlayer.h
- src/util.c
- src/embedded.c
+ src/main.h
+ src/singe.c
+ src/singe.h
+ src/util.h
+ src/embedded.h
+ src/frameFile.h
+ src/main.c
+ src/common.h
+ src/videoPlayer.c
+ src/stddclmr.h
+ src/frameFile.c
+ src/videoPlayer.h
+ src/util.c
+ src/embedded.c
)
set(ARG_PARSER_SOURCE
- thirdparty/arg_parser/carg_parser.c
- thirdparty/arg_parser/carg_parser.h
+ thirdparty/arg_parser/carg_parser.c
+ thirdparty/arg_parser/carg_parser.h
+)
+
+
+set(JBIG_SOURCE
+ thirdparty/jbigkit/libjbig/jbig.c
+ thirdparty/jbigkit/libjbig/jbig.h
+ thirdparty/jbigkit/libjbig/jbig_ar.c
+ thirdparty/jbigkit/libjbig/jbig_ar.h
)
set(LUA_SOURCE
- thirdparty/lua/src/lmem.h
- thirdparty/lua/src/ltm.h
- thirdparty/lua/src/lutf8lib.c
- thirdparty/lua/src/ldo.h
- thirdparty/lua/src/ldump.c
- thirdparty/lua/src/lstring.h
- thirdparty/lua/src/lparser.h
- thirdparty/lua/src/lcorolib.c
- thirdparty/lua/src/loslib.c
- thirdparty/lua/src/lparser.c
- thirdparty/lua/src/ltablib.c
- thirdparty/lua/src/ltable.c
- thirdparty/lua/src/ljumptab.h
- thirdparty/lua/src/luaconf.h
- thirdparty/lua/src/lstate.c
- thirdparty/lua/src/lobject.h
- thirdparty/lua/src/lstate.h
- thirdparty/lua/src/ldo.c
- thirdparty/lua/src/lfunc.c
- thirdparty/lua/src/lmathlib.c
- thirdparty/lua/src/lua.h
- thirdparty/lua/src/lauxlib.h
- thirdparty/lua/src/ltm.c
- thirdparty/lua/src/lstrlib.c
- thirdparty/lua/src/lapi.h
- thirdparty/lua/src/lopcodes.c
- thirdparty/lua/src/lvm.h
- thirdparty/lua/src/linit.c
- thirdparty/lua/src/lobject.c
- thirdparty/lua/src/ldebug.c
- thirdparty/lua/src/lctype.c
- thirdparty/lua/src/lgc.c
- thirdparty/lua/src/lzio.h
- thirdparty/lua/src/lgc.h
- thirdparty/lua/src/lctype.h
- thirdparty/lua/src/lopcodes.h
- thirdparty/lua/src/llimits.h
- thirdparty/lua/src/lprefix.h
- thirdparty/lua/src/llex.h
- thirdparty/lua/src/lundump.c
- thirdparty/lua/src/lbaselib.c
- thirdparty/lua/src/loadlib.c
- thirdparty/lua/src/ldblib.c
- thirdparty/lua/src/ldebug.h
- thirdparty/lua/src/lundump.h
- thirdparty/lua/src/lopnames.h
- thirdparty/lua/src/ltable.h
- thirdparty/lua/src/lmem.c
- thirdparty/lua/src/lcode.h
- thirdparty/lua/src/lua.hpp
- thirdparty/lua/src/lauxlib.c
- thirdparty/lua/src/liolib.c
- thirdparty/lua/src/lapi.c
- thirdparty/lua/src/lcode.c
- thirdparty/lua/src/llex.c
- thirdparty/lua/src/lstring.c
- thirdparty/lua/src/lvm.c
- thirdparty/lua/src/lualib.h
- thirdparty/lua/src/lfunc.h
- thirdparty/lua/src/lzio.c
+ thirdparty/lua/src/lmem.h
+ thirdparty/lua/src/ltm.h
+ thirdparty/lua/src/lutf8lib.c
+ thirdparty/lua/src/ldo.h
+ thirdparty/lua/src/ldump.c
+ thirdparty/lua/src/lstring.h
+ thirdparty/lua/src/lparser.h
+ thirdparty/lua/src/lcorolib.c
+ thirdparty/lua/src/loslib.c
+ thirdparty/lua/src/lparser.c
+ thirdparty/lua/src/ltablib.c
+ thirdparty/lua/src/ltable.c
+ thirdparty/lua/src/ljumptab.h
+ thirdparty/lua/src/luaconf.h
+ thirdparty/lua/src/lstate.c
+ thirdparty/lua/src/lobject.h
+ thirdparty/lua/src/lstate.h
+ thirdparty/lua/src/ldo.c
+ thirdparty/lua/src/lfunc.c
+ thirdparty/lua/src/lmathlib.c
+ thirdparty/lua/src/lua.h
+ thirdparty/lua/src/lauxlib.h
+ thirdparty/lua/src/ltm.c
+ thirdparty/lua/src/lstrlib.c
+ thirdparty/lua/src/lapi.h
+ thirdparty/lua/src/lopcodes.c
+ thirdparty/lua/src/lvm.h
+ thirdparty/lua/src/linit.c
+ thirdparty/lua/src/lobject.c
+ thirdparty/lua/src/ldebug.c
+ thirdparty/lua/src/lctype.c
+ thirdparty/lua/src/lgc.c
+ thirdparty/lua/src/lzio.h
+ thirdparty/lua/src/lgc.h
+ thirdparty/lua/src/lctype.h
+ thirdparty/lua/src/lopcodes.h
+ thirdparty/lua/src/llimits.h
+ thirdparty/lua/src/lprefix.h
+ thirdparty/lua/src/llex.h
+ thirdparty/lua/src/lundump.c
+ thirdparty/lua/src/lbaselib.c
+ thirdparty/lua/src/loadlib.c
+ thirdparty/lua/src/ldblib.c
+ thirdparty/lua/src/ldebug.h
+ thirdparty/lua/src/lundump.h
+ thirdparty/lua/src/lopnames.h
+ thirdparty/lua/src/ltable.h
+ thirdparty/lua/src/lmem.c
+ thirdparty/lua/src/lcode.h
+ thirdparty/lua/src/lua.hpp
+ thirdparty/lua/src/lauxlib.c
+ thirdparty/lua/src/liolib.c
+ thirdparty/lua/src/lapi.c
+ thirdparty/lua/src/lcode.c
+ thirdparty/lua/src/llex.c
+ thirdparty/lua/src/lstring.c
+ thirdparty/lua/src/lvm.c
+ thirdparty/lua/src/lualib.h
+ thirdparty/lua/src/lfunc.h
+ thirdparty/lua/src/lzio.c
)
set(LUA_FILESYSTEM_SOURCE
- thirdparty/luafilesystem/src/lfs.c
- thirdparty/luafilesystem/src/lfs.h
+ thirdparty/luafilesystem/src/lfs.c
+ thirdparty/luafilesystem/src/lfs.h
)
set(LUA_SOCKET_SOURCE
- thirdparty/luasocket/src/udp.h
- thirdparty/luasocket/src/unix.c
- thirdparty/luasocket/src/options.c
- thirdparty/luasocket/src/socket.h
- thirdparty/luasocket/src/except.c
- thirdparty/luasocket/src/compat.c
- thirdparty/luasocket/src/inet.c
- thirdparty/luasocket/src/options.h
- thirdparty/luasocket/src/tcp.h
- thirdparty/luasocket/src/luasocket.c
- thirdparty/luasocket/src/tcp.c
- thirdparty/luasocket/src/compat.h
- thirdparty/luasocket/src/timeout.h
- thirdparty/luasocket/src/udp.c
- thirdparty/luasocket/src/inet.h
- thirdparty/luasocket/src/timeout.c
- thirdparty/luasocket/src/buffer.h
- thirdparty/luasocket/src/io.h
- thirdparty/luasocket/src/unixdgram.h
- thirdparty/luasocket/src/unixdgram.c
- thirdparty/luasocket/src/unix.h
- thirdparty/luasocket/src/unixstream.c
- thirdparty/luasocket/src/io.c
- thirdparty/luasocket/src/select.c
- thirdparty/luasocket/src/except.h
- thirdparty/luasocket/src/luasocket.h
- thirdparty/luasocket/src/auxiliar.c
- thirdparty/luasocket/src/mime.c
- thirdparty/luasocket/src/auxiliar.h
- thirdparty/luasocket/src/buffer.c
- thirdparty/luasocket/src/mime.h
- thirdparty/luasocket/src/serial.c
- thirdparty/luasocket/src/unixstream.h
- thirdparty/luasocket/src/select.h
- thirdparty/luasocket/src/pierror.h
+ thirdparty/luasocket/src/luasocket.h
+ thirdparty/luasocket/src/luasocket.c
+ thirdparty/luasocket/src/timeout.h
+ thirdparty/luasocket/src/timeout.c
+ thirdparty/luasocket/src/buffer.h
+ thirdparty/luasocket/src/buffer.c
+ thirdparty/luasocket/src/io.h
+ thirdparty/luasocket/src/io.c
+ thirdparty/luasocket/src/auxiliar.h
+ thirdparty/luasocket/src/auxiliar.c
+ thirdparty/luasocket/src/compat.h
+ thirdparty/luasocket/src/compat.c
+ thirdparty/luasocket/src/options.h
+ thirdparty/luasocket/src/options.c
+ thirdparty/luasocket/src/inet.h
+ thirdparty/luasocket/src/inet.c
+ thirdparty/luasocket/src/except.h
+ thirdparty/luasocket/src/except.c
+ thirdparty/luasocket/src/select.h
+ thirdparty/luasocket/src/select.c
+ thirdparty/luasocket/src/tcp.h
+ thirdparty/luasocket/src/tcp.c
+ thirdparty/luasocket/src/udp.h
+ thirdparty/luasocket/src/udp.c
+ thirdparty/luasocket/src/mime.h
+ thirdparty/luasocket/src/mime.c
+ thirdparty/luasocket/src/socket.h
+ thirdparty/luasocket/src/pierror.h
)
if(WIN32)
- set(LUA_SOCKET_SOURCE
- ${LUA_SOCKET_SOURCE}
- thirdparty/luasocket/src/wsocket.h
- thirdparty/luasocket/src/wsocket.c
- )
+ set(LUA_SOCKET_SOURCE
+ ${LUA_SOCKET_SOURCE}
+ thirdparty/luasocket/src/wsocket.h
+ thirdparty/luasocket/src/wsocket.c
+ )
ELSE()
- set(LUA_SOCKET_SOURCE
- ${LUA_SOCKET_SOURCE}
- thirdparty/luasocket/src/usocket.h
- thirdparty/luasocket/src/usocket.c
- )
+ set(LUA_SOCKET_SOURCE
+ ${LUA_SOCKET_SOURCE}
+ thirdparty/luasocket/src/usocket.h
+ thirdparty/luasocket/src/usocket.c
+ thirdparty/luasocket/src/unix.h
+ thirdparty/luasocket/src/unix.c
+ thirdparty/luasocket/src/unixstream.h
+ thirdparty/luasocket/src/unixstream.c
+ thirdparty/luasocket/src/unixdgram.c
+ thirdparty/luasocket/src/unixdgram.h
+ thirdparty/luasocket/src/serial.c
+ )
ENDIF()
set(LUA_RS232_SOURCE
- thirdparty/librs232/bindings/lua/luars232.c
- thirdparty/librs232/src/rs232.c
+ thirdparty/librs232/bindings/lua/luars232.c
+ thirdparty/librs232/src/rs232.c
)
if(WIN32)
- set(LUA_RS232_SOURCE
- ${LUA_RS232_SOURCE}
- thirdparty/librs232/src/rs232_windows.c
- )
+ set(LUA_RS232_SOURCE
+ ${LUA_RS232_SOURCE}
+ thirdparty/librs232/src/rs232_windows.c
+ )
ELSE()
- set(LUA_RS232_SOURCE
- ${LUA_RS232_SOURCE}
- thirdparty/librs232/src/rs232_posix.c
- )
+ set(LUA_RS232_SOURCE
+ ${LUA_RS232_SOURCE}
+ thirdparty/librs232/src/rs232_posix.c
+ )
ENDIF()
set(UTHASH_SOURCE
- thirdparty/uthash/src/uthash.h
- thirdparty/uthash/src/utlist.h
+ thirdparty/uthash/src/uthash.h
+ thirdparty/uthash/src/utlist.h
)
+
set(MANYMOUSE_SOURCE
- thirdparty/manymouse/linux_evdev.c
- thirdparty/manymouse/macosx_hidmanager.c
- thirdparty/manymouse/macosx_hidutilities.c
- thirdparty/manymouse/manymouse.c
- thirdparty/manymouse/manymouse.h
- thirdparty/manymouse/windows_wminput.c
- thirdparty/manymouse/x11_xinput2.c
+ thirdparty/manymouse/linux_evdev.c
+ thirdparty/manymouse/macosx_hidmanager.c
+ thirdparty/manymouse/macosx_hidutilities.c
+ thirdparty/manymouse/manymouse.c
+ thirdparty/manymouse/manymouse.h
+ thirdparty/manymouse/windows_wminput.c
+ thirdparty/manymouse/x11_xinput2.c
)
add_executable(${CMAKE_PROJECT_NAME}
- ${SINGE_SOURCE}
- ${ARG_PARSER_SOURCE}
- ${LUA_SOURCE}
- ${LUA_FILESYSTEM_SOURCE}
- ${LUA_SOCKET_SOURCE}
- ${LUA_RS232_SOURCE}
- ${UTHASH_SOURCE}
- ${MANYMOUSE_SOURCE}
+ ${SINGE_SOURCE}
+ ${ARG_PARSER_SOURCE}
+ ${JBIG_SOURCE}
+ ${LUA_SOURCE}
+ ${LUA_FILESYSTEM_SOURCE}
+ ${LUA_SOCKET_SOURCE}
+ ${LUA_RS232_SOURCE}
+ ${UTHASH_SOURCE}
+ ${MANYMOUSE_SOURCE}
)
# Perform pre-build operations.
#add_custom_target(BUILD_PREREQS
-# COMMAND ${CMAKE_SOURCE_DIR}/build-deps.sh "${CMAKE_SOURCE_DIR}"
+# COMMAND ${BUILD_DIR}-deps.sh "${CMAKE_SOURCE_DIR}"
# BYPRODUCTS
# ${CMAKE_SOURCE_DIR}/thirdparty-installed/lib/libarchive.a
#)
@@ -224,56 +244,84 @@ add_executable(${CMAKE_PROJECT_NAME}
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC
- build/${KANGAROO_OS}/${KANGAROO_ARCH}
- thirdparty/lua/src
- thirdparty/librs232/include
+ ${BUILD_DIR}
+ ${BUILD_DIR}/include
+ thirdparty/lua/src
+ thirdparty/librs232/include
)
target_link_directories(${CMAKE_PROJECT_NAME} PUBLIC
- build/lib
+ build/lib
)
+if(WIN32)
+ set(LIB_LIST
+ -mwindows
+ -static
+ -lmingw32
+ -lbcrypt
+ -ldinput8
+ -ldxguid
+ -ldxerr8
+ -luser32
+ -lgdi32
+ -lwinmm
+ -limm32
+ -lole32
+ -loleaut32
+ -lshell32
+ -lsetupapi
+ -lversion
+ -luuid
+ -lssp
+ -Dmain=SDL_main
+ )
+else()
+ set(LIB_LIST)
+endif()
target_link_libraries(${CMAKE_PROJECT_NAME}
- -Wl,--start-group
- ${CMAKE_SOURCE_DIR}/build/lib/libz.a
- ${CMAKE_SOURCE_DIR}/build/lib/libbrotlicommon-static.a
- ${CMAKE_SOURCE_DIR}/build/lib/libbrotlidec-static.a
- ${CMAKE_SOURCE_DIR}/build/lib/libbz2_static.a
- ${CMAKE_SOURCE_DIR}/build/lib/libdav1d.a
- ${CMAKE_SOURCE_DIR}/build/lib/libffms2.a
- ${CMAKE_SOURCE_DIR}/build/lib/libfreetype.a
- ${CMAKE_SOURCE_DIR}/build/lib/libharfbuzz.a
- ${CMAKE_SOURCE_DIR}/build/lib/libhwy.a
- ${CMAKE_SOURCE_DIR}/build/lib/libjxl_dec.a
- ${CMAKE_SOURCE_DIR}/build/lib/liblzma.a
- ${CMAKE_SOURCE_DIR}/build/lib/libogg.a
- ${CMAKE_SOURCE_DIR}/build/lib/libopus.a
- ${CMAKE_SOURCE_DIR}/build/lib/libopusfile.a
- ${CMAKE_SOURCE_DIR}/build/lib/libpostproc.a
- ${CMAKE_SOURCE_DIR}/build/lib/libswresample.a
- ${CMAKE_SOURCE_DIR}/build/lib/libswscale.a
- ${CMAKE_SOURCE_DIR}/build/lib/libwavpack.a
- ${CMAKE_SOURCE_DIR}/build/lib/libwebp.a
- ${CMAKE_SOURCE_DIR}/build/lib/libwebpdemux.a
- ${CMAKE_SOURCE_DIR}/build/lib/libxmp.a
- ${CMAKE_SOURCE_DIR}/build/lib/libSDL2.a
- ${CMAKE_SOURCE_DIR}/build/lib/libSDL2_image.a
- ${CMAKE_SOURCE_DIR}/build/lib/libSDL2_mixer.a
- ${CMAKE_SOURCE_DIR}/build/lib/libSDL2_ttf.a
- ${CMAKE_SOURCE_DIR}/build/lib/libSDL2main.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavcodec.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavdevice.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavfilter.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavformat.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavif.a
- ${CMAKE_SOURCE_DIR}/build/lib/libavutil.a
- -Wl,--end-group
- -ldl
- -pthread
- -lm
- -lstdc++
+ -Wl,--start-group
+ ${BUILD_DIR}/lib/libavcodec.a
+ ${BUILD_DIR}/lib/libavdevice.a
+ ${BUILD_DIR}/lib/libavfilter.a
+ ${BUILD_DIR}/lib/libavformat.a
+ ${BUILD_DIR}/lib/libavif.a
+ ${BUILD_DIR}/lib/libavutil.a
+ ${BUILD_DIR}/lib/libbrotlicommon-static.a
+ ${BUILD_DIR}/lib/libbrotlidec-static.a
+ ${BUILD_DIR}/lib/libbz2_static.a
+ ${BUILD_DIR}/lib/libdav1d.a
+ ${BUILD_DIR}/lib/libffms2.a
+ ${BUILD_DIR}/lib/libfreetype.a
+ ${BUILD_DIR}/lib/libharfbuzz.a
+ ${BUILD_DIR}/lib/libhwy.a
+ ${BUILD_DIR}/lib/libjxl_dec.a
+ ${BUILD_DIR}/lib/liblzma.a
+ ${BUILD_DIR}/lib/libogg.a
+ ${BUILD_DIR}/lib/libopus.a
+ ${BUILD_DIR}/lib/libopusfile.a
+ ${BUILD_DIR}/lib/libpostproc.a
+ ${BUILD_DIR}/lib/libSDL2.a
+ ${BUILD_DIR}/lib/libSDL2_image.a
+ ${BUILD_DIR}/lib/libSDL2main.a
+ ${BUILD_DIR}/lib/libSDL2_mixer.a
+ ${BUILD_DIR}/lib/libSDL2_test.a
+ ${BUILD_DIR}/lib/libSDL2_ttf.a
+ ${BUILD_DIR}/lib/libswresample.a
+ ${BUILD_DIR}/lib/libswscale.a
+ ${BUILD_DIR}/lib/libtiff.a
+ ${BUILD_DIR}/lib/libwavpack.a
+ ${BUILD_DIR}/lib/libwebp.a
+ ${BUILD_DIR}/lib/libwebpdemux.a
+ ${BUILD_DIR}/lib/libxmp.a
+ ${BUILD_DIR}/lib/libz.a
+ -Wl,--end-group
+ ${LIB_LIST}
+ -pthread
+ -lm
+ -lstdc++
)
diff --git a/build-deps.sh b/build-all.sh
similarity index 95%
rename from build-deps.sh
rename to build-all.sh
index be1c3a517..f45bc3658 100755
--- a/build-deps.sh
+++ b/build-all.sh
@@ -25,7 +25,7 @@ G_TARGET=
G_GENERATED=
-function buildDeps() {
+function buildAll() {
local OS=$1
local ARCH=$2
local TRIPLE=
@@ -78,7 +78,7 @@ function buildDeps() {
export LD_LIBRARY_PATH=${G_TARGET}
export PKG_CONFIG_LIBDIR=${G_TARGET}/lib/pkgconfig
-#:<
-#include "../build/include/SDL2/SDL.h"
-#include "../build/include/SDL2/SDL_image.h"
-#include "../build/include/SDL2/SDL_mixer.h"
-#include "../build/include/SDL2/SDL_ttf.h"
+#include "include/SDL2/SDL.h"
+#include "include/SDL2/SDL_image.h"
+#include "include/SDL2/SDL_mixer.h"
+#include "include/SDL2/SDL_ttf.h"
#include "../thirdparty/arg_parser/carg_parser.h"
#include "../thirdparty/uthash/src/utlist.h"
@@ -42,7 +42,7 @@
#include "frameFile.h"
#include "videoPlayer.h"
#include "singe.h"
-#include "../build/generated/extensions.h"
+#include "generated/extensions.h"
#include "embedded.h"
diff --git a/src/singe.c b/src/singe.c
index 26523c0fe..e6ad3031c 100644
--- a/src/singe.c
+++ b/src/singe.c
@@ -22,10 +22,10 @@
#include
-#include "../build/include/SDL2/SDL.h"
-#include "../build/include/SDL2/SDL_image.h"
-#include "../build/include/SDL2/SDL_mixer.h"
-#include "../build/include/SDL2/SDL_ttf.h"
+#include "include/SDL2/SDL.h"
+#include "include/SDL2/SDL_image.h"
+#include "include/SDL2/SDL_mixer.h"
+#include "include/SDL2/SDL_ttf.h"
#include "../thirdparty/lua/src/lua.h"
#include "../thirdparty/lua/src/lualib.h"
#include "../thirdparty/lua/src/lauxlib.h"
diff --git a/src/videoPlayer.c b/src/videoPlayer.c
index cdedf0fea..38093c17a 100644
--- a/src/videoPlayer.c
+++ b/src/videoPlayer.c
@@ -20,9 +20,8 @@
*/
-#include "../build/include/SDL2/SDL_mixer.h"
-#include "../build/include/ffms.h"
-
+#include "include/SDL2/SDL_mixer.h"
+#include "../thirdparty/ffms2/include/ffms.h"
#include "../thirdparty/uthash/src/uthash.h"
#include "util.h"
diff --git a/thirdparty/jbigkit/ANNOUNCE b/thirdparty/jbigkit/ANNOUNCE
new file mode 100644
index 000000000..8d0e2c6aa
--- /dev/null
+++ b/thirdparty/jbigkit/ANNOUNCE
@@ -0,0 +1,172 @@
+
+JBIG-KIT lossless image compression library
+-------------------------------------------
+
+by Markus Kuhn
+
+
+The latest release of JBIG-KIT can be downloaded from
+
+ http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+
+JBIG-KIT implements a highly effective data compression algorithm for
+bi-level high-resolution images such as fax pages or scanned
+documents.
+
+JBIG-KIT provides two variants of a portable library of compression
+and decompression functions with a documented interface. You can very
+easily include into your image or document processing software. In
+addition, JBIG-KIT provides ready-to-use compression and decompression
+programs with a simple command line interface (similar to the
+converters found in Jef Poskanzer's PBM graphics file conversion
+package).
+
+JBIG-KIT implements the specification
+
+ International Standard ISO/IEC 11544:1993 and ITU-T Recommendation
+ T.82(1993), "Information technology - Coded representation of picture
+ and audio information - progressive bi-level image compression",
+ ,
+
+which is commonly referred to as the "JBIG1 standard". JBIG (Joint
+Bi-level Image experts Group) is the committee which developed this
+international standard for the lossless compression of images using
+arithmetic coding. Like the well-known compression algorithms JPEG and
+MPEG, JBIG has also been developed and published by the International
+Organization for Standardization (ISO) and the International
+Telecommunication Union (ITU). See also
+
+ http://www.jpeg.org/jbig/
+ http://www.iso.ch/
+ http://www.itu.int/
+
+The JBIG compression algorithm offers the following features:
+
+ - Close to state-of-the-art lossless compression ratio for high
+ resolution bi-level images.
+
+ - About 1.1 to 1.5 times better compression ratio on typical
+ scanned documents compared to G4 fax compression (ITU-T T.6),
+ which has been the best compression algorithm for scanned
+ documents available prior to JBIG.
+
+ - Up to 30 times better compression of scanned images with dithered
+ images compared to G4 fax compression.
+
+ - About 2 times better compression on typical 300 dpi documents
+ compared to 'gzip -9' on raw bitmaps.
+
+ - About 3-4 times better compression than GIF on typical 300 dpi
+ documents.
+
+ - Even much better competitive compression results on computer
+ generated images which are free of scanning distortions.
+
+ - JBIG supports hierarchical "progressive" encoding, that means it is
+ possible to encode a low resolution image first, followed by
+ resolution enhancement data. This allows, for instance, a document
+ browser to display already a good 75 dpi low resolution version of
+ an image, while the data necessary to reconstruct the full 300 dpi
+ version for laser printer reproduction is still arriving (say
+ over a slow network link or mass storage medium).
+
+ - The various resolution layers of a JBIG image in progressive
+ encoding mode together require not much more space than a
+ normal non-progressive mode encoded image (which JBIG also
+ supports).
+
+ - The progressive encoding mode utilizes a quite sophisticated
+ resolution reduction algorithm which offers high quality low
+ resolution versions that preserve the shape of characters as well
+ as the integrity of thin lines and dithered images.
+
+ - JBIG supports multiple bit planes and can this way also be used
+ for grayscale and color images, although the main field of
+ application is compression of bi-level images, i.e. images with
+ only two different pixel values. For grayscale images with up to
+ 6 bit per pixel, JBIG performs superior to JPEG's lossless
+ mode.
+
+JBIG-KIT can be used as free software under the GNU General Public
+License. Other license arrangements more suitable for commercial
+applications are available as well, please contact the author for
+details. JBIG-KIT provides two portable libraries implemented in
+ANSI/ISO C for encoding and decoding JBIG data streams, along with
+documentation. The first library, jbig.c, implements nearly all of the
+options that the JBIG standard provides, but keeps the entire
+uncompressed image in memory. The second library, jbig85.c, implements
+only the ITU-R T.85 subset of the standard that black/white fax
+machines use (single bit per pixel, no "progressive" encoding), and
+keeps only three lines of the uncompressed image in memory, making it
+particularly attractive for low-memory embedded applications.
+
+The libraries are not intended for 8-bit or 16-bit machine
+architectures (e.g., old MS-DOS C compilers). For maximum performance,
+a 32-bit processor is required (64-bit systems work too, of course).
+On architectures with 16-bit pointer arithmetic, the full-featured
+jbig.c library can process only very small images.
+
+Special features of the full-featured jbig.c variant:
+
+ - Fully reentrant multithread-capable design (no global or static
+ variables, isolated malloc()/free() calls, etc.)
+
+ - Capable of handling incomplete and growing JBIG data streams in
+ order to allow earliest display of low resolution versions
+
+ - Capable of handling several incoming data streams simultaneously
+ in one single process and thread
+
+ - Especially designed with applications in mind that want to display
+ incoming data as early as possible (e.g., similar to the way in
+ which Netscape Navigator handles incoming GIF images)
+
+ - Implements all JBIG features and options including progressive and
+ sequential encoding, multiple bit planes, user specified
+ resolution reduction and deterministic prediction tables, adaptive
+ template changes for optimal performance on half-tone images,
+ deterministic prediction, typical prediction in lowest and
+ differential layers, various stripe orderings, etc; only the SEQ
+ and HITOLO options are currently not supported by the decoder
+ (they are normally never required, but could be added later in
+ case of user requirements)
+
+ - Suitable for fax applications, satisfies ITU-T T.85 profile
+
+ - Efficient code, optimized utilization of 32-bit processor
+ registers
+
+ - Very easy to use documented C library interface
+
+ - Included Gray code conversion routines for efficient encoding
+ of grayscale images
+
+ - Ready-to-use pbmtojbg and jbgtopbm converters.
+
+Special features of the light-weight jbig85.c variant:
+
+ - Suitable for low-memory embedded applications
+
+ - Implements only the JBIG1 subset defined in the ITU-T T.85
+ profile (single bit plane, no differential layers)
+
+ - Requires only three pixel rows of the uncompressed image to be
+ kept in memory
+
+ - Handles all NEWLEN modes of operation required by ITU-T T.85 with
+ just a single pass over the data, automatically performing the
+ necessary lookahead after the last stripe
+
+ - Codec buffers only a few bytes of arithmetic-codec data and outputs
+ resulting bytes or lines as soon as they are available.
+
+I will try to provide free support and maintenance for this software
+for the foreseeable future, depending on my available time.
+
+Happy compressing ...
+
+Markus Kuhn
+
+--
+Markus Kuhn, Computer Laboratory, University of Cambridge
+http://www.cl.cam.ac.uk/~mgk25/ || CB3 0FD, Great Britain
diff --git a/thirdparty/jbigkit/CHANGES b/thirdparty/jbigkit/CHANGES
new file mode 100644
index 000000000..b37d64ee8
--- /dev/null
+++ b/thirdparty/jbigkit/CHANGES
@@ -0,0 +1,260 @@
+
+JBIG-KIT revision history
+-------------------------
+
+Changes in upcoming version (TBA)
+
+ - The jbig.c decoder will now, by default, return JBG_ENOMEM if the
+ final image layer would occupy more than two gigabytes. Users can
+ adjust this limit by changing sd->maxmem right after having called
+ jbg_dec_init(&sd). This is to reduce the risk of denial-of-service
+ attacks through excessive image dimensions (e.g., CVE-2017-9937).
+
+ - minor bug fixes and documentation clarifications
+
+Changes in version 2.1 (2014-04-08)
+
+This is a security-critical bug-fix release that remains API and ABI
+backwards compatible to version 2.0. Users who process BIE data from
+untrusted sources should upgrade.
+
+ - fixed a buffer-overflow vulnerability in the jbig.c decoder,
+ reported by Florian Weimer (Red Hat): CVE-2013-6369
+
+ - fixed ability of corrupted input data to force jbig85.c decoder
+ into an end-less loop
+
+ - fixed a bug in the processing of private deterministic-prediction
+ tables (DPPRIV=1) in jbig.c decoder
+
+ - fixed integer-type mismatches in printf arguments on 64-bit systems
+
+ - fuzz-testing script added
+
+
+Changes in version 2.0 (2008-08-30)
+
+Main new features of release 2.0:
+
+ - This release adds a separate lightweight "T.85" version of the
+ encoder and decoder library (jbig85.c, jbig85.h). This new T.85
+ library is optimized for embedded low-memory applications, such as
+ printers and fax machines. It implements only the subset of the
+ JBIG standard that is required by the ITU-T T.85 fax profile,
+ namely only a single bit plane (P = 1) and no differential layers
+ (DL = D = HITOLO = SEQ = ILEAVE = SMID = TPDON = DPON = DPON =
+ DPLAST = 0) and some other restrictions (MY = 0, MX < 128).
+
+ The T.85 library requires only three pixel rows of the
+ uncompressed image to reside in memory at any time. This 3-line
+ buffer has to be allocated by the calling application, therefore
+ the T.85 library will not call any heap management functions such
+ as malloc() or free() itself. It can fully deal with endless-paper
+ fax, where the height of the encoded image is not known initially.
+
+ - There are also two new example applications pbmtojbg85 and
+ jbgtopbm85 included that provide command-line access to the new
+ T.85 library.
+
+API changes in 2.0 to the original full jbig.c library (compared to 1.6):
+
+ - jbg_dec_getwidth(), jbg_dec_getheight(), jbg_dec_getsize(), and
+ jbg_dec_getsize_merged() return now an unsigned long value
+ (was: long), and return 0 (was: -1) if no image is available yet
+
+ - jbg_dec_in() return values changed; the least significant bits of
+ the error codes now provide more information about what caused the
+ error, beyond what the more general error text messages returned by
+ jbg_strerror() reveal
+
+ - non-English translations of error messages are now provided
+ in a separate PO file (e.g., for use with GNU gettext),
+ jbg_strerror() no longer has a language attribute and the
+ JBG_EN, JBG_DE_8859_1, JBG_DE_UTF_8 constants no longer exist
+
+Other changes in 2.0 to the original full jbig.c library:
+
+ - the arithmetic codec routines are now located in a separate source
+ file (they are now used by both the full library jbig.c and the new
+ T.85 library jbig85.c, and might also be of use to other applications)
+
+ - arithmetic decoder behaviour slightly changed to enable the
+ lookahead needed to handle T.85-style NEWLEN after the final
+ stripe
+
+ - added encoder support for adding comment marker segment
+
+ - added encoder option for using SDRST marker instead of SDNORM
+ (only useful to make encoder able to generate a wider range
+ of test data)
+
+ - macro JBG_LICENCE can be changed from the default value "GPL" to a
+ licence agreement reference code to if the library is used under a
+ commercial licence, to clarify under which exact licence the
+ library is used in a particular application
+
+Changes in 2.0 to the command-line wrappers for jbig.c:
+
+ - added pbmtojbg options -C and -r, which provide command-line
+ access to the previous two extensions
+
+ - slightly improved diagnostic output of jbgtopbm option -d
+
+ - pbmtojbg has a new option -f as a shortcut for all the options
+ needed to make the output comply to the basic ITU-T T.85 fax
+ profile
+
+ - jbgtopbm now outputs image dimensions in header padded to 10
+ digits fixed width, for consistency with jbgtopbm85
+ to allow for later in-place update of height due to NEWLEN
+
+
+Changes in version 1.6 (2004-06-11)
+
+ - various small changes to reduce the risk of 32-bit unsigned
+ integer overflows when dealing with extremely large images
+
+ - robuster treatment of L0 = 0xffffffff
+
+ - minor API modification in jbg_enc_options(): parameter l0 changed
+ from type long to unsigned long; previous value now remains
+ unchanged when l0 == 0 (was: l0 < 0)
+
+ - lots of type casts added such that the C source code is now
+ also compilable as C++
+
+
+Changes in version 1.5 (2003-06-11)
+
+ - fixed two minor memory leaks (special thanks to Davide Pizzolato
+ for locating one of these)
+
+ - jbgtopbm does not attempt any more to parse multiple concatenated
+ BIEs (options -m must be used now to enable this feature explicitly),
+ in order to handle BIEs with data after the last expected SDE gracefully
+
+ - various extensions to improve support of JBIG fax applications
+ (ITU-T T.85 profile):
+
+ o support for maximum adaptive template pixel offset increased
+ to MX=127 in both encoder and decoder
+
+ o encoder now has a hook for producing BIEs with a NEWLEN marker
+ segment and VLENGTH=1, in order to assist in testing decoders
+ for T.85 conformance (see also new pbmtojbg option -Y)
+
+ o a new function jbg_newlen() can be used to scan an
+ entire in-memory BIE for NEWLEN marker segments and update the
+ YD value in the BIE header, which can be applied to BIE data
+ before passing it to the decoder for T.85 compliance
+ (Background: the incremental design of the JBIG-KIT decoder
+ makes it infeasible to look ahead for NEWLEN marker segments
+ that occur after the SDE with the last image line, therefore
+ this second pass is necessary to handle the old-style fax
+ applications permitted by T.85 in which the low-RAM encoder
+ doesn't know the height of the image at the start of
+ transmission)
+
+
+Changes in version 1.4 (2002-04-09)
+
+ - typo fixed in stripe number calculation, which caused encoder and
+ decoder to fail on certain image sizes (special thanks to Koen Denecker
+ for locating this one)
+
+
+Changes in version 1.3 (2002-03-23):
+
+ - bugs fixed in jbg_split_planes(), jbg_dec_merge_planes() that
+ caused a failure for more than eight planes per pixel
+
+ - example converters now can handle PGM files with up to 32 bits
+ per pixel
+
+
+Changes in version 1.2 (2000-04-08):
+
+ - bug in the decoder fixed, which caused the rest of the input file
+ to be skipped whenever a comment marker was encountered (special
+ thanks to Ben Rudiak-Gould for
+ reporting this one)
+
+
+Changes in version 1.1 (1999-11-16):
+
+ - serious bug in the encoder fixed, which for a very small
+ percentage of images has caused an unterminated linked list to be
+ created internally that could have been responsible for
+ segmentation violations or non-terminating encoders
+ (special thanks to Hisashi Saiga for
+ tracking that one down)
+
+ - minor bug in the "jbgtopbm -d" diagnostic output fixed
+
+
+Changes in version 1.0 (1998-04-11):
+
+ - two bugs fixed that caused the encoder and decoder to fail
+ under certain modes of operation with several bit planes
+
+ - added new functions jbg_split_planes(), jbg_dec_merge_planes(),
+ and jbg_dec_getsize_merged() for easy handling of grayscale
+ images
+
+ - added support for compressing grayscale PGM files to pbmtojbg
+ and jbgtopbm
+
+ - more changes to avoid paranoid compiler warnings
+
+
+Changes in version 0.9 (1996-01-09):
+
+ - encoder won't break any more on input bitmap data with incorrect
+ zero padding
+
+ - pbmtojbg displays a warning if input file has incorrect zero
+ padding
+
+ - various minor improvements suggested by Stefan Willer
+
+
+ - many minor changes in order to avoid warnings from paranoid
+ compilers
+
+
+Changes in version 0.8 (1995-09-20):
+
+ - namespace cleared up, all names externally visible from the library
+ start now with jbg_ or JBG_
+
+ - minor non-critical bug fixed which caused library to fail compatibility
+ test and showed up especially on DEC Alpha systems
+
+ - jbg_dec_gethight() is now called jbg_dec_getheight()
+
+ - filenames conform now to MS-DOS limits
+
+ - Bug in pbmtojbg fixed (handling of ASCII PBM files)
+
+
+Changes in version 0.7 (1995-06-10):
+
+ - more problems on 16-bit int systems and on Macintosh systems fixed
+ (special thanks to Jean-Pierre Gachen )
+
+ - global Makefile
+
+
+Changes in version 0.6 (1995-06-08):
+
+ - memory leak fixed
+
+ - should now also work on systems where int is only 16-bit large
+
+ - changes of the JBIG "Technical Corrigendum 1" included (special
+ thanks to Dr. Sebestyen from Siemens AG for sending me a copy
+ of the draft)
+
+
+First release: version 0.5 (1995-05-28)
+
diff --git a/thirdparty/jbigkit/COPYING b/thirdparty/jbigkit/COPYING
new file mode 100644
index 000000000..a43ea2126
--- /dev/null
+++ b/thirdparty/jbigkit/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, 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.
+
+ GNU GENERAL PUBLIC LICENSE
+ 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
+
+ Appendix: 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.
+
+
+ Copyright (C) 19yy
+
+ 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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
+
+ , 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.
diff --git a/thirdparty/jbigkit/INSTALL b/thirdparty/jbigkit/INSTALL
new file mode 100644
index 000000000..45d68f57c
--- /dev/null
+++ b/thirdparty/jbigkit/INSTALL
@@ -0,0 +1,163 @@
+
+Getting started with JBIG-KIT
+-----------------------------
+
+Markus Kuhn -- 2014-03-27
+
+
+JBIG-KIT is a portable C library that should work on any platform with
+an ANSI/ISO C compiler, such as GNU gcc.
+
+To get started, compile the demonstration software in pbmtools/ and
+test it with some of the provided example files.
+
+On a Unix system, check Makefile to suit your compiler, then start
+"make". If libjbig.a and/or libjbig85.a have been produced correctly,
+then activate the automatic library test suite with "make test", or
+just start libjbig/tstcodec and libjbig/tstcodec85. If these tests
+fail, please do let me know.
+
+On other operating systems, just link libjbig/jbig.c and
+libjbig/jbig_ar.c together with any application in which you want to
+use the full JBIG-KIT library. Likewise, just link libjbig/jbig85.c
+and libjbig/jbig_ar.c together with any application in which you want
+to use the simpler variant optimized for fax applications.
+
+In subdirectory pbmtools/, you will find the programs pbmtojbg and
+jbgtopbm. These are two file converters, serving as examples for
+applications that use the full JBIG-KIT library (jbig.c). After
+testing them on some of the example JBIG files, you can move these
+executable files together with their respective man pages (in a UNIX
+style environment) to the appropriate directories. Options -h and
+--help will give you short command-line usage summaries. The programs
+pbmtojbg85 and jbgtopbm85 are very similar, but demonstrate use of the
+simpler jbig85.c library instead.
+
+The subdirectory examples/ contains a few files as raw JBIG data
+streams (called bi-level image entities (BIE) in the standard).
+
+Try
+
+ jbgtopbm ccitt1.jbg ccitt1.pbm
+
+to decompress CCITT test letter #1 into a portable bitmap file, which
+you can then further convert using Jef Poskanzer's PBM tools
+, or view with many popular
+image file viewers, such as the "display" command from ImageMagick.
+
+The ccitt1.jbg image is 1728 x 2376 pixels large and may not fit onto
+your display screen. However, fortunately, I have stored it in JBIG's
+"progressive mode" with the following resolution layers:
+
+ layer 0: 216 x 297 pixel
+ layer 1: 432 x 594 pixel
+ layer 2: 864 x 1188 pixel
+ layer 3: 1728 x 2376 pixel
+
+In progressive mode, each layer has twice the resolution of the
+previous one. Resolution layer 0 encodes all its pixels independent
+from any other data; all other resolution layers encode only the
+difference between the previous and the new resolution layer, which
+requires much less space than encoding resolution layers without
+referring to the lower layer. By default, the BIE files produced by
+pbmtojbg will all start with a lowest resolution layer 0 that fits
+onto a 640 x 480 screen.
+
+In order to tell jbgtopbm that you do not want to decode higher
+resolution layers if they will not fit onto your (say) 1024 x 768
+pixel display, simply use
+
+ jbgtopbm -x 1024 -y 768 ccitt1.jbg ccitt1.pbm
+
+You will get a 4 times smaller image, the highest resolution layer
+that still fits onto your screen. You can also directly pipe the image
+to another application using standard output, by removing the second
+file name, e.g.
+
+ jbgtopbm -x 1024 -y 768 ccitt1.jbg | display
+
+In fact, the data in the first quarter of the input file is sufficient
+to decode the requested resolution:
+
+ head --bytes=4000 ccitt1.jbg | ../pbmtools/jbgtopbm -x 1024 -y 768 | display
+
+Now let's do some compression. With
+
+ jbgtopbm ccitt1.jbg ccitt1.pbm
+
+followed by
+
+ pbmtojbg ccitt1.pbm test.jbg
+
+you produce again the same data stream as ccitt1.jbg. However if you
+want that the lowest resolution layer is not larger than 70 x 100
+pixels ("thumb nail" image), then use
+
+ pbmtojbg -v -x 100 -y 150 ccitt1.pbm test.jbg
+
+Option -v will output some technical data, and will tell you that five
+incremental resolution layers have been created, in addition to the
+lowest 54 x 75 pixel large layer 0. Look at the lowest resolution
+layer in test.jbg with
+
+ jbgtopbm -x 100 test.jbg | display
+
+and you will still be able to clearly recognize the layout and line
+structure of the page, which the implemented bi-level
+resolution-reduction algorithm tried to preserve. With
+
+ pbmtojbg -q ccitt1.pbm test.jbg
+
+you can enforce a single resolution layer, which usually requires a
+slightly less space than progressive encoding.
+
+
+OK, another small exercise. Assume you want to build a document
+database in which you want to store scanned images in two resolution
+layers, one for screen previewing and one for laser-printer output.
+However, you do not want your decision to store images in two
+resolutions to cause too much additional storage requirement. You
+decide that 3 resolution layers in JBIG fit your requirement and you
+want to store
+
+ layer 0: 432 x 594 pixels
+
+in the first file test-low.jbg and the two layers
+
+ layer 1: 864 x 1188 pixels
+ layer 2: 1728 x 2376 pixels
+
+in the second file test-high.jbg. No problem, just call
+
+ pbmtojbg -d 2 -l 0 -h 0 ccitt1.pbm test-low.jbg
+ pbmtojbg -d 2 -l 1 -h 2 ccitt1.pbm test-high.jbg
+
+where option -d specifies the total number of layers and -l/-h select
+the range of layers written to the output file. You will see that the
+low and high resolution file together are only 1.6 kB larger than if
+you had stored only the high-res version directly without progressive
+mode (option -q). Progressive mode has reduced the additional storage
+requirement by 50% compared to storing the 3.2 kB low-resolution
+version independently of the high resolution image.
+
+In order to view only the screen version, use
+
+ jbgtopbm test-low.jbg | display
+
+and in order to send the full version to the printer, just concatenate
+both BIE files like in
+
+ cat test-low.jbg test-high.jbg | jbgtopbm -m | ....
+
+
+All this functionality, and more, are available as functions in the
+libjbig C library, which you can link into your application. Just copy
+the relevant files from libjbig/ into your own source-code directory
+and adapt your Makefile. In libjbig/jbig.txt, you will find
+documentation about how to use the full library, while
+libjbig/jbig85.txt documents the fax variant of the library. The
+latter lacks progressive encoding, but can instead deal better with
+images where the height is not yet known at the start of a
+transmission.
+
+Markus
diff --git a/thirdparty/jbigkit/Makefile b/thirdparty/jbigkit/Makefile
new file mode 100644
index 000000000..8ea75490d
--- /dev/null
+++ b/thirdparty/jbigkit/Makefile
@@ -0,0 +1,44 @@
+# Unix makefile for JBIG-KIT
+
+# Select an ANSI/ISO C compiler here, GNU gcc is recommended
+CC = gcc
+
+# Options for the compiler: A high optimization level is suggested
+CFLAGS = -O2 -W -Wno-unused-result
+# CFLAGS = -O -g -W -Wall -Wno-unused-result -ansi -pedantic # -DDEBUG
+
+export CC CFLAGS
+
+VERSION=2.1
+
+all: lib pbm
+ @echo "Enter 'make test' in order to start some automatic tests."
+
+lib:
+ cd libjbig && $(MAKE) -e
+
+pbm: lib
+ cd pbmtools && $(MAKE) -e
+
+test: lib pbm
+ cd libjbig && $(MAKE) test
+ cd pbmtools && $(MAKE) test
+
+analyze:
+ cd libjbig && $(MAKE) analyze
+ cd pbmtools && $(MAKE) analyze
+
+clean:
+ rm -f *~ core
+ cd libjbig && $(MAKE) clean
+ cd pbmtools && $(MAKE) clean
+
+distribution:
+ rm -rf jbigkit-$(VERSION)
+ git archive v$(VERSION) --prefix jbigkit-$(VERSION)/ | tar xvf -
+ $(MAKE) -C jbigkit-$(VERSION)/pbmtools txt
+ tar cvaf jbigkit-$(VERSION).tar.gz jbigkit-$(VERSION)
+
+release:
+ rsync -t jbigkit-$(VERSION).tar.gz $(HOME)/public_html/download/
+ rsync -t jbigkit-$(VERSION)/CHANGES $(HOME)/public_html/jbigkit/
diff --git a/thirdparty/jbigkit/TODO b/thirdparty/jbigkit/TODO
new file mode 100644
index 000000000..c0b01a323
--- /dev/null
+++ b/thirdparty/jbigkit/TODO
@@ -0,0 +1,51 @@
+Features that may appear in some future release regarding jbig.c:
+
+ - function to prepare incompletely decoded images for display by Xlib
+
+ - use a more efficient resolution-reduction method suggested by
+ Dr. Klaus Bartz
+
+ - investigate whether there is a standard way of embedding JBIG
+ into TIFF and implement it (see also RFC 2301)
+
+ - test for and eliminate warning messages from compilers
+ other than GCC
+
+ - multichannel (e.g., RGB) support, PPM support
+
+ - add dynamic library target to Makefile (patch by David Woodhouse),
+ for the benefit of Linux packagers
+
+The NEWLEN handling in jbig.c remains less than ideal. There is no
+easy fix as NEWLEN is inherently incompatible with many of the other
+options that jbig.c supports. The whole point of the VLENGTH bit may
+have been to allow recipients to choose between a jbig.c (VLENGTH=0)
+and jbig85.c (VLENGTH=1) style of decoder implementation. The cleanest
+option would really be to remove NEWLEN support entirely from jbig.c
+and to urge users who need it to use jbig85.c instead. Short of that,
+the new NEWLEN look-ahead architecture from jbig85.c could be
+backported to jbig.c, but this would only only slightly increase the
+number of cases where the jbig.c decoder could deal with a NEWLEN
+marker without a prior invocation of the jbg_newlen() pre-processing
+pass.
+
+The following past feature requests for jbig.c probably have become
+less important since the release of jbig85.c:
+
+ - compile-time option to remove progressive encoding and
+ resolution-reduction support (in the interest of reducing code size)
+
+ - investigate how to best deal with broken BIEs that contain
+ multiple NEWLEN marker segments, which are not permitted by ITU-T
+ T.85, but which have been observed coming from some fax machines;
+ possible options for jbg_newlen(): use first, last, or minimum
+ value
+
+ - version of jbg_newlen() for dealing with BIEs that are split
+ into several blocks
+
+ - call-back function for progress meter
+
+Features that may appear in some future release regarding jbig85.c:
+
+ - man pages for pbmtojbg85 and jbgtopbm85
diff --git a/thirdparty/jbigkit/contrib/INDEX b/thirdparty/jbigkit/contrib/INDEX
new file mode 100644
index 000000000..3e8542aa5
--- /dev/null
+++ b/thirdparty/jbigkit/contrib/INDEX
@@ -0,0 +1,16 @@
+Here are some files which users of JBIG-KIT have contributed and which
+I have included into the package in the hope that you might find them
+useful. If you have questions with regard to these files, better
+contact the respective contributors directly.
+
+---------------------------------------------------------------------------
+
+atariprj.tar
+
+ From: Stefan Willer
+
+ These are four hierarchical project files for use with the Atari ST
+ Pure-C development environment. With these files, installing
+ JBIG-KIT should be child's play for Atari ST users (except the
+ necessary line end changes in all text files).
+
diff --git a/thirdparty/jbigkit/contrib/atariprj.tar b/thirdparty/jbigkit/contrib/atariprj.tar
new file mode 100644
index 000000000..a706bbad8
--- /dev/null
+++ b/thirdparty/jbigkit/contrib/atariprj.tar
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:af05800c10a87864a539dd86bd4f4546bb362207e6b2695dbc0925edea49074f
+size 10240
diff --git a/thirdparty/jbigkit/examples/README b/thirdparty/jbigkit/examples/README
new file mode 100644
index 000000000..c43b4f885
--- /dev/null
+++ b/thirdparty/jbigkit/examples/README
@@ -0,0 +1,8 @@
+The files in this directory are a few sample images and documents
+stored as raw bi-level image entities (BIE) (the data stream specified
+by the JBIG standard).
+
+The source data for the test examples ccitt* and lena.bie is available from
+
+ ftp://ftp.funet.fi/pub/graphics/misc/test-images/
+
diff --git a/thirdparty/jbigkit/examples/ccitt1.jbg b/thirdparty/jbigkit/examples/ccitt1.jbg
new file mode 100644
index 000000000..6288c679e
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt1.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:93159675c3bb72b5baf8f4cc50a6d5bdc4c7636d00b3df35d103fdbfb94df3d0
+size 16830
diff --git a/thirdparty/jbigkit/examples/ccitt2.jbg b/thirdparty/jbigkit/examples/ccitt2.jbg
new file mode 100644
index 000000000..06d2d1883
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt2.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4a228c2c9ce68f0eced024218d8974bf6b28759ed23efa883827b7b9d2eddff8
+size 8958
diff --git a/thirdparty/jbigkit/examples/ccitt3.jbg b/thirdparty/jbigkit/examples/ccitt3.jbg
new file mode 100644
index 000000000..3f384aaa4
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt3.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:282a6acf9f7b354920665b3f622c7a8a24c9f6f6d5cbba1b26996871972f1a37
+size 23642
diff --git a/thirdparty/jbigkit/examples/ccitt4.jbg b/thirdparty/jbigkit/examples/ccitt4.jbg
new file mode 100644
index 000000000..b8c2903dd
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt4.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e4eec46656b7e3949819200bc5c5393f6fc7c92b7c5ccb1ae8bd41e0130a9e2f
+size 58748
diff --git a/thirdparty/jbigkit/examples/ccitt5.jbg b/thirdparty/jbigkit/examples/ccitt5.jbg
new file mode 100644
index 000000000..4ee2f7407
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt5.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:601c65798210409d7affde011f08681b1d24874f19d3808355c3062fab9a416a
+size 28092
diff --git a/thirdparty/jbigkit/examples/ccitt6.jbg b/thirdparty/jbigkit/examples/ccitt6.jbg
new file mode 100644
index 000000000..9b98be86e
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt6.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a074accefbe45a9d9f4768df2bb595c9927a5f79d9546d044a278555d952319a
+size 13503
diff --git a/thirdparty/jbigkit/examples/ccitt7.jbg b/thirdparty/jbigkit/examples/ccitt7.jbg
new file mode 100644
index 000000000..e8efb6e9d
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt7.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0d6e4c8aeb8ccc04463b5edd74e59a759525ccbc767712ea9cdbaefdaf5ddec1
+size 60640
diff --git a/thirdparty/jbigkit/examples/ccitt8.jbg b/thirdparty/jbigkit/examples/ccitt8.jbg
new file mode 100644
index 000000000..7e7fad090
--- /dev/null
+++ b/thirdparty/jbigkit/examples/ccitt8.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:45a19ab97f4ca29fe7fe02c75308d0fe6f01cc486352127aa9ab8f6a9578e675
+size 15135
diff --git a/thirdparty/jbigkit/examples/jbgtests.m b/thirdparty/jbigkit/examples/jbgtests.m
new file mode 100644
index 000000000..2ebc77b36
--- /dev/null
+++ b/thirdparty/jbigkit/examples/jbgtests.m
@@ -0,0 +1,10 @@
+% MATLAB code to generate test files that exercise a JBIG codec
+
+width = 1200;
+img = [];
+for y=1:650;
+ mx = ceil(y / 5);
+ line = uint8(repmat(round(rand(1,mx)),1,ceil(width/mx))) == 1;
+ img = [img ; line(1:width)];
+end
+imwrite(img, 'mx.png', 'PNG');
diff --git a/thirdparty/jbigkit/examples/multi.pgm b/thirdparty/jbigkit/examples/multi.pgm
new file mode 100644
index 000000000..603a0bcd8
--- /dev/null
+++ b/thirdparty/jbigkit/examples/multi.pgm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3a73e95a31682faf804e5fb9d55f4e56e24ccdcfa52bb183bb704bfffffd777f
+size 52
diff --git a/thirdparty/jbigkit/examples/mx.jbg b/thirdparty/jbigkit/examples/mx.jbg
new file mode 100644
index 000000000..4f69228aa
--- /dev/null
+++ b/thirdparty/jbigkit/examples/mx.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0e131764d51a5d43f86ead9a66423247f6fa152b67bedf90a21a85d593bab60c
+size 74847
diff --git a/thirdparty/jbigkit/examples/sandra.pgm b/thirdparty/jbigkit/examples/sandra.pgm
new file mode 100644
index 000000000..ce0a52594
--- /dev/null
+++ b/thirdparty/jbigkit/examples/sandra.pgm
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2ef7cd894cf592766bc9246d01211313484165a7766e9294c725a9fd37d71302
+size 26878
diff --git a/thirdparty/jbigkit/examples/xvlogo.jbg b/thirdparty/jbigkit/examples/xvlogo.jbg
new file mode 100644
index 000000000..8efb1a5a2
--- /dev/null
+++ b/thirdparty/jbigkit/examples/xvlogo.jbg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f111aace8710a3d7c2873e58e6ea1ae23d6a22ec274b4a92ab4b0cba0538353e
+size 8628
diff --git a/thirdparty/jbigkit/libjbig/Makefile b/thirdparty/jbigkit/libjbig/Makefile
new file mode 100644
index 000000000..10362bc1c
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/Makefile
@@ -0,0 +1,60 @@
+# Unix makefile for the JBIG-KIT library
+
+# Select an ANSI/ISO C compiler here, GNU gcc is recommended
+CC = gcc
+
+# Options for the compiler: A high optimization level is suggested
+CFLAGS = -g -O -W -Wall -ansi -pedantic # --coverage
+
+all: libjbig.a libjbig85.a tstcodec tstcodec85 tstjoint
+
+tstcodec: tstcodec.o jbig.o jbig_ar.o
+ $(CC) $(LDFLAGS) $(CFLAGS) -o tstcodec tstcodec.o jbig.o jbig_ar.o
+
+tstcodec85: tstcodec85.o jbig85.o jbig_ar.o
+ $(CC) $(LDFLAGS) $(CFLAGS) -o tstcodec85 tstcodec85.o jbig85.o jbig_ar.o
+
+tstjoint: tstjoint.o jbig.o jbig85.o jbig_ar.o
+ $(CC) $(LDFLAGS) $(CFLAGS) -o tstjoint \
+ tstjoint.o jbig.o jbig85.o jbig_ar.o
+
+libjbig.a: jbig.o jbig_ar.o
+ rm -f libjbig.a
+ ar rc libjbig.a jbig.o jbig_ar.o
+ -ranlib libjbig.a
+
+libjbig85.a: jbig85.o jbig_ar.o
+ rm -f libjbig85.a
+ ar rc libjbig85.a jbig85.o jbig_ar.o
+ -ranlib libjbig85.a
+
+jbig.o: jbig.c jbig.h jbig_ar.h
+jbig85.o: jbig85.c jbig85.h jbig_ar.h
+jbig_ar.o: jbig_ar.c jbig_ar.h
+tstcodec.o: tstcodec.c jbig.h
+tstcodec85.o: tstcodec85.c jbig85.h
+
+update-po: jbig.c jbig85.c Makefile
+ xgettext -ojbig.pot -k_ \
+ --copyright-holder='Markus Kuhn' \
+ --msgid-bugs-address='http://www.cl.cam.ac.uk/~mgk25/jbigkit/' \
+ --package-name jbigkit \
+ jbig.c jbig85.c
+ cd po && for po in *.po ; do \
+ msgmerge --update $$po ../jbig.pot ; done
+
+analyze:
+ clang --analyze *.c
+
+test: tstcodec tstcodec85 tstjoint
+ ./tstcodec
+ ./tstcodec85
+ ./tstjoint
+
+t82test.pbm: tstcodec
+ ./tstcodec $@
+
+clean:
+ rm -f *.o *.gcda *.gcno *.gcov *.plist *~ core gmon.out dbg_d\=??.pbm
+ rm -f t82test.pbm
+ rm -f tstcodec tstcodec85 tstjoint
diff --git a/thirdparty/jbigkit/libjbig/jbig.c b/thirdparty/jbigkit/libjbig/jbig.c
new file mode 100644
index 000000000..289b6d87f
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig.c
@@ -0,0 +1,3292 @@
+/*
+ * Portable JBIG image compression library
+ *
+ * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * This module implements a portable standard C encoder and decoder
+ * using the JBIG1 lossless bi-level image compression algorithm
+ * specified in International Standard ISO 11544:1993 and
+ * ITU-T Recommendation T.82. See the file jbig.txt for usage
+ * instructions and application examples.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * If you want to use this program under different license conditions,
+ * then contact the author for an arrangement.
+ */
+
+#ifdef DEBUG
+#include
+#else
+#define NDEBUG
+#endif
+
+#include
+#include
+#include
+
+#include "jbig.h"
+
+#define MX_MAX 127 /* maximal supported mx offset for
+ * adaptive template in the encoder */
+
+#define TPB2CX 0x195 /* contexts for TP special pixels */
+#define TPB3CX 0x0e5
+#define TPDCX 0xc3f
+
+/* marker codes */
+#define MARKER_STUFF 0x00
+#define MARKER_RESERVE 0x01
+#define MARKER_SDNORM 0x02
+#define MARKER_SDRST 0x03
+#define MARKER_ABORT 0x04
+#define MARKER_NEWLEN 0x05
+#define MARKER_ATMOVE 0x06
+#define MARKER_COMMENT 0x07
+#define MARKER_ESC 0xff
+
+/* loop array indices */
+#define STRIPE 0
+#define LAYER 1
+#define PLANE 2
+
+/* special jbg_buf pointers (instead of NULL) */
+#define SDE_DONE ((struct jbg_buf *) -1)
+#define SDE_TODO ((struct jbg_buf *) 0)
+
+/* object code version id */
+
+const char jbg_version[] =
+ "JBIG-KIT " JBG_VERSION " -- (c) 1995-2014 Markus Kuhn -- "
+ "Licence: " JBG_LICENCE "\n";
+
+/*
+ * The following array specifies for each combination of the 3
+ * ordering bits, which ii[] variable represents which dimension
+ * of s->sde.
+ */
+static const int iindex[8][3] = {
+ { 2, 1, 0 }, /* no ordering bit set */
+ { -1, -1, -1}, /* SMID -> illegal combination */
+ { 2, 0, 1 }, /* ILEAVE */
+ { 1, 0, 2 }, /* SMID + ILEAVE */
+ { 0, 2, 1 }, /* SEQ */
+ { 1, 2, 0 }, /* SEQ + SMID */
+ { 0, 1, 2 }, /* SEQ + ILEAVE */
+ { -1, -1, -1 } /* SEQ + SMID + ILEAVE -> illegal combination */
+};
+
+#define _(String) String /* to mark translatable string for GNU gettext */
+
+/*
+ * Array with English ASCII error messages that correspond
+ * to return values from public functions in this library.
+ */
+static const char *errmsg[] = {
+ _("All OK"), /* JBG_EOK */
+ _("Reached specified image size"), /* JBG_EOK_INTR */
+ _("Unexpected end of input data stream"), /* JBG_EAGAIN */
+ _("Not enough memory available"), /* JBG_ENOMEM */
+ _("ABORT marker segment encountered"), /* JBG_EABORT */
+ _("Unknown marker segment encountered"), /* JBG_EMARKER */
+ _("Input data stream contains invalid data"), /* JBG_EINVAL */
+ _("Input data stream uses unimplemented JBIG features"), /* JBG_EIMPL */
+ _("Incremental BIE does not continue previous one") /* JBG_ENOCONT */
+};
+
+
+/*
+ * The following three functions are the only places in this code, were
+ * C library memory management functions are called. The whole JBIG
+ * library has been designed in order to allow multi-threaded
+ * execution. No static or global variables are used, so all fuctions
+ * are fully reentrant. However if you want to use this multi-thread
+ * capability and your malloc, realloc and free are not reentrant,
+ * then simply add the necessary semaphores or mutex primitives below.
+ * In contrast to C's malloc() and realloc(), but like C's calloc(),
+ * these functions take two parameters nmemb and size that are multiplied
+ * before being passed on to the corresponding C function.
+ * This we can catch all overflows during a size_t multiplication a
+ * a single place.
+ */
+
+#ifndef SIZE_MAX
+#define SIZE_MAX ((size_t) -1) /* largest value of size_t */
+#endif
+
+static void *checked_malloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ /* Full manual exception handling is ugly here for performance
+ * reasons. If an adequate handling of lack of memory is required,
+ * then use C++ and throw a C++ exception instead of abort(). */
+
+ /* assert that nmemb * size <= SIZE_MAX */
+ if (size > SIZE_MAX / nmemb)
+ abort();
+
+ p = malloc(nmemb * size);
+
+ if (!p)
+ abort();
+
+#if 0
+ fprintf(stderr, "%p = malloc(%lu * %lu)\n", p,
+ (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+ return p;
+}
+
+
+static void *checked_realloc(void *ptr, size_t nmemb, size_t size)
+{
+ void *p;
+
+ /* Full manual exception handling is ugly here for performance
+ * reasons. If an adequate handling of lack of memory is required,
+ * then use C++ and throw a C++ exception here instead of abort(). */
+
+ /* assert that nmemb * size <= SIZE_MAX */
+ if (size > SIZE_MAX / nmemb)
+ abort();
+
+ p = realloc(ptr, nmemb * size);
+
+ if (!p)
+ abort();
+
+#if 0
+ fprintf(stderr, "%p = realloc(%p, %lu * %lu)\n", p, ptr,
+ (unsigned long) nmemb, (unsigned long) size);
+#endif
+
+ return p;
+}
+
+
+static void checked_free(void *ptr)
+{
+ free(ptr);
+
+#if 0
+ fprintf(stderr, "free(%p)\n", ptr);
+#endif
+
+}
+
+
+
+
+/*
+ * Memory management for buffers which are used for temporarily
+ * storing SDEs by the encoder.
+ *
+ * The following functions manage a set of struct jbg_buf storage
+ * containers were each can keep JBG_BUFSIZE bytes. The jbg_buf
+ * containers can be linked to form linear double-chained lists for
+ * which a number of operations are provided. Blocks which are
+ * tempoarily not used any more are returned to a freelist which each
+ * encoder keeps. Only the destructor of the encoder actually returns
+ * the block via checked_free() to the stdlib memory management.
+ */
+
+
+/*
+ * Allocate a new buffer block and initialize it. Try to get it from
+ * the free_list, and if it is empty, call checked_malloc().
+ */
+static struct jbg_buf *jbg_buf_init(struct jbg_buf **free_list)
+{
+ struct jbg_buf *new_block;
+
+ /* Test whether a block from the free list is available */
+ if (*free_list) {
+ new_block = *free_list;
+ *free_list = new_block->next;
+ } else {
+ /* request a new memory block */
+ new_block = (struct jbg_buf *) checked_malloc(1, sizeof(struct jbg_buf));
+ }
+ new_block->len = 0;
+ new_block->next = NULL;
+ new_block->previous = NULL;
+ new_block->last = new_block;
+ new_block->free_list = free_list;
+
+ return new_block;
+}
+
+
+/*
+ * Return an entire free_list to the memory management of stdlib.
+ * This is only done by jbg_enc_free().
+ */
+static void jbg_buf_free(struct jbg_buf **free_list)
+{
+ struct jbg_buf *tmp;
+
+ while (*free_list) {
+ tmp = (*free_list)->next;
+ checked_free(*free_list);
+ *free_list = tmp;
+ }
+
+ return;
+}
+
+
+/*
+ * Append a single byte to a single list that starts with the block
+ * *(struct jbg_buf *) head. The type of *head is void here in order to
+ * keep the interface of the arithmetic encoder gereric, which uses this
+ * function as a call-back function in order to deliver single bytes
+ * for a PSCD.
+ */
+static void jbg_buf_write(int b, void *head)
+{
+ struct jbg_buf *now;
+
+ now = ((struct jbg_buf *) head)->last;
+ if (now->len < JBG_BUFSIZE - 1) {
+ now->d[now->len++] = b;
+ return;
+ }
+ now->next = jbg_buf_init(((struct jbg_buf *) head)->free_list);
+ now->next->previous = now;
+ now->next->d[now->next->len++] = b;
+ ((struct jbg_buf *) head)->last = now->next;
+
+ return;
+}
+
+
+/*
+ * Remove any trailing zero bytes from the end of a linked jbg_buf list,
+ * however make sure that no zero byte is removed which directly
+ * follows a 0xff byte (i.e., keep MARKER_ESC MARKER_STUFF sequences
+ * intact). This function is used to remove any redundant final zero
+ * bytes from a PSCD.
+ */
+static void jbg_buf_remove_zeros(struct jbg_buf *head)
+{
+ struct jbg_buf *last;
+
+ while (1) {
+ /* remove trailing 0x00 in last block of list until this block is empty */
+ last = head->last;
+ while (last->len && last->d[last->len - 1] == 0)
+ last->len--;
+ /* if block became really empty, remove it in case it is not the
+ * only remaining block and then loop to next block */
+ if (last->previous && !last->len) {
+ head->last->next = *head->free_list;
+ *head->free_list = head->last;
+ head->last = last->previous;
+ head->last->next = NULL;
+ } else
+ break;
+ }
+
+ /*
+ * If the final non-zero byte is 0xff (MARKER_ESC), then we just have
+ * removed a MARKER_STUFF and we will append it again now in order
+ * to preserve PSCD status of byte stream.
+ */
+ if (head->last->len && head->last->d[head->last->len - 1] == MARKER_ESC)
+ jbg_buf_write(MARKER_STUFF, head);
+
+ return;
+}
+
+
+/*
+ * The jbg_buf list which starts with block *new_prefix is concatenated
+ * with the list which starts with block **start and *start will then point
+ * to the first block of the new list.
+ */
+static void jbg_buf_prefix(struct jbg_buf *new_prefix, struct jbg_buf **start)
+{
+ new_prefix->last->next = *start;
+ new_prefix->last->next->previous = new_prefix->last;
+ new_prefix->last = new_prefix->last->next->last;
+ *start = new_prefix;
+
+ return;
+}
+
+
+/*
+ * Send the contents of a jbg_buf list that starts with block **head to
+ * the call back function data_out and return the blocks of the jbg_buf
+ * list to the freelist from which these jbg_buf blocks have been taken.
+ * After the call, *head == NULL.
+ */
+static void jbg_buf_output(struct jbg_buf **head,
+ void (*data_out)(unsigned char *start,
+ size_t len, void *file),
+ void *file)
+{
+ struct jbg_buf *tmp;
+
+ while (*head) {
+ data_out((*head)->d, (*head)->len, file);
+ tmp = (*head)->next;
+ (*head)->next = *(*head)->free_list;
+ *(*head)->free_list = *head;
+ *head = tmp;
+ }
+
+ return;
+}
+
+
+/*
+ * Calculate y = ceil(x/2) applied n times, which is equivalent to
+ * y = ceil(x/(2^n)). This function is used to
+ * determine the number of pixels per row or column after n resolution
+ * reductions. E.g. X[d-1] = jbg_ceil_half(X[d], 1) and X[0] =
+ * jbg_ceil_half(X[d], d) as defined in clause 6.2.3 of T.82.
+ */
+unsigned long jbg_ceil_half(unsigned long x, int n)
+{
+ unsigned long mask;
+
+ assert(n >= 0 && n < 32);
+ mask = (1UL << n) - 1; /* the lowest n bits are 1 here */
+ return (x >> n) + ((mask & x) != 0);
+}
+
+
+/*
+ * Set L0 (the number of lines in a stripe at lowest resolution)
+ * to a default value, such that there are about 35 stripes, as
+ * suggested in Annex C of ITU-T T.82, without exceeding the
+ * limit 128/2^D suggested in Annex A.
+ */
+static void jbg_set_default_l0(struct jbg_enc_state *s)
+{
+ s->l0 = jbg_ceil_half(s->yd, s->d) / 35; /* 35 stripes/image */
+ while ((s->l0 << s->d) > 128) /* but <= 128 lines/stripe */
+ --s->l0;
+ if (s->l0 < 2) s->l0 = 2;
+}
+
+
+/*
+ * Calculate the number of stripes, as defined in clause 6.2.3 of T.82.
+ */
+unsigned long jbg_stripes(unsigned long l0, unsigned long yd,
+ unsigned long d)
+{
+ unsigned long y0 = jbg_ceil_half(yd, d);
+
+ return y0 / l0 + (y0 % l0 != 0);
+}
+
+
+/*
+ * Resolution reduction table given by ITU-T T.82 Table 17
+ */
+
+static char jbg_resred[4096] = {
+ 0,0,0,1,0,0,0,1,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1,0,0,1,1,1,0,1,1,
+ 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,0,1,0,0,1,1,0,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,1,1,0,1,0,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 1,1,1,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,0,1,1,
+ 1,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,
+ 0,0,1,0,1,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,
+ 0,0,0,0,1,0,0,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+ 0,0,1,0,0,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,1,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,
+ 0,0,1,0,0,1,1,1,0,0,0,0,1,0,0,1,0,0,0,1,1,1,1,0,1,0,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,
+ 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,0,1,0,0,0,1,1,0,1,0,0,0,0,1,1,1,1,0,0,1,1,1,0,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+ 0,0,0,1,0,0,0,1,0,0,1,0,0,0,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,1,1,0,1,1,1,0,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,0,1,0,0,1,1,0,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,1,0,1,1,0,1,1,1,
+ 0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,0,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,1,0,1,0,0,0,1,1,1,1,1,1,1,1,1,
+ 1,1,1,0,1,0,0,0,1,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,1,
+ 0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,1,1,0,1,1,0,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,1,0,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,
+ 1,0,0,0,1,0,0,0,0,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,1,1,0,
+ 0,0,1,1,1,1,1,1,0,0,0,0,1,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,1,0,0,0,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,1,0,1,0,1,1,0,0,1,0,1,1,1,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,1,1,
+ 0,0,1,0,1,0,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,1,
+ 0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,
+ 0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,1,
+ 0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,
+ 1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,
+ 0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,
+ 0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,0,0,1,1,0,0,0,1,0,1,1,1,0,1,1,1
+};
+
+/*
+ * Deterministic prediction tables given by ITU-T T.82 tables
+ * 19 to 22. The table below is organized differently, the
+ * index bits are permutated for higher efficiency.
+ */
+
+static char jbg_dptable[256 + 512 + 2048 + 4096] = {
+ /* phase 0: offset=0 */
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ /* phase 1: offset=256 */
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,0,0,2,2,2,2,2,0,0,2,2,2,2,2,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
+ 1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,1,1,2,2,2,2,2,0,2,2,2,2,2,2,
+ 2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,0,2,0,2,2,2,2,2,0,2,2,2,2,2,2,2,
+ 0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 2,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,1,
+ 0,2,0,2,2,1,2,1,2,2,2,2,1,1,1,1,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,1,
+ 2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,0,0,0,2,2,2,2,2,
+ 2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,
+ /* phase 2: offset=768 */
+ 2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,2,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,2,2,2,2,2,1,1,1,
+ 2,0,2,2,2,1,2,1,0,2,2,2,1,2,1,2,2,2,2,0,2,2,2,2,0,2,0,2,2,2,2,2,
+ 0,2,0,0,1,1,1,1,2,2,2,2,1,1,1,1,0,2,0,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,1,2,1,2,2,2,0,2,2,1,2,1,0,2,0,2,1,1,1,1,
+ 2,0,0,2,2,2,2,2,0,2,0,2,2,0,2,0,2,0,2,0,2,2,2,1,2,2,0,2,1,1,2,1,
+ 2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,0,0,0,2,2,2,2,0,0,0,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,2,1,0,2,2,2,1,1,1,1,2,0,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+ 2,2,2,0,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,1,2,1,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,1,1,2,2,2,2,1,1,1,1,
+ 2,2,2,1,2,2,2,2,2,2,1,2,0,0,0,0,2,2,0,2,2,1,2,2,2,2,2,2,1,1,1,1,
+ 2,0,0,0,2,2,2,2,0,2,2,2,2,2,2,0,2,2,2,0,2,2,2,2,2,0,0,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,1,
+ 0,2,0,2,2,1,1,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,1,2,
+ 2,2,2,0,2,2,2,2,2,2,0,2,2,2,2,2,2,2,1,2,2,2,2,2,2,0,1,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,2,1,0,2,2,2,1,1,1,1,
+ 2,0,2,0,2,1,2,2,0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+ 2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+ 2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,0,0,2,2,2,1,2,2,2,
+ 0,0,2,0,2,2,2,2,0,2,0,2,2,0,2,0,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+ 2,2,0,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,0,2,2,2,2,2,0,2,0,2,2,2,2,2,1,0,1,2,2,2,2,1,0,2,2,2,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,0,2,0,2,1,2,2,2,2,2,2,2,2,0,2,2,1,2,2,
+ 0,2,0,0,1,1,1,1,0,2,2,2,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,2,1,2,1,1,
+ 2,2,0,2,2,1,2,2,2,2,2,2,1,2,2,2,2,0,2,2,2,2,2,2,0,2,0,2,1,2,1,1,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,2,2,2,2,1,1,2,2,2,2,2,1,2,2,2,
+ 2,0,2,2,2,1,2,1,0,2,2,2,2,2,1,2,2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,
+ 0,2,0,0,2,2,2,2,1,2,2,2,2,2,2,0,2,1,2,2,2,2,2,2,1,2,2,2,2,2,2,2,
+ 0,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,1,0,2,2,
+ 0,0,0,2,2,1,1,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,1,2,2,2,2,1,2,1,2,
+ 0,0,0,0,2,2,2,2,2,2,0,2,2,1,2,2,2,1,2,1,2,2,2,2,1,2,1,2,0,2,2,2,
+ 2,0,2,0,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,2,2,2,2,0,2,2,1,2,2,0,0,0,2,2,2,2,2,1,2,2,0,2,2,2,1,2,1,2,
+ 2,0,2,0,2,2,2,2,0,2,0,2,2,1,2,2,0,2,0,0,2,2,2,2,2,2,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,2,2,1,
+ 1,2,0,2,2,1,2,1,2,2,2,2,1,2,2,2,2,0,2,0,2,2,2,2,2,0,2,2,1,1,1,1,
+ 0,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,2,1,2,1,
+ 2,2,0,0,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,
+ 2,2,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,
+ 2,0,2,0,2,2,2,2,2,1,1,2,2,2,2,2,2,2,2,2,2,2,2,1,0,2,0,2,2,2,1,2,
+ 2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,2,0,2,0,2,2,2,2,0,0,0,0,2,1,2,1,
+ 2,2,2,2,2,1,2,1,0,2,0,2,2,2,2,2,2,0,2,0,2,2,2,2,0,2,0,2,2,2,2,1,
+ 2,0,2,0,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,
+ 2,0,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,0,2,0,2,2,2,2,0,0,0,2,2,2,2,1,
+ 2,0,2,0,2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,2,
+ /* phase 3: offset=2816 */
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+ 2,2,2,1,2,2,2,0,1,1,1,1,0,0,0,0,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,0,2,0,2,1,2,1,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,
+ 2,0,2,2,2,1,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,0,1,1,2,1,
+ 2,2,2,0,2,2,2,1,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,
+ 2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,1,1,1,2,0,0,0,
+ 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+ 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,0,2,0,2,1,2,1,0,0,2,0,1,1,2,1,
+ 2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+ 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,
+ 2,0,2,2,2,1,2,2,0,0,2,0,1,1,2,1,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,0,0,0,1,1,1,1,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,2,1,0,2,2,0,1,2,
+ 2,2,2,1,2,2,2,0,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,0,0,2,1,1,1,2,0,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,1,2,1,2,0,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,2,2,0,0,2,2,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,0,0,0,2,1,1,1,
+ 2,2,2,0,2,2,2,1,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,0,2,2,2,1,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,1,2,1,1,0,2,0,0,2,0,2,2,2,1,2,2,0,2,1,2,1,2,0,2,
+ 2,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+ 0,0,2,0,1,1,2,1,0,0,1,0,1,1,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,0,2,2,1,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+ 2,0,0,0,2,1,1,1,0,0,0,0,1,1,1,1,2,2,2,1,2,2,2,0,2,1,2,1,2,0,2,0,
+ 2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,
+ 2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,1,2,1,2,0,2,0,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,1,1,1,2,0,0,0,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,2,2,0,2,2,2,1,2,0,2,0,2,1,2,1,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,1,0,0,1,0,1,1,
+ 2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,2,2,1,2,2,2,0,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,1,2,2,1,0,2,0,2,2,2,1,2,2,2,
+ 2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 0,2,0,0,1,2,1,1,2,0,0,0,2,1,1,1,2,2,2,2,2,2,2,2,1,0,1,2,0,1,0,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,1,2,2,2,0,2,2,1,1,2,2,0,0,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,2,1,2,2,2,0,2,2,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,1,2,2,2,0,2,2,2,
+ 2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,2,
+ 0,0,0,0,1,1,1,1,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,
+ 0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,1,2,2,2,0,1,1,2,1,0,0,2,0,2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,2,2,0,2,2,2,1,2,
+ 2,0,2,0,2,1,2,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,2,2,
+ 0,2,0,0,1,2,1,1,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,2,1,1,1,2,0,0,2,2,2,1,2,2,2,
+ 2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 0,0,2,2,1,1,2,2,0,2,1,2,1,2,0,2,2,1,2,1,2,0,2,0,1,2,1,2,0,2,0,2,
+ 2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,0,0,2,2,1,1,2,2,0,0,2,2,1,1,2,2,2,2,2,2,2,2,2,2,0,0,2,2,1,1,
+ 2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,1,2,1,1,
+ 2,2,2,0,2,2,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,
+ 2,2,2,2,2,2,2,2,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,0,0,2,1,1,1,
+ 2,0,2,2,2,1,2,2,0,2,2,2,1,2,2,2,2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,2,1,2,0,2,0,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,0,2,1,2,1,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,1,2,1,2,0,2,0,2,2,1,2,1,2,0,2,0,2,2,2,2,2,2,2,2,
+ 2,0,2,1,2,1,2,0,0,2,1,2,1,2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,0,2,0,2,1,2,1,
+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,1,2,1,2,0,2,0,1,1,1,2,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,
+ 2,0,2,0,2,1,2,1,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+};
+
+
+/*
+ * Initialize the status struct for the encoder.
+ */
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+ int planes, unsigned char **p,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file)
+{
+ unsigned long l, lx;
+ int i;
+
+ assert(x > 0 && y > 0 && planes > 0 && planes < 256);
+ s->xd = x;
+ s->yd = y;
+ s->yd1 = y; /* This is the hight initially announced in BIH. To provoke
+ generation of NEWLEN for T.85 compatibility tests,
+ overwrite with new value s->yd1 > s->yd */
+ s->planes = planes;
+ s->data_out = data_out;
+ s->file = file;
+
+ s->d = 0;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ s->mx = 8;
+ s->my = 0;
+ s->order = JBG_ILEAVE | JBG_SMID;
+ s->options = JBG_TPBON | JBG_TPDON | JBG_DPON;
+ s->comment = NULL;
+ s->dppriv = jbg_dptable;
+ s->res_tab = jbg_resred;
+
+ s->highres = (int *) checked_malloc(planes, sizeof(int));
+ s->lhp[0] = p;
+ s->lhp[1] = (unsigned char **)
+ checked_malloc(planes, sizeof(unsigned char *));
+ for (i = 0; i < planes; i++) {
+ s->highres[i] = 0;
+ s->lhp[1][i] = (unsigned char *)
+ checked_malloc(jbg_ceil_half(y, 1), jbg_ceil_half(x, 1+3));
+ }
+
+ s->free_list = NULL;
+ s->s = (struct jbg_arenc_state *)
+ checked_malloc(s->planes, sizeof(struct jbg_arenc_state));
+ s->tx = (int *) checked_malloc(s->planes, sizeof(int));
+ lx = jbg_ceil_half(x, 1);
+ s->tp = (char *) checked_malloc(lx, sizeof(char));
+ for (l = 0; l < lx; s->tp[l++] = 2) ;
+ s->sde = NULL;
+
+ return;
+}
+
+
+/*
+ * This function selects the number of differential layers based on
+ * the maximum size requested for the lowest resolution layer. If
+ * possible, a number of differential layers is selected, which will
+ * keep the size of the lowest resolution layer below or equal to the
+ * given width x and height y. However not more than 6 differential
+ * resolution layers will be used. In addition, a reasonable value for
+ * l0 (height of one stripe in the lowest resolution layer) is
+ * selected, which obeys the recommended limitations for l0 in annex A
+ * and C of the JBIG standard. The selected number of resolution layers
+ * is returned.
+ */
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long x,
+ unsigned long y)
+{
+ for (s->d = 0; s->d < 6; s->d++)
+ if (jbg_ceil_half(s->xd, s->d) <= x && jbg_ceil_half(s->yd, s->d) <= y)
+ break;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ return s->d;
+}
+
+
+/*
+ * As an alternative to jbg_enc_lrlmax(), the following function allows
+ * to specify the number of layers directly. The stripe height and layer
+ * range is also adjusted automatically here.
+ */
+void jbg_enc_layers(struct jbg_enc_state *s, int d)
+{
+ if (d < 0 || d > 31)
+ return;
+ s->d = d;
+ s->dl = 0;
+ s->dh = s->d;
+ jbg_set_default_l0(s);
+ return;
+}
+
+
+/*
+ * Specify the highest and lowest resolution layers which will be
+ * written to the output file. Call this function not before
+ * jbg_enc_layers() or jbg_enc_lrlmax(), because these two functions
+ * reset the lowest and highest resolution layer to default values.
+ * Negative values are ignored. The total number of layers is returned.
+ */
+int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh)
+{
+ if (dl >= 0 && dl <= s->d) s->dl = dl;
+ if (dh >= s->dl && dh <= s->d) s->dh = dh;
+
+ return s->d;
+}
+
+
+/*
+ * The following function allows to specify the bits describing the
+ * options of the format as well as the maximum AT movement window and
+ * the number of layer 0 lines per stripes.
+ */
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+ unsigned long l0, int mx, int my)
+{
+ if (order >= 0 && order <= 0x0f) s->order = order;
+ if (options >= 0) s->options = options;
+ if (l0 > 0) s->l0 = l0;
+ if (mx >= 0 && mx < 128) s->mx = mx;
+ if (my >= 0 && my < 256) s->my = my;
+
+ return;
+}
+
+
+/*
+ * This function actually does all the tricky work involved in producing
+ * a SDE, which is stored in the appropriate s->sde[][][] element
+ * for later output in the correct order.
+ */
+static void encode_sde(struct jbg_enc_state *s,
+ long stripe, int layer, int plane)
+{
+ unsigned char *hp, *lp1, *lp2, *p0, *p1, *q1, *q2;
+ unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl;
+ unsigned long line_h0 = 0, line_h1 = 0;
+ unsigned long line_h2, line_h3, line_l1, line_l2, line_l3;
+ struct jbg_arenc_state *se;
+ unsigned long y; /* current line number in highres image */
+ unsigned long i; /* current line number within highres stripe */
+ unsigned long j; /* current column number in highres image */
+ long o;
+ unsigned a, p, t;
+ int ltp, ltp_old, cx;
+ unsigned long c_all, c[MX_MAX + 1], cmin, cmax, clmin, clmax;
+ int tmax, at_determined;
+ int new_tx;
+ long new_tx_line = -1;
+ int reset;
+ struct jbg_buf *new_jbg_buf;
+
+#ifdef DEBUG
+ static long tp_lines, tp_exceptions, tp_pixels, dp_pixels;
+ static long encoded_pixels;
+#endif
+
+ /* return immediately if this stripe has already been encoded */
+ if (s->sde[stripe][layer][plane] != SDE_TODO)
+ return;
+
+#ifdef DEBUG
+ if (stripe == 0)
+ tp_lines = tp_exceptions = tp_pixels = dp_pixels = encoded_pixels = 0;
+ fprintf(stderr, "encode_sde: s/d/p = %2ld/%2d/%2d\n",
+ stripe, layer, plane);
+#endif
+
+ /* number of lines per stripe in highres image */
+ hl = s->l0 << layer;
+ /* number of lines per stripe in lowres image */
+ ll = hl >> 1;
+ /* current line number in highres image */
+ y = stripe * hl;
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - layer);
+ hy = jbg_ceil_half(s->yd, s->d - layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointer to first image byte of highres stripe */
+ hp = s->lhp[s->highres[plane]][plane] + stripe * hl * hbpl;
+ lp2 = s->lhp[1 - s->highres[plane]][plane] + stripe * ll * lbpl;
+ lp1 = lp2 + lbpl;
+
+ /* check whether we can refer to any state of a previous stripe */
+ reset = (stripe == 0) || (s->options & JBG_SDRST);
+
+ /* initialize arithmetic encoder */
+ se = s->s + plane;
+ arith_encode_init(se, !reset);
+ s->sde[stripe][layer][plane] = jbg_buf_init(&s->free_list);
+ se->byte_out = jbg_buf_write;
+ se->file = s->sde[stripe][layer][plane];
+
+ /* initialize adaptive template movement algorithm */
+ c_all = 0;
+ for (t = 0; t <= s->mx; t++)
+ c[t] = 0;
+ if (stripe == 0) /* the SDRST case is handled at the end */
+ s->tx[plane] = 0;
+ new_tx = -1;
+ at_determined = 0; /* we haven't yet decided the template move */
+ if (s->mx == 0)
+ at_determined = 1;
+
+ /* initialize typical prediction */
+ ltp = 0;
+ if (reset)
+ ltp_old = 0;
+ else {
+ ltp_old = 1;
+ p1 = hp - hbpl;
+ if (y > 1) {
+ q1 = p1 - hbpl;
+ while (p1 < hp && (ltp_old = (*p1++ == *q1++)) != 0) ;
+ } else
+ while (p1 < hp && (ltp_old = (*p1++ == 0)) != 0) ;
+ }
+
+ if (layer == 0) {
+
+ /*
+ * Encode lowest resolution layer
+ */
+
+ for (i = 0; i < hl && y < hy; i++, y++) {
+
+ /* check whether it is worth to perform an ATMOVE */
+ if (!at_determined && c_all > 2048) {
+ cmin = clmin = 0xffffffffL;
+ cmax = clmax = 0;
+ tmax = 0;
+ for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) {
+ if (c[t] > cmax) cmax = c[t];
+ if (c[t] < cmin) cmin = c[t];
+ if (c[t] > c[tmax]) tmax = t;
+ }
+ clmin = (c[0] < cmin) ? c[0] : cmin;
+ clmax = (c[0] > cmax) ? c[0] : cmax;
+ if (c_all - cmax < (c_all >> 3) &&
+ cmax - c[s->tx[plane]] > c_all - cmax &&
+ cmax - c[s->tx[plane]] > (c_all >> 4) &&
+ /* ^ T.82 said < here, fixed in Cor.1/25 */
+ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+ cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+ cmax - cmin > (c_all >> 2) &&
+ (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+ /* we have decided to perform an ATMOVE */
+ new_tx = tmax;
+ if (!(s->options & JBG_DELAY_AT)) {
+ new_tx_line = i;
+ s->tx[plane] = new_tx;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+ i, new_tx, c_all);
+#endif
+ }
+ at_determined = 1;
+ }
+ assert(s->tx[plane] >= 0); /* i.e., tx can safely be cast to unsigned */
+
+ /* typical prediction */
+ if (s->options & JBG_TPBON) {
+ ltp = 1;
+ p1 = hp;
+ if (i > 0 || !reset) {
+ q1 = hp - hbpl;
+ while (q1 < hp && (ltp = (*p1++ == *q1++)) != 0) ;
+ } else
+ while (p1 < hp + hbpl && (ltp = (*p1++ == 0)) != 0) ;
+ arith_encode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX,
+ ltp == ltp_old);
+#ifdef DEBUG
+ tp_lines += ltp;
+#endif
+ ltp_old = ltp;
+ if (ltp) {
+ /* skip next line */
+ hp += hbpl;
+ continue;
+ }
+ }
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently coded pixel X:
+ *
+ * 76543210765432107654321076543210 line_h3
+ * 76543210765432107654321076543210 line_h2
+ * 76543210765432107654321X76543210 line_h1
+ */
+
+ line_h1 = line_h2 = line_h3 = 0;
+ if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8;
+ if (i > 1 || !reset) line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+
+ /* encode line */
+ for (j = 0; j < hx; hp++) {
+ line_h1 |= *hp;
+ if (j < hbpl * 8 - 8 && (i > 0 || !reset)) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (i > 1 || !reset)
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+ arith_encode(se, (((line_h2 >> 10) & 0x3e0) | a |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+ }
+ else
+ arith_encode(se, (((line_h2 >> 10) & 0x3f0) |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx && j < hx-2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 5; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ c[t] += 0 == p;
+ }
+ ++c_all;
+ }
+ } while (++j & 7 && j < hx);
+ } else {
+ /* three line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (6 + s->tx[plane])) & 0x004));
+ arith_encode(se, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x078) | a |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+ } else
+ arith_encode(se, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x07c) |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx && j < hx-2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 3; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ c[t] += 0 == p;
+ }
+ ++c_all;
+ }
+ } while (++j & 7 && j < hx);
+ } /* if (s->options & JBG_LRLTWO) */
+ } /* for (j = ...) */
+ } /* for (i = ...) */
+
+ } else {
+
+ /*
+ * Encode differential layer
+ */
+
+ for (i = 0; i < hl && y < hy; i++, y++) {
+
+ /* check whether it is worth to perform an ATMOVE */
+ if (!at_determined && c_all > 2048) {
+ cmin = clmin = 0xffffffffL;
+ cmax = clmax = 0;
+ tmax = 0;
+ for (t = 3; t <= s->mx; t++) {
+ if (c[t] > cmax) cmax = c[t];
+ if (c[t] < cmin) cmin = c[t];
+ if (c[t] > c[tmax]) tmax = t;
+ }
+ clmin = (c[0] < cmin) ? c[0] : cmin;
+ clmax = (c[0] > cmax) ? c[0] : cmax;
+ if (c_all - cmax < (c_all >> 3) &&
+ cmax - c[s->tx[plane]] > c_all - cmax &&
+ cmax - c[s->tx[plane]] > (c_all >> 4) &&
+ /* ^ T.82 said < here, fixed in Cor.1/25 */
+ cmax - (c_all - c[s->tx[plane]]) > c_all - cmax &&
+ cmax - (c_all - c[s->tx[plane]]) > (c_all >> 4) &&
+ cmax - cmin > (c_all >> 2) &&
+ (s->tx[plane] || clmax - clmin > (c_all >> 3))) {
+ /* we have decided to perform an ATMOVE */
+ new_tx = tmax;
+ if (!(s->options & JBG_DELAY_AT)) {
+ new_tx_line = i;
+ s->tx[plane] = new_tx;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%ld, tx=%d, c_all=%ld\n",
+ i, new_tx, c_all);
+#endif
+ }
+ at_determined = 1;
+ }
+
+ if ((i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+ lp1 = lp2;
+
+ /* typical prediction */
+ if (s->options & JBG_TPDON && (i & 1) == 0) {
+ q1 = lp1; q2 = lp2;
+ p0 = p1 = hp;
+ if (i < hl - 1 && y < hy - 1)
+ p0 = hp + hbpl;
+ if (i > 1 || !reset)
+ line_l3 = (long)*(q2 - lbpl) << 8;
+ else
+ line_l3 = 0;
+ line_l2 = (long)*q2 << 8;
+ line_l1 = (long)*q1 << 8;
+ ltp = 1;
+ for (j = 0; j < lx && ltp; q1++, q2++) {
+ if (j < lbpl * 8 - 8) {
+ if (i > 1 || !reset)
+ line_l3 |= *(q2 - lbpl + 1);
+ line_l2 |= *(q2 + 1);
+ line_l1 |= *(q1 + 1);
+ }
+ do {
+ if ((j >> 2) < hbpl) {
+ line_h1 = *(p1++);
+ line_h0 = *(p0++);
+ }
+ do {
+ line_l3 <<= 1;
+ line_l2 <<= 1;
+ line_l1 <<= 1;
+ line_h1 <<= 2;
+ line_h0 <<= 2;
+ cx = (((line_l3 >> 15) & 0x007) |
+ ((line_l2 >> 12) & 0x038) |
+ ((line_l1 >> 9) & 0x1c0));
+ if (cx == 0x000)
+ if ((line_h1 & 0x300) == 0 && (line_h0 & 0x300) == 0)
+ s->tp[j] = 0;
+ else {
+ ltp = 0;
+#ifdef DEBUG
+ tp_exceptions++;
+#endif
+ }
+ else if (cx == 0x1ff)
+ if ((line_h1 & 0x300) == 0x300 && (line_h0 & 0x300) == 0x300)
+ s->tp[j] = 1;
+ else {
+ ltp = 0;
+#ifdef DEBUG
+ tp_exceptions++;
+#endif
+ }
+ else
+ s->tp[j] = 2;
+ } while (++j & 3 && j < lx);
+ } while (j & 7 && j < lx);
+ } /* for (j = ...) */
+ arith_encode(se, TPDCX, !ltp);
+#ifdef DEBUG
+ tp_lines += ltp;
+#endif
+ }
+
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently coded
+ * highres pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 7654321X 76543210 line_h1
+ *
+ * Layout of the variables line_l1, line_l2, line_l3, which contain
+ * the low resolution pixels near the currently coded pixel as bits.
+ * The lowres pixel in which the currently coded highres pixel is
+ * located is marked as Y:
+ *
+ * 76543210 76543210 76543210 76543210 line_l3
+ * 76543210 7654321Y 76543210 76543210 line_l2
+ * 76543210 76543210 76543210 76543210 line_l1
+ */
+
+
+ line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+ if (i > 0 || !reset) line_h2 = (long)*(hp - hbpl) << 8;
+ if (i > 1 || !reset) {
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ line_l3 = (long)*(lp2 - lbpl) << 8;
+ }
+ line_l2 = (long)*lp2 << 8;
+ line_l1 = (long)*lp1 << 8;
+
+ /* encode line */
+ for (j = 0; j < hx; lp1++, lp2++) {
+ if ((j >> 1) < lbpl * 8 - 8) {
+ if (i > 1 || !reset)
+ line_l3 |= *(lp2 - lbpl + 1);
+ line_l2 |= *(lp2 + 1);
+ line_l1 |= *(lp1 + 1);
+ }
+ do { /* ... while (j & 15 && j < hx) */
+
+ assert(hp - (s->lhp[s->highres[plane]][plane] +
+ (stripe * hl + i) * hbpl)
+ == (ptrdiff_t) j >> 3);
+
+ assert(lp2 - (s->lhp[1-s->highres[plane]][plane] +
+ (stripe * ll + (i>>1)) * lbpl)
+ == (ptrdiff_t) j >> 4);
+
+ line_h1 |= *hp;
+ if (j < hbpl * 8 - 8) {
+ if (i > 0 || !reset) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (i > 1 || !reset)
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ }
+ do { /* ... while (j & 7 && j < hx) */
+ line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1;
+ if (ltp && s->tp[j >> 1] < 2) {
+ /* pixel are typical and have not to be encoded */
+ line_h1 <<= 2; line_h2 <<= 2; line_h3 <<= 2;
+#ifdef DEBUG
+ do {
+ ++tp_pixels;
+ } while (++j & 1 && j < hx);
+#else
+ j += 2;
+#endif
+ } else
+ do { /* ... while (++j & 1 && j < hx) */
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+
+ /* deterministic prediction */
+ if (s->options & JBG_DPON) {
+ if ((y & 1) == 0) {
+ if ((j & 1) == 0) {
+ /* phase 0 */
+ if (s->dppriv[((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x010) |
+ ((line_h2 >> 10) & 0x0e0)] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ } else {
+ /* phase 1 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x030) |
+ ((line_h2 >> 10) & 0x1c0)) + 256] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ }
+ } else {
+ if ((j & 1) == 0) {
+ /* phase 2 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x010) |
+ ((line_h2 >> 10) & 0x0e0) |
+ ((line_h3 >> 7) & 0x700)) + 768] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ } else {
+ /* phase 3 */
+ if (s->dppriv[(((line_l3 >> 16) & 0x003) |
+ ((line_l2 >> 14) & 0x00c) |
+ ((line_h1 >> 5) & 0x030) |
+ ((line_h2 >> 10) & 0x1c0) |
+ ((line_h3 >> 7) & 0xe00)) + 2816] < 2) {
+#ifdef DEBUG
+ ++dp_pixels;
+#endif
+ continue;
+ }
+ }
+ }
+ }
+
+ /* determine context */
+ if (s->tx[plane]) {
+ if ((unsigned) s->tx[plane] > j)
+ a = 0;
+ else {
+ o = (j - s->tx[plane]) - (j & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx[plane] > 23 ||
+ a == ((line_h1 >> (4 + s->tx[plane])) & 0x010));
+ cx = (((line_h1 >> 9) & 0x003) | a |
+ ((line_h2 >> 13) & 0x00c) |
+ ((line_h3 >> 11) & 0x020));
+ } else
+ cx = (((line_h1 >> 9) & 0x003) |
+ ((line_h2 >> 13) & 0x01c) |
+ ((line_h3 >> 11) & 0x020));
+ if (j & 1)
+ cx |= (((line_l2 >> 9) & 0x0c0) |
+ ((line_l1 >> 7) & 0x300)) | (1UL << 10);
+ else
+ cx |= (((line_l2 >> 10) & 0x0c0) |
+ ((line_l1 >> 8) & 0x300));
+ cx |= (y & 1) << 11;
+
+ arith_encode(se, cx, (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+
+ /* statistics for adaptive template changes */
+ if (!at_determined && j >= s->mx) {
+ c[0] += !(((line_h2 >> 6) ^ line_h1) & 0x100);
+ for (t = 3; t <= s->mx; t++)
+ c[t] += !(((line_h1 >> t) ^ line_h1) & 0x100);
+ ++c_all;
+ }
+
+ } while (++j & 1 && j < hx);
+ } while (j & 7 && j < hx);
+ hp++;
+ } while (j & 15 && j < hx);
+ } /* for (j = ...) */
+
+ /* low resolution pixels are used twice */
+ if ((i & 1) == 0) {
+ lp1 -= lbpl;
+ lp2 -= lbpl;
+ }
+
+ } /* for (i = ...) */
+ }
+
+ arith_encode_flush(se);
+ jbg_buf_remove_zeros(s->sde[stripe][layer][plane]);
+ jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+ jbg_buf_write((s->options & JBG_SDRST) ? MARKER_SDRST : MARKER_SDNORM,
+ s->sde[stripe][layer][plane]);
+ if (s->options & JBG_SDRST)
+ s->tx[plane] = 0;
+
+ /* add ATMOVE */
+ if (new_tx != -1) {
+ if (s->options & JBG_DELAY_AT) {
+ /* ATMOVE will become active at the first line of the next stripe */
+ s->tx[plane] = new_tx;
+ jbg_buf_write(MARKER_ESC, s->sde[stripe][layer][plane]);
+ jbg_buf_write(MARKER_ATMOVE, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ jbg_buf_write(s->tx[plane], s->sde[stripe][layer][plane]);
+ jbg_buf_write(0, s->sde[stripe][layer][plane]);
+ } else {
+ /* ATMOVE has already become active during this stripe
+ * => we have to prefix the SDE data with an ATMOVE marker */
+ new_jbg_buf = jbg_buf_init(&s->free_list);
+ jbg_buf_write(MARKER_ESC, new_jbg_buf);
+ jbg_buf_write(MARKER_ATMOVE, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 24) & 0xff, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 16) & 0xff, new_jbg_buf);
+ jbg_buf_write((new_tx_line >> 8) & 0xff, new_jbg_buf);
+ jbg_buf_write(new_tx_line & 0xff, new_jbg_buf);
+ jbg_buf_write(new_tx, new_jbg_buf);
+ jbg_buf_write(0, new_jbg_buf);
+ jbg_buf_prefix(new_jbg_buf, &s->sde[stripe][layer][plane]);
+ }
+ }
+
+#if 0
+ if (stripe == s->stripes - 1)
+ fprintf(stderr, "tp_lines = %ld, tp_exceptions = %ld, tp_pixels = %ld, "
+ "dp_pixels = %ld, encoded_pixels = %ld\n",
+ tp_lines, tp_exceptions, tp_pixels, dp_pixels, encoded_pixels);
+#endif
+
+ return;
+}
+
+
+/*
+ * Create the next lower resolution version of an image
+ */
+static void resolution_reduction(struct jbg_enc_state *s, int plane,
+ int higher_layer)
+{
+ unsigned long hl, ll, hx, hy, lx, ly, hbpl, lbpl;
+ unsigned char *hp1, *hp2, *hp3, *lp;
+ unsigned long line_h1, line_h2, line_h3, line_l2;
+ unsigned long y; /* current line number in lowres image */
+ unsigned long i; /* current line number within lowres stripe */
+ unsigned long j; /* current column number in lowres image */
+ int pix, k, l;
+
+ /* number of lines per stripe in highres image */
+ hl = s->l0 << higher_layer;
+ /* number of lines per stripe in lowres image */
+ ll = hl >> 1;
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - higher_layer);
+ hy = jbg_ceil_half(s->yd, s->d - higher_layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointers to first image bytes */
+ hp2 = s->lhp[s->highres[plane]][plane];
+ hp1 = hp2 + hbpl;
+ hp3 = hp2 - hbpl;
+ lp = s->lhp[1 - s->highres[plane]][plane];
+
+#ifdef DEBUG
+ fprintf(stderr, "resolution_reduction: plane = %d, higher_layer = %d\n",
+ plane, higher_layer);
+#endif
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently coded
+ * lowres pixel /\:
+ * \/
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 765432/\ 76543210 line_h2
+ * 76543210 76543210 765432\/ 76543210 line_h1
+ *
+ * Layout of the variable line_l2, which contains the low resolution
+ * pixels near the currently coded pixel as bits. The lowres pixel
+ * which is currently coded is marked as X:
+ *
+ * 76543210 76543210 76543210 76543210 line_l2
+ * X
+ */
+
+ for (y = 0; y < ly;) {
+ for (i = 0; i < ll && y < ly; i++, y++) {
+ if (2*y + 1 >= hy)
+ hp1 = hp2;
+ pix = 0;
+ line_h1 = line_h2 = line_h3 = line_l2 = 0;
+ for (j = 0; j < lbpl * 8; j += 8) {
+ *lp = 0;
+ if (i > 0 || (y > 0 && !(s->options & JBG_SDRST)))
+ line_l2 |= *(lp-lbpl);
+ for (k = 0; k < 8 && j + k < lx; k += 4) {
+ if (((j + k) >> 2) < hbpl) {
+ if (i > 0 || (y > 0 && !(s->options & JBG_SDRST)))
+ line_h3 |= *hp3;
+ ++hp3;
+ line_h2 |= *(hp2++);
+ line_h1 |= *(hp1++);
+ }
+ for (l = 0; l < 4 && j + k + l < lx; l++) {
+ line_h3 <<= 2;
+ line_h2 <<= 2;
+ line_h1 <<= 2;
+ line_l2 <<= 1;
+ pix = s->res_tab[((line_h1 >> 8) & 0x007) |
+ ((line_h2 >> 5) & 0x038) |
+ ((line_h3 >> 2) & 0x1c0) |
+ (pix << 9) | ((line_l2 << 2) & 0xc00)];
+ *lp = (*lp << 1) | pix;
+ }
+ }
+ ++lp;
+ }
+ *(lp - 1) <<= lbpl * 8 - lx;
+ hp1 += hbpl;
+ hp2 += hbpl;
+ hp3 += hbpl;
+ }
+ }
+
+#ifdef DEBUG
+ {
+ FILE *f;
+ char fn[50];
+
+ sprintf(fn, "dbg_d=%02d.pbm", higher_layer - 1);
+ f = fopen(fn, "wb");
+ fprintf(f, "P4\n%lu %lu\n", lx, ly);
+ fwrite(s->lhp[1 - s->highres[plane]][plane], 1, lbpl * ly, f);
+ fclose(f);
+ }
+#endif
+
+ return;
+}
+
+
+/*
+ * This function is called inside the three loops of jbg_enc_out() in
+ * order to write the next SDE. It has first to generate the required
+ * SDE and all SDEs which have to be encoded before this SDE can be
+ * created. The problem here is that if we want to output a lower
+ * resolution layer, we have to apply the resolution reduction
+ * algorithm first to get it. As we try to safe as much memory as
+ * possible, the resolution reduction will overwrite previous higher
+ * resolution bitmaps. Consequently, we have to encode and buffer SDEs
+ * which depend on higher resolution layers before we can start the
+ * resolution reduction. All the logic about which SDE has to be
+ * encoded before resolution reduction is allowed is handled
+ * here. This approach may be a bit more complex than alternative ways
+ * of doing it, but it minimizes the amount of temporary memory used.
+ */
+static void output_sde(struct jbg_enc_state *s,
+ unsigned long stripe, int layer, int plane)
+{
+ int lfcl; /* lowest fully coded layer */
+ long i;
+ unsigned long u;
+
+ assert(s->sde[stripe][layer][plane] != SDE_DONE);
+
+ if (s->sde[stripe][layer][plane] != SDE_TODO) {
+#ifdef DEBUG
+ fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n",
+ stripe, layer, plane);
+#endif
+ jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+ s->sde[stripe][layer][plane] = SDE_DONE;
+ return;
+ }
+
+ /* Determine the smallest resolution layer in this plane for which
+ * not yet all stripes have been encoded into SDEs. This layer will
+ * have to be completely coded, before we can apply the next
+ * resolution reduction step. */
+ lfcl = 0;
+ for (i = s->d; i >= 0; i--)
+ if (s->sde[s->stripes - 1][i][plane] == SDE_TODO) {
+ lfcl = i + 1;
+ break;
+ }
+ if (lfcl > s->d && s->d > 0 && stripe == 0) {
+ /* perform the first resolution reduction */
+ resolution_reduction(s, plane, s->d);
+ }
+ /* In case HITOLO is not used, we have to encode and store the higher
+ * resolution layers first, although we do not need them right now. */
+ while (lfcl - 1 > layer) {
+ for (u = 0; u < s->stripes; u++)
+ encode_sde(s, u, lfcl - 1, plane);
+ --lfcl;
+ s->highres[plane] ^= 1;
+ if (lfcl > 1)
+ resolution_reduction(s, plane, lfcl - 1);
+ }
+
+ encode_sde(s, stripe, layer, plane);
+
+#ifdef DEBUG
+ fprintf(stderr, "writing SDE: s/d/p = %2lu/%2d/%2d\n", stripe, layer, plane);
+#endif
+ jbg_buf_output(&s->sde[stripe][layer][plane], s->data_out, s->file);
+ s->sde[stripe][layer][plane] = SDE_DONE;
+
+ if (stripe == s->stripes - 1 && layer > 0 &&
+ s->sde[0][layer-1][plane] == SDE_TODO) {
+ s->highres[plane] ^= 1;
+ if (layer > 1)
+ resolution_reduction(s, plane, layer - 1);
+ }
+
+ return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the internal format into the representation required
+ * for the 1728 byte long DPTABLE element of a BIH.
+ *
+ * The bit order of the DPTABLE format (see also ITU-T T.82 figure 13) is
+ *
+ * high res: 4 5 6 low res: 0 1
+ * 7 8 9 2 3
+ * 10 11 12
+ *
+ * were 4 table entries are packed into one byte, while we here use
+ * internally an unpacked 6912 byte long table indexed by the following
+ * bit order:
+ *
+ * high res: 7 6 5 high res: 8 7 6 low res: 1 0
+ * (phase 0) 4 . . (phase 1) 5 4 . 3 2
+ * . . . . . .
+ *
+ * high res: 10 9 8 high res: 11 10 9
+ * (phase 2) 7 6 5 (phase 3) 8 7 6
+ * 4 . . 5 4 .
+ */
+void jbg_int2dppriv(unsigned char *dptable, const char *internal)
+{
+ int i, j, k;
+ int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+ int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+ int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+ int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+
+ for (i = 0; i < 1728; dptable[i++] = 0) ;
+
+#define FILL_TABLE1(offset, len, trans) \
+ for (i = 0; i < len; i++) { \
+ k = 0; \
+ for (j = 0; i >> j; j++) \
+ k |= ((i >> j) & 1) << trans[j]; \
+ dptable[(i + offset) >> 2] |= \
+ (internal[k + offset] & 3) << ((3 - (i&3)) << 1); \
+ }
+
+ FILL_TABLE1( 0, 256, trans0);
+ FILL_TABLE1( 256, 512, trans1);
+ FILL_TABLE1( 768, 2048, trans2);
+ FILL_TABLE1(2816, 4096, trans3);
+
+ return;
+}
+
+
+/*
+ * Convert the table which controls the deterministic prediction
+ * process from the 1728 byte long DPTABLE format into the 6912 byte long
+ * internal format.
+ */
+void jbg_dppriv2int(char *internal, const unsigned char *dptable)
+{
+ int i, j, k;
+ int trans0[ 8] = { 1, 0, 3, 2, 7, 6, 5, 4 };
+ int trans1[ 9] = { 1, 0, 3, 2, 8, 7, 6, 5, 4 };
+ int trans2[11] = { 1, 0, 3, 2, 10, 9, 8, 7, 6, 5, 4 };
+ int trans3[12] = { 1, 0, 3, 2, 11, 10, 9, 8, 7, 6, 5, 4 };
+
+#define FILL_TABLE2(offset, len, trans) \
+ for (i = 0; i < len; i++) { \
+ k = 0; \
+ for (j = 0; i >> j; j++) \
+ k |= ((i >> j) & 1) << trans[j]; \
+ internal[k + offset] = \
+ (dptable[(i + offset) >> 2] >> ((3 - (i & 3)) << 1)) & 3; \
+ }
+
+ FILL_TABLE2( 0, 256, trans0);
+ FILL_TABLE2( 256, 512, trans1);
+ FILL_TABLE2( 768, 2048, trans2);
+ FILL_TABLE2(2816, 4096, trans3);
+
+ return;
+}
+
+
+/*
+ * Encode one full BIE and pass the generated data to the specified
+ * call-back function
+ */
+void jbg_enc_out(struct jbg_enc_state *s)
+{
+ unsigned long bpl;
+ unsigned char buf[20];
+ unsigned long xd, yd, y;
+ long ii[3], is[3], ie[3]; /* generic variables for the 3 nested loops */
+ unsigned long stripe;
+ int layer, plane;
+ int order;
+ unsigned char dpbuf[1728];
+
+ /* some sanity checks */
+ s->order &= JBG_HITOLO | JBG_SEQ | JBG_ILEAVE | JBG_SMID;
+ order = s->order & (JBG_SEQ | JBG_ILEAVE | JBG_SMID);
+ if (iindex[order][0] < 0)
+ s->order = order = JBG_SMID | JBG_ILEAVE;
+ if (s->options & JBG_DPON && s->dppriv != jbg_dptable)
+ s->options |= JBG_DPPRIV;
+ if (s->mx > MX_MAX)
+ s->mx = MX_MAX;
+ s->my = 0;
+ if (s->mx && s->mx < ((s->options & JBG_LRLTWO) ? 5U : 3U))
+ s->mx = 0;
+ if (s->d > 255 || s->d < 0 || s->dh > s->d || s->dh < 0 ||
+ s->dl < 0 || s->dl > s->dh || s->planes < 0 || s->planes > 255)
+ return;
+ /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+ if (s->d > 31 || (s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+ return;
+ if (s->yd1 < s->yd)
+ s->yd1 = s->yd;
+ if (s->yd1 > s->yd)
+ s->options |= JBG_VLENGTH;
+
+ /* ensure correct zero padding of bitmap at the final byte of each line */
+ if (s->xd & 7) {
+ bpl = jbg_ceil_half(s->xd, 3); /* bytes per line */
+ for (plane = 0; plane < s->planes; plane++)
+ for (y = 0; y < s->yd; y++)
+ s->lhp[0][plane][y * bpl + bpl - 1] &= ~((1 << (8 - (s->xd & 7))) - 1);
+ }
+
+ /* prepare BIH */
+ buf[0] = s->dl;
+ buf[1] = s->dh;
+ buf[2] = s->planes;
+ buf[3] = 0;
+ xd = jbg_ceil_half(s->xd, s->d - s->dh);
+ yd = jbg_ceil_half(s->yd1, s->d - s->dh);
+ buf[4] = xd >> 24;
+ buf[5] = (xd >> 16) & 0xff;
+ buf[6] = (xd >> 8) & 0xff;
+ buf[7] = xd & 0xff;
+ buf[8] = yd >> 24;
+ buf[9] = (yd >> 16) & 0xff;
+ buf[10] = (yd >> 8) & 0xff;
+ buf[11] = yd & 0xff;
+ buf[12] = s->l0 >> 24;
+ buf[13] = (s->l0 >> 16) & 0xff;
+ buf[14] = (s->l0 >> 8) & 0xff;
+ buf[15] = s->l0 & 0xff;
+ buf[16] = s->mx;
+ buf[17] = s->my;
+ buf[18] = s->order;
+ buf[19] = s->options & 0x7f;
+
+#if 0
+ /* sanitize L0 (if it was set to 0xffffffff for T.85-style NEWLEN tests) */
+ if (s->l0 > (s->yd >> s->d))
+ s->l0 = s->yd >> s->d;
+#endif
+
+ /* calculate number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+
+ /* allocate buffers for SDE pointers */
+ if (s->sde == NULL) {
+ s->sde = (struct jbg_buf ****)
+ checked_malloc(s->stripes, sizeof(struct jbg_buf ***));
+ for (stripe = 0; stripe < s->stripes; stripe++) {
+ s->sde[stripe] = (struct jbg_buf ***)
+ checked_malloc(s->d + 1, sizeof(struct jbg_buf **));
+ for (layer = 0; layer < s->d + 1; layer++) {
+ s->sde[stripe][layer] = (struct jbg_buf **)
+ checked_malloc(s->planes, sizeof(struct jbg_buf *));
+ for (plane = 0; plane < s->planes; plane++)
+ s->sde[stripe][layer][plane] = SDE_TODO;
+ }
+ }
+ }
+
+ /* output BIH */
+ s->data_out(buf, 20, s->file);
+ if ((s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+ (JBG_DPON | JBG_DPPRIV)) {
+ /* write private table */
+ jbg_int2dppriv(dpbuf, s->dppriv);
+ s->data_out(dpbuf, 1728, s->file);
+ }
+
+#if 0
+ /*
+ * Encode everything first. This is a simple-minded alternative to
+ * all the tricky on-demand encoding logic in output_sde() for
+ * debugging purposes.
+ */
+ for (layer = s->dh; layer >= s->dl; layer--) {
+ for (plane = 0; plane < s->planes; plane++) {
+ if (layer > 0)
+ resolution_reduction(s, plane, layer);
+ for (stripe = 0; stripe < s->stripes; stripe++)
+ encode_sde(s, stripe, layer, plane);
+ s->highres[plane] ^= 1;
+ }
+ }
+#endif
+
+ /*
+ * Generic loops over all SDEs. Which loop represents layer, plane and
+ * stripe depends on the option flags.
+ */
+
+ /* start and end value for each loop */
+ is[iindex[order][STRIPE]] = 0;
+ ie[iindex[order][STRIPE]] = s->stripes - 1;
+ is[iindex[order][LAYER]] = s->dl;
+ ie[iindex[order][LAYER]] = s->dh;
+ is[iindex[order][PLANE]] = 0;
+ ie[iindex[order][PLANE]] = s->planes - 1;
+
+ for (ii[0] = is[0]; ii[0] <= ie[0]; ii[0]++)
+ for (ii[1] = is[1]; ii[1] <= ie[1]; ii[1]++)
+ for (ii[2] = is[2]; ii[2] <= ie[2]; ii[2]++) {
+
+ stripe = ii[iindex[order][STRIPE]];
+ if (s->order & JBG_HITOLO)
+ layer = s->dh - (ii[iindex[order][LAYER]] - s->dl);
+ else
+ layer = ii[iindex[order][LAYER]];
+ plane = ii[iindex[order][PLANE]];
+
+ /* output comment marker segment if there is any pending */
+ if (s->comment) {
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_COMMENT;
+ buf[2] = s->comment_len >> 24;
+ buf[3] = (s->comment_len >> 16) & 0xff;
+ buf[4] = (s->comment_len >> 8) & 0xff;
+ buf[5] = s->comment_len & 0xff;
+ s->data_out(buf, 6, s->file);
+ s->data_out(s->comment, s->comment_len, s->file);
+ s->comment = NULL;
+ }
+
+ output_sde(s, stripe, layer, plane);
+
+ /*
+ * When we generate a NEWLEN test case (s->yd1 > s->yd), output
+ * NEWLEN after last stripe if we have only a single
+ * resolution layer or plane (see ITU-T T.85 profile), otherwise
+ * output NEWLEN before last stripe.
+ */
+ if (s->yd1 > s->yd &&
+ (stripe == s->stripes - 1 ||
+ (stripe == s->stripes - 2 &&
+ (s->dl != s->dh || s->planes > 1)))) {
+ s->yd1 = s->yd;
+ yd = jbg_ceil_half(s->yd, s->d - s->dh);
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_NEWLEN;
+ buf[2] = yd >> 24;
+ buf[3] = (yd >> 16) & 0xff;
+ buf[4] = (yd >> 8) & 0xff;
+ buf[5] = yd & 0xff;
+ s->data_out(buf, 6, s->file);
+#ifdef DEBUG
+ fprintf(stderr, "NEWLEN: yd=%lu\n", yd);
+#endif
+ if (stripe == s->stripes - 1) {
+ buf[1] = MARKER_SDNORM;
+ s->data_out(buf, 2, s->file);
+ }
+ }
+
+ }
+
+ return;
+}
+
+
+void jbg_enc_free(struct jbg_enc_state *s)
+{
+ unsigned long stripe;
+ int layer, plane;
+
+#ifdef DEBUG
+ fprintf(stderr, "jbg_enc_free(%p)\n", (void *) s);
+#endif
+
+ /* clear buffers for SDEs */
+ if (s->sde) {
+ for (stripe = 0; stripe < s->stripes; stripe++) {
+ for (layer = 0; layer < s->d + 1; layer++) {
+ for (plane = 0; plane < s->planes; plane++)
+ if (s->sde[stripe][layer][plane] != SDE_DONE &&
+ s->sde[stripe][layer][plane] != SDE_TODO)
+ jbg_buf_free(&s->sde[stripe][layer][plane]);
+ checked_free(s->sde[stripe][layer]);
+ }
+ checked_free(s->sde[stripe]);
+ }
+ checked_free(s->sde);
+ }
+
+ /* clear free_list */
+ jbg_buf_free(&s->free_list);
+
+ /* clear memory for arithmetic encoder states */
+ checked_free(s->s);
+
+ /* clear memory for differential-layer typical prediction buffer */
+ checked_free(s->tp);
+
+ /* clear memory for adaptive template pixel offsets */
+ checked_free(s->tx);
+
+ /* clear lowres image buffers */
+ if (s->lhp[1]) {
+ for (plane = 0; plane < s->planes; plane++)
+ checked_free(s->lhp[1][plane]);
+ checked_free(s->lhp[1]);
+ }
+
+ /* clear buffer for index of highres image in lhp */
+ checked_free(s->highres);
+
+ return;
+}
+
+
+/*
+ * Convert the error codes used by jbg_dec_in() into an English ASCII string
+ */
+const char *jbg_strerror(int errnum)
+{
+ errnum >>= 4;
+ if (errnum < 0 || (unsigned) errnum >= sizeof(errmsg)/sizeof(errmsg[0]))
+ return "Unknown error code passed to jbg_strerror()";
+
+ return errmsg[errnum];
+}
+
+
+/*
+ * The constructor for a decoder
+ */
+void jbg_dec_init(struct jbg_dec_state *s)
+{
+ s->order = 0;
+ s->d = -1;
+ s->bie_len = 0;
+ s->buf_len = 0;
+ s->dppriv = NULL;
+ s->xmax = 4294967295UL;
+ s->ymax = 4294967295UL;
+ s->dmax = 256;
+ s->maxmem = 2000000000; /* no final image larger than 2 GB by default */
+ s->s = NULL;
+
+ return;
+}
+
+
+/*
+ * Specify a maximum image size for the decoder. If the JBIG file has
+ * the order bit ILEAVE, but not the bit SEQ set, then the decoder
+ * will abort to decode after the image has reached the maximal
+ * resolution layer which is still not wider than xmax or higher than
+ * ymax.
+ */
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+ unsigned long ymax)
+{
+ if (xmax > 0) s->xmax = xmax;
+ if (ymax > 0) s->ymax = ymax;
+
+ return;
+}
+
+
+/*
+ * Decode the new len PSDC bytes to which data points and add them to
+ * the current stripe. Return the number of bytes which have actually
+ * been read (this will be less than len if a marker segment was
+ * part of the data or if the final byte was 0xff, in which case
+ * this code cannot determine whether we have a marker segment).
+ */
+static size_t decode_pscd(struct jbg_dec_state *s, unsigned char *data,
+ size_t len)
+{
+ unsigned long stripe;
+ unsigned int layer, plane;
+ unsigned long hl, ll, y, hx, hy, lx, ly, hbpl, lbpl;
+ unsigned char *hp, *lp1, *lp2, *p1, *q1;
+ register unsigned long line_h1, line_h2, line_h3;
+ register unsigned long line_l1, line_l2, line_l3;
+ struct jbg_ardec_state *se;
+ unsigned long x;
+ long o;
+ unsigned a;
+ int n;
+ int pix, cx = 0, slntp, tx;
+
+ /* SDE loop variables */
+ stripe = s->ii[iindex[s->order & 7][STRIPE]];
+ layer = s->ii[iindex[s->order & 7][LAYER]];
+ plane = s->ii[iindex[s->order & 7][PLANE]];
+
+ /* forward data to arithmetic decoder */
+ se = s->s[plane] + layer - s->dl;
+ se->pscd_ptr = data;
+ se->pscd_end = data + len;
+
+ /* number of lines per stripe in highres image */
+ hl = s->l0 << layer;
+ /* number of lines per stripe in lowres image */
+ ll = hl >> 1;
+ /* current line number in highres image */
+ y = stripe * hl + s->i;
+ /* number of pixels in highres image */
+ hx = jbg_ceil_half(s->xd, s->d - layer);
+ hy = jbg_ceil_half(s->yd, s->d - layer);
+ /* number of pixels in lowres image */
+ lx = jbg_ceil_half(hx, 1);
+ ly = jbg_ceil_half(hy, 1);
+ /* bytes per line in highres and lowres image */
+ hbpl = jbg_ceil_half(hx, 3);
+ lbpl = jbg_ceil_half(lx, 3);
+ /* pointer to highres and lowres image bytes */
+ hp = s->lhp[ layer & 1][plane] + (stripe * hl + s->i) * hbpl +
+ (s->x >> 3);
+ lp2 = s->lhp[(layer-1) & 1][plane] + (stripe * ll + (s->i >> 1)) * lbpl +
+ (s->x >> 4);
+ lp1 = lp2 + lbpl;
+
+ /* restore a few local variables */
+ line_h1 = s->line_h1;
+ line_h2 = s->line_h2;
+ line_h3 = s->line_h3;
+ line_l1 = s->line_l1;
+ line_l2 = s->line_l2;
+ line_l3 = s->line_l3;
+ x = s->x;
+
+#ifdef DEBUG
+ if (s->x == 0 && s->i == 0 && s->pseudo)
+ fprintf(stderr, "decode_pscd(%p, %p, %ld): s/d/p = %2lu/%2u/%2u\n",
+ (void *) s, (void *) data, (long) len, stripe, layer, plane);
+#endif
+
+ if (s->x == 0 && s->i == 0 &&
+ (stripe == 0 || s->reset[plane][layer - s->dl]) && s->pseudo) {
+ s->tx[plane][layer - s->dl] = s->ty[plane][layer - s->dl] = 0;
+ s->lntp[plane][layer - s->dl] = 1;
+ }
+
+ if (layer == 0) {
+
+ /*
+ * Decode lowest resolution layer
+ */
+
+ for (; s->i < hl && y < hy; s->i++, y++) {
+
+ /* adaptive template changes */
+ if (x == 0 && s->pseudo)
+ for (n = 0; n < s->at_moves; n++)
+ if (s->at_line[n] == s->i) {
+ s->tx[plane][layer - s->dl] = s->at_tx[n];
+ s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+ s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+ }
+ tx = s->tx[plane][layer - s->dl];
+ assert(tx >= 0); /* i.e., tx can safely be cast to unsigned */
+
+ /* typical prediction */
+ if (s->options & JBG_TPBON && s->pseudo) {
+ slntp = arith_decode(se, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX);
+ if (slntp < 0)
+ goto leave;
+ s->lntp[plane][layer - s->dl] =
+ !(slntp ^ s->lntp[plane][layer - s->dl]);
+ if (!s->lntp[plane][layer - s->dl]) {
+ /* this line is 'typical' (i.e. identical to the previous one) */
+ p1 = hp;
+ if (s->i == 0 && (stripe == 0 || s->reset[plane][layer - s->dl]))
+ while (p1 < hp + hbpl) *p1++ = 0;
+ else {
+ q1 = hp - hbpl;
+ while (q1 < hp) *p1++ = *q1++;
+ }
+ hp += hbpl;
+ continue;
+ }
+ /* this line is 'not typical' and has to be coded completely */
+ }
+ s->pseudo = 0;
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently decoded pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 76543210 76543210 X line_h1
+ */
+
+ if (x == 0) {
+ line_h1 = line_h2 = line_h3 = 0;
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))
+ line_h2 = (long)*(hp - hbpl) << 8;
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ }
+
+ /*
+ * Another tiny JBIG standard bug:
+ *
+ * While implementing the line_h3 handling here, I discovered
+ * another problem with the ITU-T T.82(1993 E) specification.
+ * This might be a somewhat pathological case, however. The
+ * standard is unclear about how a decoder should behave in the
+ * following situation:
+ *
+ * Assume we are in layer 0 and all stripes are single lines
+ * (L0=1 allowed by table 9). We are now decoding the first (and
+ * only) line of the third stripe. Assume, the first stripe was
+ * terminated by SDRST and the second stripe was terminated by
+ * SDNORM. While decoding the only line of the third stripe with
+ * the three-line template, we need access to pixels from the
+ * previous two stripes. We know that the previous stripe
+ * terminated with SDNROM, so we access the pixel from the
+ * second stripe. But do we have to replace the pixels from the
+ * first stripe by background pixels, because this stripe ended
+ * with SDRST? The standard, especially clause 6.2.5 does never
+ * mention this case, so the behaviour is undefined here. My
+ * current implementation remembers only the marker used to
+ * terminate the previous stripe. In the above example, the
+ * pixels of the first stripe are accessed despite the fact that
+ * this stripe ended with SDRST. An alternative (only slightly
+ * more complicated) implementation would be to remember the end
+ * marker (SDNORM or SDRST) of the previous two stripes in a
+ * plane/layer and to act accordingly when accessing the two
+ * previous lines. What am I supposed to do here?
+ *
+ * As the standard is unclear about the correct behaviour in the
+ * situation of the above example, I strongly suggest to avoid
+ * the following situation while encoding data with JBIG:
+ *
+ * LRLTWO = 0, L0=1 and both SDNORM and SDRST appear in layer 0.
+ *
+ * I guess that only a very few if any encoders will switch
+ * between SDNORM and SDRST, so let us hope that this ambiguity
+ * in the standard will never cause any interoperability
+ * problems.
+ *
+ * Markus Kuhn -- 1995-04-30
+ */
+
+ /* decode line */
+ while (x < hx) {
+ if ((x & 7) == 0) {
+ if (x < hbpl * 8 - 8 &&
+ (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl]))) {
+ line_h2 |= *(hp - hbpl + 1);
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 |= *(hp - hbpl - hbpl + 1);
+ }
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ if (tx) {
+ if ((unsigned) tx > x)
+ a = 0;
+ else if (tx < 8)
+ a = ((line_h1 >> (tx - 5)) & 0x010);
+ else {
+ o = (x - tx) - (x & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(tx > 31 ||
+ a == ((line_h1 >> (tx - 5)) & 0x010));
+ pix = arith_decode(se, (((line_h2 >> 9) & 0x3e0) | a |
+ (line_h1 & 0x00f)));
+ } else
+ pix = arith_decode(se, (((line_h2 >> 9) & 0x3f0) |
+ (line_h1 & 0x00f)));
+ if (pix < 0)
+ goto leave;
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ } while ((++x & 7) && x < hx);
+ } else {
+ /* three line template */
+ do {
+ if (tx) {
+ if ((unsigned) tx > x)
+ a = 0;
+ else if (tx < 8)
+ a = ((line_h1 >> (tx - 3)) & 0x004);
+ else {
+ o = (x - tx) - (x & ~7L);
+ a = (hp[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(tx > 31 ||
+ a == ((line_h1 >> (tx - 3)) & 0x004));
+ pix = arith_decode(se, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x078) | a |
+ (line_h1 & 0x003)));
+ } else
+ pix = arith_decode(se, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x07c) |
+ (line_h1 & 0x003)));
+ if (pix < 0)
+ goto leave;
+
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ line_h3 <<= 1;
+ } while ((++x & 7) && x < hx);
+ } /* if (s->options & JBG_LRLTWO) */
+ *hp++ = line_h1;
+ } /* while */
+ *(hp - 1) <<= hbpl * 8 - hx;
+ x = 0;
+ s->pseudo = 1;
+ } /* for (i = ...) */
+
+ } else {
+
+ /*
+ * Decode differential layer
+ */
+
+ for (; s->i < hl && y < hy; s->i++, y++) {
+
+ /* adaptive template changes */
+ if (x == 0)
+ for (n = 0; n < s->at_moves; n++)
+ if (s->at_line[n] == s->i) {
+ s->tx[plane][layer - s->dl] = s->at_tx[n];
+ s->ty[plane][layer - s->dl] = s->at_ty[n];
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%lu, tx=%d, ty=%d.\n", s->i,
+ s->tx[plane][layer - s->dl], s->ty[plane][layer - s->dl]);
+#endif
+ }
+ tx = s->tx[plane][layer - s->dl];
+
+ /* handle lower border of low-resolution image */
+ if ((s->i >> 1) >= ll - 1 || (y >> 1) >= ly - 1)
+ lp1 = lp2;
+
+ /* typical prediction */
+ if ((s->options & JBG_TPDON) && s->pseudo) {
+ if ((s->lntp[plane][layer - s->dl] = arith_decode(se, TPDCX)) < 0)
+ goto leave;
+ }
+ s->pseudo = 0;
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the high resolution neighbour pixels of the currently
+ * decoded highres pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 76543210 76543210 X line_h1
+ *
+ * Layout of the variables line_l1, line_l2, line_l3, which contain
+ * the low resolution pixels near the currently decoded pixel as bits.
+ * The lowres pixel in which the currently coded highres pixel is
+ * located is marked as Y:
+ *
+ * 76543210 76543210 76543210 76543210 line_l3
+ * 76543210 76543210 Y6543210 76543210 line_l2
+ * 76543210 76543210 76543210 76543210 line_l1
+ */
+
+
+ if (x == 0) {
+ line_h1 = line_h2 = line_h3 = line_l1 = line_l2 = line_l3 = 0;
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+ line_h2 = (long)*(hp - hbpl) << 8;
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 = (long)*(hp - hbpl - hbpl) << 8;
+ }
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer-s->dl]))
+ line_l3 = (long)*(lp2 - lbpl) << 8;
+ line_l2 = (long)*lp2 << 8;
+ line_l1 = (long)*lp1 << 8;
+ }
+
+ /* decode line */
+ while (x < hx) {
+ if ((x & 15) == 0)
+ if ((x >> 1) < lbpl * 8 - 8) {
+ line_l1 |= *(lp1 + 1);
+ line_l2 |= *(lp2 + 1);
+ if (s->i > 1 ||
+ (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_l3 |= *(lp2 - lbpl + 1);
+ }
+ do {
+
+ assert(hp - (s->lhp[ layer &1][plane] + (stripe * hl + s->i)
+ * hbpl) == (ptrdiff_t) x >> 3);
+ assert(lp2 - (s->lhp[(layer-1) &1][plane] + (stripe * ll + (s->i>>1))
+ * lbpl) == (ptrdiff_t) x >> 4);
+
+ if ((x & 7) == 0)
+ if (x < hbpl * 8 - 8) {
+ if (s->i > 0 || (y > 0 && !s->reset[plane][layer - s->dl])) {
+ line_h2 |= *(hp + 1 - hbpl);
+ if (s->i > 1 || (y > 1 && !s->reset[plane][layer - s->dl]))
+ line_h3 |= *(hp + 1 - hbpl - hbpl);
+ }
+ }
+ do {
+ if (!s->lntp[plane][layer - s->dl])
+ cx = (((line_l3 >> 14) & 0x007) |
+ ((line_l2 >> 11) & 0x038) |
+ ((line_l1 >> 8) & 0x1c0));
+ if (!s->lntp[plane][layer - s->dl] &&
+ (cx == 0x000 || cx == 0x1ff)) {
+ /* pixels are typical and have not to be decoded */
+ do {
+ line_h1 = (line_h1 << 1) | (cx & 1);
+ } while ((++x & 1) && x < hx);
+ line_h2 <<= 2; line_h3 <<= 2;
+ } else
+ do {
+
+ /* deterministic prediction */
+ if (s->options & JBG_DPON)
+ if ((y & 1) == 0)
+ if ((x & 1) == 0)
+ /* phase 0 */
+ pix = s->dppriv[((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x010) |
+ ((line_h2 >> 9) & 0x0e0)];
+ else
+ /* phase 1 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x030) |
+ ((line_h2 >> 9) & 0x1c0)) + 256];
+ else
+ if ((x & 1) == 0)
+ /* phase 2 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x010) |
+ ((line_h2 >> 9) & 0x0e0) |
+ ((line_h3 >> 6) & 0x700)) + 768];
+ else
+ /* phase 3 */
+ pix = s->dppriv[(((line_l3 >> 15) & 0x003) |
+ ((line_l2 >> 13) & 0x00c) |
+ ((line_h1 << 4) & 0x030) |
+ ((line_h2 >> 9) & 0x1c0) |
+ ((line_h3 >> 6) & 0xe00)) + 2816];
+ else
+ pix = 2;
+
+ if (pix & 2) {
+ if (tx)
+ cx = ((line_h1 & 0x003) |
+ (((line_h1 << 2) >> (tx - 3)) & 0x010) |
+ ((line_h2 >> 12) & 0x00c) |
+ ((line_h3 >> 10) & 0x020));
+ else
+ cx = ((line_h1 & 0x003) |
+ ((line_h2 >> 12) & 0x01c) |
+ ((line_h3 >> 10) & 0x020));
+ if (x & 1)
+ cx |= (((line_l2 >> 8) & 0x0c0) |
+ ((line_l1 >> 6) & 0x300)) | (1UL << 10);
+ else
+ cx |= (((line_l2 >> 9) & 0x0c0) |
+ ((line_l1 >> 7) & 0x300));
+ cx |= (y & 1) << 11;
+
+ pix = arith_decode(se, cx);
+ if (pix < 0)
+ goto leave;
+ }
+
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ line_h3 <<= 1;
+
+ } while ((++x & 1) && x < hx);
+ line_l1 <<= 1; line_l2 <<= 1; line_l3 <<= 1;
+ } while ((x & 7) && x < hx);
+ *hp++ = line_h1;
+ } while ((x & 15) && x < hx);
+ ++lp1;
+ ++lp2;
+ } /* while */
+ x = 0;
+
+ *(hp - 1) <<= hbpl * 8 - hx;
+ if ((s->i & 1) == 0) {
+ /* low resolution pixels are used twice */
+ lp1 -= lbpl;
+ lp2 -= lbpl;
+ } else
+ s->pseudo = 1;
+
+ } /* for (i = ...) */
+
+ }
+
+ leave:
+
+ /* save a few local variables */
+ s->line_h1 = line_h1;
+ s->line_h2 = line_h2;
+ s->line_h3 = line_h3;
+ s->line_l1 = line_l1;
+ s->line_l2 = line_l2;
+ s->line_l3 = line_l3;
+ s->x = x;
+
+ return se->pscd_ptr - data;
+}
+
+
+/*
+ * Provide to the decoder a new BIE fragment of len bytes starting at data.
+ *
+ * Unless cnt is NULL, *cnt will contain the number of actually read bytes
+ * on return.
+ *
+ * Normal return values:
+ *
+ * JBG_EAGAIN All data bytes provided so far have been processed
+ * (*cnt == len) but the end of the data stream has
+ * not yet been recognized. Call the function again
+ * with additional BIE bytes.
+ * JBG_EOK The function has reached the end of a and
+ * a full image has been decoded. The function can
+ * be called again with data from the next BIE, if
+ * there exists one, in order to get to a higher
+ * resolution layer. The remaining len - *cnt bytes
+ * of the previous data block will then have to passed
+ * to this function again if len > *cnt.
+ * JBG_EOK_INTR Parsing the BIE has been interrupted as had been
+ * requested by a jbg_dec_maxsize() specification.
+ * This function can be called again with the
+ * rest of the BIE to continue the decoding process.
+ * The remaining len - *cnt bytes of the previous
+ * data block will then have to be passed to this
+ * function again if len > *cnt.
+ *
+ * Any other return value indicates that the decoding process was
+ * aborted by a serious problem and the only function you can then
+ * still call is jbg_dec_free() in order to remove the mess, and
+ * jbg85_strerror() to find out what to tell the user. (Looking at the
+ * least significant bits of the return value will provide additional
+ * information by identifying which test exactly has failed.)
+ */
+int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt)
+{
+ int i, j, required_length;
+ unsigned long x, y;
+ unsigned long is[3], ie[3];
+ size_t dummy_cnt;
+ unsigned char *dppriv;
+
+ if (!cnt) cnt = &dummy_cnt;
+ *cnt = 0;
+ if (len < 1) return JBG_EAGAIN;
+
+ /* read in 20-byte BIH */
+ if (s->bie_len < 20) {
+ while (s->bie_len < 20 && *cnt < len)
+ s->buffer[s->bie_len++] = data[(*cnt)++];
+ if (s->bie_len < 20)
+ return JBG_EAGAIN;
+ /* test whether this looks like a valid JBIG header at all */
+ if (s->buffer[1] < s->buffer[0])
+ return JBG_EINVAL | 1;
+ if (s->buffer[3] != 0) return JBG_EINVAL | 2; /* padding != 0 */
+ if ((s->buffer[18] & 0xf0) != 0) return JBG_EINVAL | 3; /* padding != 0 */
+ if ((s->buffer[19] & 0x80) != 0) return JBG_EINVAL | 4; /* padding != 0 */
+ if (s->buffer[0] != s->d + 1)
+ return JBG_ENOCONT | 1;
+ s->dl = s->buffer[0];
+ s->d = s->buffer[1];
+ if (s->dl == 0)
+ s->planes = s->buffer[2];
+ else
+ if (s->planes != s->buffer[2])
+ return JBG_ENOCONT | 2;
+ x = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) |
+ ((long) s->buffer[ 6] << 8) | (long) s->buffer[ 7]);
+ y = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) |
+ ((long) s->buffer[10] << 8) | (long) s->buffer[11]);
+ if (s->dl != 0 && ((s->xd << (s->d - s->dl + 1)) != x &&
+ (s->yd << (s->d - s->dl + 1)) != y))
+ return JBG_ENOCONT | 3;
+ s->xd = x;
+ s->yd = y;
+ s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) |
+ ((long) s->buffer[14] << 8) | (long) s->buffer[15]);
+ /* ITU-T T.85 trick not directly supported by decoder; for full
+ * T.85 compatibility with respect to all NEWLEN marker scenarios,
+ * preprocess BIE with jbg_newlen() before passing it to the decoder,
+ * or consider using the decoder found in jbig85.c instead. */
+ if (s->yd == 0xffffffff)
+ return JBG_EIMPL | 1;
+ if (!s->planes) return JBG_EINVAL | 5;
+ if (!s->xd) return JBG_EINVAL | 6;
+ if (!s->yd) return JBG_EINVAL | 7;
+ if (!s->l0) return JBG_EINVAL | 8;
+ /* prevent uint32 overflow: s->l0 * 2 ^ s->d < 2 ^ 32 */
+ if (s->d > 31)
+ return JBG_EIMPL | 2;
+ if ((s->d != 0 && s->l0 >= (1UL << (32 - s->d))))
+ return JBG_EIMPL | 3;
+ s->mx = s->buffer[16];
+ if (s->mx > 127)
+ return JBG_EINVAL | 9;
+ s->my = s->buffer[17];
+#if 0
+ if (s->my > 0)
+ return JBG_EIMPL | 4;
+#endif
+ s->order = s->buffer[18];
+ if (iindex[s->order & 7][0] < 0)
+ return JBG_EINVAL | 10;
+ /* HITOLO and SEQ currently not yet implemented */
+ if (s->dl != s->d && (s->order & JBG_HITOLO || s->order & JBG_SEQ))
+ return JBG_EIMPL | 5;
+ s->options = s->buffer[19];
+
+ /* will the final image require more bytes than permitted by s->maxmem? */
+ if (s->maxmem / s->planes / s->yd / jbg_ceil_half(s->xd, 3) == 0)
+ return JBG_ENOMEM; /* increase s->maxmem if needed */
+
+ /* calculate number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+
+ /* some initialization */
+ s->ii[iindex[s->order & 7][STRIPE]] = 0;
+ s->ii[iindex[s->order & 7][LAYER]] = s->dl;
+ s->ii[iindex[s->order & 7][PLANE]] = 0;
+ if (s->dl == 0) {
+ s->s = (struct jbg_ardec_state **)
+ checked_malloc(s->planes, sizeof(struct jbg_ardec_state *));
+ s->tx = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->ty = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->reset = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->lntp = (int **) checked_malloc(s->planes, sizeof(int *));
+ s->lhp[0] = (unsigned char **)
+ checked_malloc(s->planes, sizeof(unsigned char *));
+ s->lhp[1] = (unsigned char **)
+ checked_malloc(s->planes, sizeof(unsigned char *));
+ for (i = 0; i < s->planes; i++) {
+ s->s[i] = (struct jbg_ardec_state *)
+ checked_malloc(s->d - s->dl + 1, sizeof(struct jbg_ardec_state));
+ s->tx[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->ty[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->reset[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->lntp[i] = (int *) checked_malloc(s->d - s->dl + 1, sizeof(int));
+ s->lhp[ s->d & 1][i] = (unsigned char *)
+ checked_malloc(s->yd, jbg_ceil_half(s->xd, 3));
+ s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+ checked_malloc(jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+ }
+ } else {
+ for (i = 0; i < s->planes; i++) {
+ s->s[i] = (struct jbg_ardec_state *)
+ checked_realloc(s->s[i], s->d - s->dl + 1,
+ sizeof(struct jbg_ardec_state));
+ s->tx[i] = (int *) checked_realloc(s->tx[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->ty[i] = (int *) checked_realloc(s->ty[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->reset[i] = (int *) checked_realloc(s->reset[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->lntp[i] = (int *) checked_realloc(s->lntp[i],
+ s->d - s->dl + 1, sizeof(int));
+ s->lhp[ s->d & 1][i] = (unsigned char *)
+ checked_realloc(s->lhp[ s->d & 1][i],
+ s->yd, jbg_ceil_half(s->xd, 3));
+ s->lhp[(s->d-1) & 1][i] = (unsigned char *)
+ checked_realloc(s->lhp[(s->d-1) & 1][i],
+ jbg_ceil_half(s->yd, 1), jbg_ceil_half(s->xd, 1+3));
+ }
+ }
+ for (i = 0; i < s->planes; i++)
+ for (j = 0; j <= s->d - s->dl; j++)
+ arith_decode_init(s->s[i] + j, 0);
+ if (s->dl == 0 || (s->options & JBG_DPON && !(s->options & JBG_DPPRIV)))
+ s->dppriv = jbg_dptable;
+ s->comment_skip = 0;
+ s->buf_len = 0;
+ s->x = 0;
+ s->i = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+ }
+
+ /* read in DPTABLE */
+ if (s->bie_len < 20 + 1728 &&
+ (s->options & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST)) ==
+ (JBG_DPON | JBG_DPPRIV)) {
+ assert(s->bie_len >= 20);
+ if (!s->dppriv || s->dppriv == jbg_dptable)
+ s->dppriv = (char *) checked_malloc(1728, sizeof(char));
+ while (s->bie_len < 20 + 1728 && *cnt < len)
+ s->dppriv[s->bie_len++ - 20] = data[(*cnt)++];
+ if (s->bie_len < 20 + 1728)
+ return JBG_EAGAIN;
+ dppriv = (unsigned char *) s->dppriv;
+ s->dppriv = (char *) checked_malloc(6912, sizeof(char));
+ jbg_dppriv2int(s->dppriv, dppriv);
+ checked_free(dppriv);
+ }
+
+ /*
+ * BID processing loop
+ */
+
+ while (*cnt < len) {
+
+ /* process floating marker segments */
+
+ /* skip COMMENT contents */
+ if (s->comment_skip) {
+ if (s->comment_skip <= len - *cnt) {
+ *cnt += s->comment_skip;
+ s->comment_skip = 0;
+ } else {
+ s->comment_skip -= len - *cnt;
+ *cnt = len;
+ }
+ continue;
+ }
+
+ /* load complete marker segments into s->buffer for processing */
+ if (s->buf_len > 0) {
+ assert(s->buffer[0] == MARKER_ESC);
+ while (s->buf_len < 2 && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < 2) continue;
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT: required_length = 6; break;
+ case MARKER_ATMOVE: required_length = 8; break;
+ case MARKER_NEWLEN: required_length = 6; break;
+ case MARKER_ABORT:
+ case MARKER_SDNORM:
+ case MARKER_SDRST: required_length = 2; break;
+ case MARKER_STUFF:
+ /* forward stuffed 0xff to arithmetic decoder */
+ s->buf_len = 0;
+ decode_pscd(s, s->buffer, 2);
+ continue;
+ default:
+ return JBG_EMARKER;
+ }
+ while (s->buf_len < required_length && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < required_length) continue;
+ /* now the buffer is filled with exactly one marker segment */
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT:
+ s->comment_skip =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ break;
+ case MARKER_ATMOVE:
+ if (s->at_moves < JBG_ATMOVES_MAX) {
+ s->at_line[s->at_moves] =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ s->at_tx[s->at_moves] = (signed char) s->buffer[6];
+ s->at_ty[s->at_moves] = s->buffer[7];
+ if (s->at_tx[s->at_moves] < - (int) s->mx ||
+ s->at_tx[s->at_moves] > (int) s->mx ||
+ s->at_ty[s->at_moves] > (int) s->my ||
+ (s->at_ty[s->at_moves] == 0 && s->at_tx[s->at_moves] < 0))
+ return JBG_EINVAL | 11;
+ if (s->at_ty[s->at_moves] != 0)
+ return JBG_EIMPL | 6;
+ s->at_moves++;
+ } else
+ return JBG_EIMPL | 7; /* more than JBG_ATMOVES_MAX ATMOVES */
+ break;
+ case MARKER_NEWLEN:
+ y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ if (y > s->yd) return JBG_EINVAL | 12;
+ if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13;
+ s->yd = y;
+ /* calculate again number of stripes that will be required */
+ s->stripes = jbg_stripes(s->l0, s->yd, s->d);
+ break;
+ case MARKER_ABORT:
+ return JBG_EABORT;
+
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ /* decode final pixels based on trailing zero bytes */
+ decode_pscd(s, s->buffer, 2);
+
+ arith_decode_init(s->s[s->ii[iindex[s->order & 7][PLANE]]] +
+ s->ii[iindex[s->order & 7][LAYER]] - s->dl,
+ s->ii[iindex[s->order & 7][STRIPE]] != s->stripes - 1
+ && s->buffer[1] != MARKER_SDRST);
+
+ s->reset[s->ii[iindex[s->order & 7][PLANE]]]
+ [s->ii[iindex[s->order & 7][LAYER]] - s->dl] =
+ (s->buffer[1] == MARKER_SDRST);
+
+ /* prepare for next SDE */
+ s->x = 0;
+ s->i = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+
+ /* increment layer/stripe/plane loop variables */
+ /* start and end value for each loop: */
+ is[iindex[s->order & 7][STRIPE]] = 0;
+ ie[iindex[s->order & 7][STRIPE]] = s->stripes - 1;
+ is[iindex[s->order & 7][LAYER]] = s->dl;
+ ie[iindex[s->order & 7][LAYER]] = s->d;
+ is[iindex[s->order & 7][PLANE]] = 0;
+ ie[iindex[s->order & 7][PLANE]] = s->planes - 1;
+ i = 2; /* index to innermost loop */
+ do {
+ j = 0; /* carry flag */
+ if (++s->ii[i] > ie[i]) {
+ /* handling overflow of loop variable */
+ j = 1;
+ if (i > 0)
+ s->ii[i] = is[i];
+ }
+ } while (--i >= 0 && j);
+
+ s->buf_len = 0;
+
+ /* check whether this have been all SDEs */
+ if (j) {
+#ifdef DEBUG
+ fprintf(stderr, "This was the final SDE in this BIE, "
+ "%ld bytes left.\n", (long) (len - *cnt));
+#endif
+ s->bie_len = 0;
+ return JBG_EOK;
+ }
+
+ /* check whether we have to abort because of xmax/ymax */
+ if (iindex[s->order & 7][LAYER] == 0 && i < 0) {
+ /* LAYER is the outermost loop and we have just gone to next layer */
+ if (jbg_ceil_half(s->xd, s->d - s->ii[0]) > s->xmax ||
+ jbg_ceil_half(s->yd, s->d - s->ii[0]) > s->ymax) {
+ s->xmax = 4294967295UL;
+ s->ymax = 4294967295UL;
+ return JBG_EOK_INTR;
+ }
+ if (s->ii[0] > (unsigned long) s->dmax) {
+ s->dmax = 256;
+ return JBG_EOK_INTR;
+ }
+ }
+
+ break;
+ }
+ s->buf_len = 0;
+
+ } else if (data[*cnt] == MARKER_ESC)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+
+ else {
+
+ /* we have found PSCD bytes */
+ *cnt += decode_pscd(s, data + *cnt, len - *cnt);
+ if (*cnt < len && data[*cnt] != 0xff) {
+#ifdef DEBUG
+ fprintf(stderr, "PSCD was longer than expected, unread bytes "
+ "%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1],
+ data[*cnt+2], data[*cnt+3]);
+#endif
+ return JBG_EINVAL | 14;
+ }
+
+ }
+ } /* of BID processing loop 'while (*cnt < len) ...' */
+
+ return JBG_EAGAIN;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the width of the image. Returns 0 if
+ * there is no image available yet.
+ */
+unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return 0;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return 0;
+ else
+ return jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1));
+ }
+
+ return s->xd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to find out the height of the image. Returns 0 if
+ * there is no image available yet.
+ */
+unsigned long jbg_dec_getheight(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return 0;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return 0;
+ else
+ return jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+ }
+
+ return s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call this
+ * function in order to get a pointer to the image. Returns NULL if
+ * there is no image available yet.
+ */
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane)
+{
+ if (s->d < 0)
+ return NULL;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return NULL;
+ else
+ return s->lhp[(s->ii[0] - 1) & 1][plane];
+ }
+
+ return s->lhp[s->d & 1][plane];
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size in bytes of one
+ * bitplane of the image.
+ */
+unsigned long jbg_dec_getsize(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return 0;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return 0;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1) + 3) * /* overflow risk? */
+ jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1));
+ }
+
+ return jbg_ceil_half(s->xd, 3) * s->yd;
+}
+
+
+/*
+ * After jbg_dec_in() returned JBG_EOK or JBG_EOK_INTR, you can call
+ * this function in order to find out the size of the image that you
+ * can retrieve with jbg_merge_planes().
+ */
+unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s)
+{
+ if (s->d < 0)
+ return 0;
+ if (iindex[s->order & 7][LAYER] == 0) {
+ if (s->ii[0] < 1)
+ return 0;
+ else
+ return
+ jbg_ceil_half(s->xd, s->d - (s->ii[0] - 1)) * /* overflow risk? */
+ jbg_ceil_half(s->yd, s->d - (s->ii[0] - 1)) *
+ ((s->planes + 7) / 8);
+ }
+
+ return s->xd * s->yd * ((s->planes + 7) / 8);
+}
+
+
+/*
+ * The destructor function which releases any resources obtained by the
+ * other decoder functions.
+ */
+void jbg_dec_free(struct jbg_dec_state *s)
+{
+ int i;
+
+ if (s->d < 0 || s->s == NULL)
+ return;
+ s->d = -2;
+
+ for (i = 0; i < s->planes; i++) {
+ checked_free(s->s[i]);
+ checked_free(s->tx[i]);
+ checked_free(s->ty[i]);
+ checked_free(s->reset[i]);
+ checked_free(s->lntp[i]);
+ checked_free(s->lhp[0][i]);
+ checked_free(s->lhp[1][i]);
+ }
+
+ checked_free(s->s);
+ checked_free(s->tx);
+ checked_free(s->ty);
+ checked_free(s->reset);
+ checked_free(s->lntp);
+ checked_free(s->lhp[0]);
+ checked_free(s->lhp[1]);
+ if (s->dppriv && s->dppriv != jbg_dptable)
+ checked_free(s->dppriv);
+
+ s->s = NULL;
+
+ return;
+}
+
+
+/*
+ * Split bigendian integer pixel field into separate bit planes. In the
+ * src array, every pixel is represented by a ((has_planes + 7) / 8) byte
+ * long word, most significant byte first. While has_planes describes
+ * the number of used bits per pixel in the source image, encode_plane
+ * is the number of most significant bits among those that we
+ * actually transfer to dest.
+ */
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+ int encode_planes,
+ const unsigned char *src, unsigned char **dest,
+ int use_graycode)
+{
+ unsigned long bpl = jbg_ceil_half(x, 3); /* bytes per line in dest plane */
+ unsigned long line, i;
+ unsigned k = 8;
+ int p;
+ unsigned prev; /* previous *src byte shifted by 8 bit to the left */
+ register int bits, msb = has_planes - 1;
+ int bitno;
+
+ /* sanity checks */
+ if (encode_planes > has_planes)
+ encode_planes = has_planes;
+ use_graycode = use_graycode != 0 && encode_planes > 1;
+
+ for (p = 0; p < encode_planes; p++)
+ memset(dest[p], 0, bpl * y);
+
+ for (line = 0; line < y; line++) { /* lines loop */
+ for (i = 0; i * 8 < x; i++) { /* dest bytes loop */
+ for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */
+ prev = 0;
+ for (p = 0; p < encode_planes; p++) { /* bit planes loop */
+ /* calculate which bit in *src do we want */
+ bitno = (msb - p) & 7;
+ /* put this bit with its left neighbor right adjusted into bits */
+ bits = (prev | *src) >> bitno;
+ /* go to next *src byte, but keep old */
+ if (bitno == 0)
+ prev = *src++ << 8;
+ /* make space for inserting new bit */
+ dest[p][bpl * line + i] <<= 1;
+ /* insert bit, if requested apply Gray encoding */
+ dest[p][bpl * line + i] |= (bits ^ (use_graycode & (bits>>1))) & 1;
+ /*
+ * Theorem: Let b(n),...,b(1),b(0) be the digits of a
+ * binary word and let g(n),...,g(1),g(0) be the digits of the
+ * corresponding Gray code word, then g(i) = b(i) xor b(i+1).
+ */
+ }
+ /* skip unused *src bytes */
+ for (;p < has_planes; p++)
+ if (((msb - p) & 7) == 0)
+ src++;
+ }
+ }
+ for (p = 0; p < encode_planes; p++) /* right padding loop */
+ dest[p][bpl * (line + 1) - 1] <<= 8 - k;
+ }
+
+ return;
+}
+
+/*
+ * Merge the separate bit planes decoded by the JBIG decoder into an
+ * integer pixel field. This is essentially the counterpart to
+ * jbg_split_planes().
+ */
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file), void *file)
+{
+#define BUFLEN 4096
+ unsigned long bpl, line, i;
+ unsigned k = 8;
+ int p;
+ unsigned char buf[BUFLEN];
+ unsigned char *bp = buf;
+ unsigned char **src;
+ unsigned long x, y;
+ unsigned v;
+
+ /* sanity check */
+ use_graycode = use_graycode != 0;
+
+ x = jbg_dec_getwidth(s);
+ y = jbg_dec_getheight(s);
+ if (x == 0 || y == 0)
+ return;
+ bpl = jbg_ceil_half(x, 3); /* bytes per line in src plane */
+
+ if (iindex[s->order & 7][LAYER] == 0)
+ if (s->ii[0] < 1)
+ return;
+ else
+ src = s->lhp[(s->ii[0] - 1) & 1];
+ else
+ src = s->lhp[s->d & 1];
+
+ for (line = 0; line < y; line++) { /* lines loop */
+ for (i = 0; i * 8 < x; i++) { /* src bytes loop */
+ for (k = 0; k < 8 && i * 8 + k < x; k++) { /* pixel loop */
+ v = 0;
+ for (p = 0; p < s->planes;) { /* dest bytes loop */
+ do {
+ v = (v << 1) |
+ (((src[p][bpl * line + i] >> (7 - k)) & 1) ^
+ (use_graycode & v));
+ } while ((s->planes - ++p) & 7);
+ *bp++ = v;
+ if (bp - buf == BUFLEN) {
+ data_out(buf, BUFLEN, file);
+ bp = buf;
+ }
+ }
+ }
+ }
+ }
+
+ if (bp - buf > 0)
+ data_out(buf, bp - buf, file);
+
+ return;
+}
+
+
+/*
+ * Given a pointer p to the first byte of either a marker segment or a
+ * PSCD, as well as the length len of the remaining data, return
+ * either the pointer to the first byte of the next marker segment or
+ * PSCD, or p+len if this was the last one, or NULL if some error was
+ * encountered. Possible errors are:
+ *
+ * - not enough bytes left for complete marker segment
+ * - no marker segment terminates the PSCD
+ * - unknown marker code encountered
+ *
+ */
+unsigned char *jbg_next_pscdms(unsigned char *p, size_t len)
+{
+ unsigned char *pp;
+ unsigned long l;
+
+ if (len < 2)
+ return NULL; /* not enough bytes left for complete marker segment */
+
+ if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) {
+ do {
+ while (p[0] == MARKER_ESC && p[1] == MARKER_STUFF) {
+ p += 2;
+ len -= 2;
+ if (len < 2)
+ return NULL; /* not enough bytes left for complete marker segment */
+ }
+ assert(len >= 2);
+ pp = (unsigned char *) memchr(p, MARKER_ESC, len - 1);
+ if (!pp)
+ return NULL; /* no marker segment terminates the PSCD */
+ l = pp - p;
+ assert(l < len);
+ p += l;
+ len -= l;
+ } while (p[1] == MARKER_STUFF);
+ } else {
+ switch (p[1]) {
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ case MARKER_ABORT:
+ return p + 2;
+ case MARKER_NEWLEN:
+ if (len < 6)
+ return NULL; /* not enough bytes left for complete marker segment */
+ return p + 6;
+ case MARKER_ATMOVE:
+ if (len < 8)
+ return NULL; /* not enough bytes left for complete marker segment */
+ return p + 8;
+ case MARKER_COMMENT:
+ if (len < 6)
+ return NULL; /* not enough bytes left for complete marker segment */
+ l = (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]);
+ if (len - 6 < l)
+ return NULL; /* not enough bytes left for complete marker segment */
+ return p + 6 + l;
+ default:
+ /* unknown marker sequence encountered */
+ return NULL;
+ }
+ }
+
+ return p;
+}
+
+
+/*
+ * Scan a complete BIE for a NEWLEN marker segment, then read the new
+ * YD value found in it and use it to overwrite the one in the BIE
+ * header. Use this procedure if a BIE initially declares an
+ * unreasonably high provisional YD value (e.g., 0xffffffff) or
+ * depends on the fact that section 6.2.6.2 of ITU-T T.82 says that a
+ * NEWLEN marker segment "could refer to a line in the immediately
+ * preceding stripe due to an unexpected termination of the image or
+ * the use of only such stripe". ITU-T.85 explicitely suggests the
+ * use of this for fax machines that start transmission before having
+ * encountered the end of the page. None of this is necessary for
+ * BIEs produced by JBIG-KIT, which normally does not use NEWLEN.
+ */
+int jbg_newlen(unsigned char *bie, size_t len)
+{
+ unsigned char *p = bie + 20;
+ int i;
+ unsigned long y, yn;
+
+ if (len < 20)
+ return JBG_EAGAIN;
+ if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST))
+ == (JBG_DPON | JBG_DPPRIV))
+ p += 1728; /* skip DPTABLE */
+ if (p >= bie + len)
+ return JBG_EAGAIN;
+
+ while ((p = jbg_next_pscdms(p, len - (p - bie)))) {
+ if (p == bie + len)
+ return JBG_EOK;
+ else if (p[0] == MARKER_ESC)
+ switch (p[1]) {
+ case MARKER_NEWLEN:
+ if (p + 5 >= bie + len)
+ return JBG_EAGAIN;
+ y = (((long) bie[ 8] << 24) | ((long) bie[ 9] << 16) |
+ ((long) bie[10] << 8) | (long) bie[11]);
+ yn = (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]);
+ if (yn > y) return JBG_EINVAL | 12;
+ /* overwrite YD in BIH with YD from NEWLEN */
+ for (i = 0; i < 4; i++) {
+ bie[8+i] = p[2+i];
+ }
+ return JBG_EOK;
+ case MARKER_ABORT:
+ return JBG_EABORT;
+ }
+ }
+ return JBG_EINVAL | 0;
+}
diff --git a/thirdparty/jbigkit/libjbig/jbig.h b/thirdparty/jbigkit/libjbig/jbig.h
new file mode 100644
index 000000000..2577399a6
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig.h
@@ -0,0 +1,235 @@
+/*
+ * Header file for the portable JBIG compression library
+ *
+ * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#ifndef JBG_H
+#define JBG_H
+
+#include
+#include "jbig_ar.h"
+
+/*
+ * JBIG-KIT version number
+ */
+
+#define JBG_VERSION "2.1"
+#define JBG_VERSION_MAJOR 2
+#define JBG_VERSION_MINOR 1
+
+/*
+ * JBIG-KIT licence agreement reference code:
+ * If you use JBIG-KIT under a commercial licence, please replace
+ * below the letters GPL with the reference code that you received
+ * with your licence agreement. (This code is typically a letter "A"
+ * followed by four decimal digits, e.g. "A1234".)
+ */
+
+#define JBG_LICENCE "GPL"
+
+/*
+ * Buffer block for SDEs which are temporarily stored by encoder
+ */
+
+#define JBG_BUFSIZE 4000
+
+struct jbg_buf {
+ unsigned char d[JBG_BUFSIZE]; /* one block of a buffer list */
+ int len; /* length of the data in this block */
+ struct jbg_buf *next; /* pointer to next block */
+ struct jbg_buf *previous; /* pointer to previous block *
+ * (unused in freelist) */
+ struct jbg_buf *last; /* only used in list head: final block of list */
+ struct jbg_buf **free_list; /* pointer to pointer to head of free list */
+};
+
+/*
+ * Maximum number of ATMOVEs per stripe that decoder can handle
+ */
+
+#define JBG_ATMOVES_MAX 64
+
+/*
+ * Option and order flags
+ */
+
+#define JBG_HITOLO 0x08
+#define JBG_SEQ 0x04
+#define JBG_ILEAVE 0x02
+#define JBG_SMID 0x01
+
+#define JBG_LRLTWO 0x40
+#define JBG_VLENGTH 0x20
+#define JBG_TPDON 0x10
+#define JBG_TPBON 0x08
+#define JBG_DPON 0x04
+#define JBG_DPPRIV 0x02
+#define JBG_DPLAST 0x01
+
+/* encoding options that will not be indicated in the header */
+
+#define JBG_DELAY_AT 0x100 /* Delay ATMOVE until the first line of the next
+ * stripe. Option available for compatibility
+ * with conformance test example in clause 7.2. */
+
+#define JBG_SDRST 0x200 /* Use SDRST instead of SDNORM. This option is
+ * there for anyone who needs to generate
+ * test data that covers the SDRST cases. */
+
+/*
+ * Possible error code return values
+ */
+
+#define JBG_EOK (0 << 4)
+#define JBG_EOK_INTR (1 << 4)
+#define JBG_EAGAIN (2 << 4)
+#define JBG_ENOMEM (3 << 4)
+#define JBG_EABORT (4 << 4)
+#define JBG_EMARKER (5 << 4)
+#define JBG_EINVAL (6 << 4)
+#define JBG_EIMPL (7 << 4)
+#define JBG_ENOCONT (8 << 4)
+
+/*
+ * Status of a JBIG encoder
+ */
+
+struct jbg_enc_state {
+ int d; /* resolution layer of the input image */
+ unsigned long xd, yd; /* size of the input image (resolution layer d) */
+ unsigned long yd1; /* BIH announced height of image, use yd1 != yd to
+ emulate T.85-style NEWLEN height updates for tests */
+ int planes; /* number of different bitmap planes */
+ int dl; /* lowest resolution layer in the next BIE */
+ int dh; /* highest resolution layer in the next BIE */
+ unsigned long l0; /* number of lines per stripe at lowest *
+ * resolution layer 0 */
+ unsigned long stripes; /* number of stripes required (determ. by l0) */
+ unsigned char **lhp[2]; /* pointers to lower/higher resolution images */
+ int *highres; /* index [plane] of highres image in lhp[] */
+ int order; /* SDE ordering parameters */
+ int options; /* encoding parameters */
+ unsigned mx, my; /* maximum ATMOVE window size */
+ int *tx; /* array [plane] with x-offset of adaptive template pixel */
+ char *dppriv; /* optional private deterministic prediction table */
+ char *res_tab; /* table for the resolution reduction algorithm */
+ struct jbg_buf ****sde; /* array [stripe][layer][plane] pointers to *
+ * buffers for stored SDEs */
+ struct jbg_arenc_state *s; /* array [planes] for arithm. encoder status */
+ struct jbg_buf *free_list; /* list of currently unused SDE block buffers */
+ void (*data_out)(unsigned char *start, size_t len, void *file);
+ /* data write callback */
+ void *file; /* parameter passed to data_out() */
+ char *tp; /* buffer for temp. values used by diff. typical prediction */
+ unsigned char *comment; /* content of comment marker segment to be added
+ at next opportunity (will be reset to NULL
+ as soon as comment has been written) */
+ unsigned long comment_len; /* length of data pointed to by comment */
+};
+
+
+/*
+ * Status of a JBIG decoder
+ */
+
+struct jbg_dec_state {
+ /* data from BIH */
+ int d; /* resolution layer of the full image */
+ int dl; /* first resolution layer in this BIE */
+ unsigned long xd, yd; /* size of the full image (resolution layer d) */
+ int planes; /* number of different bitmap planes */
+ unsigned long l0; /* number of lines per stripe at lowest *
+ * resolution layer 0 */
+ unsigned long stripes; /* number of stripes required (determ. by l0) */
+ int order; /* SDE ordering parameters */
+ int options; /* encoding parameters */
+ int mx, my; /* maximum ATMOVE window size */
+ char *dppriv; /* optional private deterministic prediction table */
+
+ /* loop variables */
+ unsigned long ii[3]; /* current stripe, layer, plane (outer loop first) */
+
+ /*
+ * Pointers to array [planes] of lower/higher resolution images.
+ * lhp[d & 1] contains image of layer d.
+ */
+ unsigned char **lhp[2];
+
+ /* status information */
+ int **tx, **ty; /* array [plane][layer-dl] with x,y-offset of AT pixel */
+ struct jbg_ardec_state **s; /* array [plane][layer-dl] for arithmetic *
+ * decoder status */
+ int **reset; /* array [plane][layer-dl] remembers if previous stripe *
+ * in that plane/resolution ended with SDRST. */
+ unsigned long bie_len; /* number of bytes read so far */
+ unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */
+ int buf_len; /* number of bytes in buffer */
+ unsigned long comment_skip; /* remaining bytes of a COMMENT segment */
+ unsigned long x; /* x position of next pixel in current SDE */
+ unsigned long i; /* line in current SDE (first line of each stripe is 0) */
+ int at_moves; /* number of AT moves in the current stripe */
+ unsigned long at_line[JBG_ATMOVES_MAX]; /* lines at which an *
+ * AT move will happen */
+ int at_tx[JBG_ATMOVES_MAX], at_ty[JBG_ATMOVES_MAX]; /* ATMOVE offsets in *
+ * current stripe */
+ unsigned long line_h1, line_h2, line_h3; /* variables of decode_pscd */
+ unsigned long line_l1, line_l2, line_l3;
+ int pseudo; /* flag for TPBON/TPDON: next pixel is pseudo pixel */
+ int **lntp; /* flag [plane][layer-dl] for TP: line is not typical */
+
+ unsigned long xmax, ymax; /* if possible abort before image gets *
+ * larger than this size */
+ int dmax; /* abort after this layer */
+ size_t maxmem; /* return JBG_ENOMEM if final image layer D
+ would require more than maxmem bytes */
+};
+
+
+/* some macros (too trivial for a function) */
+
+#define jbg_dec_getplanes(s) ((s)->planes)
+
+
+/* function prototypes */
+
+void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+ int planes, unsigned char **p,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file);
+int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
+ unsigned long mheight);
+void jbg_enc_layers(struct jbg_enc_state *s, int d);
+int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
+void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+ unsigned long l0, int mx, int my);
+void jbg_enc_out(struct jbg_enc_state *s);
+void jbg_enc_free(struct jbg_enc_state *s);
+
+void jbg_dec_init(struct jbg_dec_state *s);
+void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+ unsigned long ymax);
+int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt);
+unsigned long jbg_dec_getwidth(const struct jbg_dec_state *s);
+unsigned long jbg_dec_getheight(const struct jbg_dec_state *s);
+unsigned char *jbg_dec_getimage(const struct jbg_dec_state *s, int plane);
+unsigned long jbg_dec_getsize(const struct jbg_dec_state *s);
+void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file), void *file);
+unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
+void jbg_dec_free(struct jbg_dec_state *s);
+
+const char *jbg_strerror(int errnum);
+void jbg_int2dppriv(unsigned char *dptable, const char *internal);
+void jbg_dppriv2int(char *internal, const unsigned char *dptable);
+unsigned long jbg_ceil_half(unsigned long x, int n);
+void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+ int encode_planes,
+ const unsigned char *src, unsigned char **dest,
+ int use_graycode);
+int jbg_newlen(unsigned char *bie, size_t len);
+
+#endif /* JBG_H */
diff --git a/thirdparty/jbigkit/libjbig/jbig.txt b/thirdparty/jbigkit/libjbig/jbig.txt
new file mode 100644
index 000000000..4547b1234
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig.txt
@@ -0,0 +1,828 @@
+
+Using the JBIG-KIT library
+--------------------------
+
+Markus Kuhn -- 2020-08-03
+
+
+This text explains how to use the functions provided by the JBIG-KIT
+portable image compression library jbig.c in your application
+software. The jbig.c library is a full-featured implementation of the
+JBIG1 standard aimed at applications that can hold the entire
+uncompressed and compressed image in RAM.
+
+[For applications that require only the single-bit-per-pixel "fax
+subset" of the JBIG1 standard defined in ITU-T Recommendation T.85
+, the alternative implementation
+found in jbig85.c may be preferable. It keeps not more than three
+lines of the uncompressed image in RAM, which makes it particularly
+suitable for embedded applications. For information on how to use
+jbig85.c, please refer to the separate documentation file jbig85.txt.]
+
+
+1 Introduction to JBIG
+
+We start with a short introduction to JBIG1. More detailed information
+is provided in the "Introduction and overview" section of the JBIG1
+standard. Information on how to obtain a copy of the standard is
+available from or
+.
+
+Image data encoded with the JBIG algorithm is separated into planes,
+layers, and stripes. Each plane contains one bit per pixel. The number
+of planes stored in a JBIG data stream is the number of bits per
+pixel. Resolution layers are numbered from 0 to D with 0 being the
+layer with the lowest resolution and D the one with the highest. Each
+next higher resolution layer has twice the number of rows and columns.
+Layer 0 is encoded independently of any other data, all other
+resolution layers are encoded as only the difference between the next
+lower and the current layer. For applications that require very quick
+access to parts of an image, it is possible to divide an image into
+several horizontal stripes. All stripes of one resolution layer have
+equal size, except perhaps the final one. The number of stripes of an
+image is equal in all resolution layers and in all bit planes.
+
+The compressed data stream specified by the JBIG standard is called a
+bi-level image entity (BIE). A BIE consists of a 20-byte header,
+followed by an optional 1728-byte table (usually not present, except
+in special applications) followed by a sequence of stripe data
+entities (SDE). Each SDE encodes the content of one single stripe in
+one plane of one resolution layer. Between the SDEs, other information
+blocks (called floating marker segments) can also be present. They are
+used to change certain parameters of the algorithm in the middle of an
+image or contain additional application specific information. A BIE
+looks like this:
+
+
+ +------------------------------------------------+
+ | |
+ | 20-byte header (with image size, #planes, |
+ | #layers, stripe size, first layer, options, |
+ | SDE ordering, ...) |
+ | |
+ +------------------------------------------------+
+ | |
+ | optional 1728-byte table |
+ | |
+ +------------------------------------------------+
+ | |
+ | optional floating marker segments |
+ | |
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+ | |
+ | optional floating marker segments |
+ | |
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+ ...
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+
+
+One BIE can contain all resolution layers of an image, but it is also
+possible to store various resolution layers in several BIEs. The BIE
+header contains the number of the first and the last resolution layer
+stored in this BIE, as well as the size of the highest resolution
+layer stored in this BIE. Progressive coding is deactivated by simply
+storing the image in one single resolution layer.
+
+Different applications might have different requirements for the order
+in which the SDEs for stripes of various planes and layers are stored
+in the BIE, so all possible sensible orderings are allowed by the
+standard and indicated by four bits in the header.
+
+It is possible to use the raw BIE data stream as specified by the JBIG
+standard directly as the format of a file used for storing images.
+This is what the pbmtojbg, jbgtopbm, pbmtojbg85, and jbgtopbm85
+conversion tools do that are provided in this package as demonstration
+applications. However, as the BIE format has been designed for a large
+number of very different applications, and to allow efficient direct
+processing by special JBIG hardware chip implementations, the BIE
+header contains only the minimum amount of information absolutely
+required by the decompression algorithm. Many features expected from a
+good file format are missing in the BIE data stream:
+
+ - no "magic code" in the first few bytes to allow identification
+ of the file format on a typeless file system and to allow
+ automatic distinction from other compression algorithms
+
+ - no standardized way to encode additional information such as a
+ textual description, information about the meaning of various bit
+ planes, the physical size and resolution of the document, etc.
+
+ - a checksum to ensure image integrity
+
+ - encryption and signature mechanisms
+
+ - many things more
+
+Raw BIE data streams alone may therefore not be a suitable format for
+document archiving and exchange. A standard format for this purpose
+would typically combine a BIE representing the image data with an
+additional header providing auxiliary information into one file.
+Existing established multi-purpose file formats with a rich set of
+auxiliary information attributes like TIFF could be extended easily to
+also hold JBIG compressed data.
+
+On the other hand, in e.g. database applications, a BIE might be
+stored directly in a binary variable-length field. Auxiliary
+information would then be stored in other fields of the same record,
+to simplify search operations.
+
+
+2 Compressing an image
+
+2.1 Format of the source image
+
+To be processed by the jbig.c encoder, the image has to be present in
+memory as separate bitmap planes. Each byte of a bitmap contains eight
+pixels, where the most significant bit represents the leftmost of
+these. Each line of a bitmap has to be stored in an integral number of
+bytes. If the image width is not an integral multiple of eight, then
+the final byte has to be padded with zero bits.
+
+For example the 23x5 pixels large single plane image:
+
+ .XXXXX..XXX...X...XXX..
+ .....X..X..X..X..X.....
+ .....X..XXX...X..X.XXX.
+ .X...X..X..X..X..X...X.
+ ..XXX...XXX...X...XXX..
+
+is represented by the 15 bytes
+
+ 01111100 11100010 00111000
+ 00000100 10010010 01000000
+ 00000100 11100010 01011100
+ 01000100 10010010 01000100
+ 00111000 11100010 00111000
+
+or in hexadecimal notation
+
+ 7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38
+
+This is the format used in binary PBM files and it can also be handled
+directly by the Xlib library of the X Window System.
+
+As JBIG can also handle images with multiple bit planes, the jbig.c
+library functions accept and return always arrays of pointers to
+bitmaps with one pointer per plane.
+
+For single-plane images, the standard recommends that a 0 pixel
+represents the background and a 1 pixel represents the foreground
+colour of an image, in other words, 0 is white and 1 is black for
+scanned paper documents. For images with several bits per pixel, the
+JBIG standard makes no recommendations about how various colours should
+be encoded.
+
+For grey-scale images, by using a Gray code instead of a simple binary
+weighted representation of the pixel intensity, some increase in
+coding efficiency can be reached.
+
+A Gray code is also a binary representation of integer numbers, but it
+has the property that the representations of the integer numbers i and
+(i+1) always differ in exactly one bit. For example, the numbers 0 to
+7 can be represented in normal binary code and Gray code as in the
+following table:
+
+ normal
+ number binary code Gray code
+ ---------------------------------------
+ 0 000 000
+ 1 001 001
+ 2 010 011
+ 3 011 010
+ 4 100 110
+ 5 101 111
+ 6 110 101
+ 7 111 100
+
+The form of Gray code shown above has the property that the second
+half of the code (numbers 4 - 7) is simply the mirrored first half
+(numbers 3 - 0) with the first bit set to one. This way, arbitrarily
+large Gray codes can be generated quickly by mirroring the above
+example and prefixing the first half with zeros and the second half
+with ones as often as required. In grey-scale images, it is common
+practise to use the all-0 code for black and the all-1 code for white.
+
+No matter whether a Gray code or a binary code is used for encoding a
+pixel intensity in several bit planes, it always makes sense to store
+the most significant (leftmost) bit in plane 0, which is transmitted
+first. This way, a decoder could increase the precision of the
+displayed pixel intensities while data is still being received and the
+basic structure of the image will become visible as early as possible
+during the transmission.
+
+
+2.2 A simple compression application
+
+In order to use jbig.c in your application, just link your executable
+with both jbig.c and jbig_ar.c. Both are already combined into
+libjbig.a by the provided Makefile, so on Unix systems, just add
+-ljbig and -L. to the command line options of your compiler. On other
+systems you will probably have to write a new Makefile. Make sure your
+compiler can find the file jbig.h and put the line
+
+ #include "jbig.h"
+
+into your source code.
+
+The library interface follows object-oriented programming principles.
+You have to declare a variable (object)
+
+ struct jbg_enc_state s;
+
+which contains the current status of an encoder. Then you initialize
+the encoder by calling the constructor function
+
+ void jbg_enc_init(struct jbg_enc_state *s, unsigned long x, unsigned long y,
+ int pl, unsigned char **p,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file);
+
+The parameters have the following meaning:
+
+ s A pointer to the jbg_enc_state structure that you want
+ to initialize.
+
+ x The width of your image in pixels.
+
+ y The height of your image in pixels (lines).
+
+ pl the number of bitmap planes you want to encode.
+
+ p A pointer to an array of pl pointers, where each is again
+ pointing to the first byte of a bitmap as described in
+ section 2.1.
+
+ data_out This is a call-back function that the encoder will
+ call during the compression process by in order to
+ deliver the BIE data to your application. The
+ parameters of the function data_out are a pointer
+ start to the new block of data being delivered, as
+ well as the number len of delivered bytes. The pointer
+ file is transparently delivered to data_out, as
+ specified in jbg_enc_init(). Typically, data_out will
+ write the BIE portion to a file, send it to a network
+ connection, or append it to some memory buffer.
+
+ file A pointer parameter that is passed on to data_out()
+ and can be used, for instance, to allow data_out() to
+ distinguish by which compression task it has been
+ called in multi-threaded applications.
+
+In the simplest case, the compression is then started by calling the
+function
+
+ void jbg_enc_out(struct jbg_enc_state *s);
+
+which will deliver the complete BIE to data_out() in several calls.
+After jbg_enc_out has returned, a call to the destructor function
+
+ void jbg_enc_free(struct jbg_enc_state *s);
+
+will release any heap memory allocated by the previous functions.
+
+
+A minimal example application, which sends the BIE of the above bitmap
+to stdout, looks like this:
+
+---------------------------------------------------------------------------
+/* A sample JBIG encoding application */
+
+#include
+#include "jbig.h"
+
+void output_bie(unsigned char *start, size_t len, void *file)
+{
+ fwrite(start, 1, len, (FILE *) file);
+
+ return;
+}
+
+int main()
+{
+ unsigned char bitmap[15] = {
+ /* 23 x 5 pixels, "JBIG" */
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2,
+ 0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38
+ };
+ unsigned char *bitmaps[1] = { bitmap };
+ struct jbg_enc_state se;
+
+ jbg_enc_init(&se, 23, 5, 1, bitmaps,
+ output_bie, stdout); /* initialize encoder */
+ jbg_enc_out(&se); /* encode image */
+ jbg_enc_free(&se); /* release allocated resources */
+
+ return 0;
+}
+---------------------------------------------------------------------------
+
+This software produces a 42 byte long BIE. (JBIG is not very good at
+compressing extremely small images like in this example, because the
+arithmetic encoder requires some startup data in order to generate
+reasonable statistics which influence the compression process and
+because there is some header overhead.)
+
+
+2.3 More about compression
+
+If jbg_enc_out() is called directly after jbg_enc_init(), the
+following default values are used for various compression parameters:
+
+ - Only one single resolution layer is used, i.e. no progressive
+ mode.
+
+ - The number of lines per stripe is selected so that approximately
+ 35 stripes per image are used (as recommended in annex C of the
+ standard together with the suggested adaptive template change
+ algorithm). However, not less than 2 and not more than 128 lines
+ are used in order to stay within the suggested minimum parameter
+ support range specified in annex A of the standard).
+
+ - All optional parts of the JBIG algorithm are activated (TPBON,
+ TPDON and DPON).
+
+ - The default resolution reduction table and the default deterministic
+ prediction table are used
+
+ - The maximal vertical offset of the adaptive template pixel is 0
+ and the maximal horizontal offset is 8 (mx = 8, my = 0).
+
+In order to change any of these default parameters, additional
+functions have to be called between jbg_enc_init() and jbg_enc_out().
+
+In order to activate progressive encoding, it is possible to specify
+with
+
+ void jbg_enc_layers(struct jbg_enc_state *s, int d);
+
+the number d of differential resolution layers which shall be encoded
+in addition to the lowest resolution layer 0. For example, if a
+document with 60-micrometer pixels has to be stored, and the lowest
+resolution layer shall have 240-micrometer pixels, so that a screen
+previewer can directly decompress only the required resolution, then a
+call
+
+ jbg_enc_layers(&se, 2);
+
+will cause three layers with 240, 120 and 60 micrometers resolution to
+be generated.
+
+If the application does not know what typical resolutions are used and
+simply wants to ensure that the lowest resolution layer will fit into
+a given maximal window size, then as an alternative, a call to
+
+ int jbg_enc_lrlmax(struct jbg_enc_state *s, unsigned long mwidth,
+ unsigned long mheight);
+
+will cause the library to automatically determine the suitable number
+of resolutions so that the lowest resolution layer 0 will not be
+larger than mwidth x mheight pixels. E.g. if one wants to ensure that
+systems with a 640 x 480 pixel large screen can decode the required
+resolution directly, then call
+
+ jbg_enc_lrlmax(&se, 640, 480);
+
+The return value is the number of differential layers selected.
+
+After the number of resolution layers has been specified by calls to
+jbg_enc_layers() or jbg_enc_lrlmax(), by default, all these layers
+will be written into the BIE. This can be changed with a call to
+
+ int jbg_enc_lrange(struct jbg_enc_state *s, int dl, int dh);
+
+Parameter dl specifies the lowest resolution layer and dh the highest
+resolution layer that will appear in the BIE. For instance, if layer 0
+shall be written to the first BIE and layer 1 and 2 shall be written
+to a second one, then before writing the first BIE, call
+
+ jbg_enc_lrange(&se, 0, 0);
+
+and before writing the second BIE with jbg_enc_out(), call
+
+ jbg_enc_lrange(&se, 1, 2);
+
+If any of the parameters is negative, it will be ignored. The return
+value is the total number of differential layers that will represent
+the input image. This way, jbg_enc_lrange(&se, -1, -1) can be used to
+query the layer of the full image resolution.
+
+A number of other more exotic options of the JBIG algorithm can be
+modified by calling
+
+ void jbg_enc_options(struct jbg_enc_state *s, int order, int options,
+ long l0, int mx, int my);
+
+before calling jbg_enc_out().
+
+The order parameter can be a combination of the bits JBG_HITOLO,
+JBG_SEQ, JBG_ILEAVE and JBG_SMID and it determines in which order
+the SDEs are stored in the BIE. The bits have the following meaning:
+
+ JBG_HITOLO Usually, the lower resolution layers are stored before
+ the higher resolution layers, so that a decoder can
+ already start to display a low resolution version of
+ the full image once a prefix of the BIE has been
+ received. When this bit is set, however, the BIE will
+ contain the higher layers before the lower layers. This
+ avoids additional buffer memory in the encoder and is
+ intended for applications where the encoder is connected
+ to a database which can easily reorder the SDEs before
+ sending them to a decoder. Warning: JBIG decoders are
+ not expected to support the HITOLO option (e.g. the
+ jbig.c decoder currently does not) so you should
+ normally not use it.
+
+ JBG_SEQ Usually, at first all stripes of one resolution layer
+ are written to the BIE and then all stripes of the next
+ layer, and so on. When the SEQ bit is set however, then
+ all layers of the first stripe will be written,
+ followed by all layers of the second stripe, etc. This
+ option also should normally never be required and is
+ not supported by the current jbig.c decoder.
+
+ JBG_SMID In case there exist several bit planes, then the order of
+ the stripes is determined by three loops over all stripes,
+ all planes and all layers. When SMID is set, the loop
+ over all stripes is the middle loop.
+
+ JBG_ILEAVE If this bit is set, then at first all layers of one
+ plane are written before the encoder starts with the next
+ plane.
+
+The above description may be somewhat confusing, but the following
+table (see also Table 11 in ITU-T T.82) clarifies how the three bits
+JBG_SEQ, JBIG_ILEAVE and JBG_SMID influence the ordering of the loops
+over all stripes, planes and layers:
+
+
+ Loops:
+ JBG_SEQ JBG_ILEAVE JBG_SMID | Outer Middle Inner
+ ------------------------------------+---------------------------
+ 0 0 0 | p d s
+ 0 1 0 | d p s
+ 0 1 1 | d s p
+ 1 0 0 | s p d
+ 1 0 1 | p s d
+ 1 1 0 | s d p
+
+ p: plane, s: stripe, d: layer
+
+
+By default, the order combination JBG_ILEAVE | JBG_SMID is used.
+
+The options value can contain the following bits, which activate
+some of the optional algorithms defined by JBIG:
+
+ JBG_LRLTWO Normally, in the lowest resolution layer, pixels
+ from three lines around the next pixel are used
+ in order to determine the context in which the next
+ pixel is encoded. Some people in the JBIG committee
+ seem to have argued that using only 2 lines will
+ make software implementations a little bit faster,
+ however others have argued that using only two lines
+ will decrease compression efficiency by around 5%.
+ As you might expect from a committee, now both
+ alternatives are allowed and if JBG_LRLTWO is set,
+ the slightly faster but 5% less well compressing two
+ line alternative is selected. God bless the committees.
+ Although probably nobody will ever need this option,
+ it has been implemented in jbig.c and is off by
+ default.
+
+ JBG_TPDON This activates the "typical prediction" algorithm
+ for differential layers which avoids that large
+ areas of equal colour have to be encoded at all.
+ This is on by default and there is no good reason to
+ switch it off except for debugging or preparing data
+ for cheap JBIG hardware that might not support this
+ option.
+
+ JBG_TPBON Like JBG_TPDON this activates the "typical prediction"
+ algorithm in the lowest resolution layer. Also activated
+ by default.
+
+ JBG_DPON This bit activates for the differential resolution
+ layers the "deterministic prediction" algorithm,
+ which avoids that higher resolution layer pixels are
+ encoded when their value can already be determined
+ with the knowledge of the neighbour pixels, the
+ corresponding lower resolution pixels and the
+ resolution reduction algorithm. This is also
+ activated by default and one reason for deactivating
+ it would be if the default resolution reduction
+ algorithm were replaced by another one.
+
+ JBG_DELAY_AT Use a slightly less efficient algorithm to determine
+ when an adaptive template change is necessary. With
+ this bit set, the encoder output is compatible to the
+ conformance test examples in cause 7.2 of ITU-T T.82.
+ Then all adaptive template changes are delayed until
+ the first line of the next stripe. This option is by
+ default deactivated and is only required for passing a
+ special compatibility test suite.
+
+In addition, parameter l0 in jbg_enc_options() allows you to specify
+the number of lines per stripe in resolution layer 0. The parameters
+mx and my change the maximal offset allowed for the adaptive template
+pixel. JBIG-KIT now supports the full range of possible mx values up
+to 127 in the encoder and decoder, but my is at the moment ignored and
+always set to 0. As the standard requires of all decoder
+implementations only to support maximum values mx = 16 and my = 0,
+higher values should normally be avoided in order to guarantee
+interoperability. The ITU-T T.85 profile for JBIG in fax machines
+requires support for mx = 127 and my = 0. Default is mx = 8 and my =
+0. If any of the parameters order, options, mx or my is negative, or
+l0 is zero, then the corresponding current value remains unmodified.
+
+The resolution reduction and deterministic prediction tables can also
+be replaced. However as these options are anyway only for experts,
+please have a look at the source code of jbg_enc_out() and the struct
+members dppriv and res_tab of struct jbg_enc_state for the details of
+how to do this, in case you really need it. The functions
+jbg_int2dppriv and jbg_dppriv2int are provided in order to convert the
+DPTABLE data from the format used in the standard into the more
+efficient format used internally by JBIG-KIT.
+
+If you want to encode a grey-scale image, you can use the library
+function
+
+ void jbg_split_planes(unsigned long x, unsigned long y, int has_planes,
+ int encode_planes,
+ const unsigned char *src, unsigned char **dest,
+ int use_graycode);
+
+It separates an image in which each pixel is represented by one or
+more bytes into separate bit planes. The dest array of pointers to
+these bit planes can then be handed over to jbg_enc_init(). The
+variables x and y specify the width and height of the image in pixels,
+and has_planes specifies how many bits per pixel are used. As each
+pixel is represented by an integral number of consecutive bytes, of
+which each contains up to eight bits, the total length of the input
+image array src[] will therefore be x * y * ((has_planes + 7) / 8)
+bytes. The pixels are stored as usually in English reading order, and
+for each pixel the integer value is stored with the most significant
+byte coming first (Bigendian). This is exactly the format used in raw
+PGM files. In encode_planes, the number of bit planes that shall be
+extracted can be specified. This allows for instance to extract only
+the most significant 8 bits of a 12-bit image, where each pixel is
+represented by two bytes, by specifying has_planes = 12 and
+encode_planes = 8. If use_graycode is zero, then the binary code of
+the pixel integer values will be used instead of the Gray code. Plane
+0 contains always the most significant bit.
+
+
+3 Decompressing an image
+
+Like with the compression functions, if you want to use the jbig.c
+library, you have to put the line
+
+ #include "jbig.h"
+
+into your source code and link your executable with libjbig.a.
+
+The state of a JBIG decoder is stored completely in a struct and you
+will have to define a variable like
+
+ struct jbg_dec_state sd;
+
+which is initialized by a call to
+
+ void jbg_dec_init(struct jbg_dec_state *s);
+
+After this, you can directly start to pass data from the BIE to the decoder
+by calling the function
+
+ int jbg_dec_in(struct jbg_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt);
+
+The pointer data points to the first byte of a data block with length
+len, which contains bytes from a BIE. It is not necessary to pass a
+whole BIE at once to jbg_dec_in(), it can arrive fragmented in any way
+by calling jbg_dec_in() several times. It is also possible to send
+several BIEs concatenated to jbg_dec_in(), however these then have to
+fit together. If you send several BIEs to the decoder, the lowest
+resolution layer in each following BIE has to be the highest
+resolution layer in the previous BIE plus one and the image sizes and
+number of planes also have to fit together, otherwise jbg_dec_in()
+will return the error JBG_ENOCONT after the header of the new BIE has
+been received completely.
+
+If pointer cnt is not NULL, then the number of bytes actually read
+from the data block will be stored there. In case the data block did
+not contain the end of the BIE, then the value JBG_EAGAIN will be
+returned and *cnt equals len.
+
+Once the end of a BIE has been reached, the return value of
+jbg_dec_in() will be JBG_EOK. After this has happened, the functions
+and macros
+
+ unsigned long jbg_dec_getwidth(struct jbg_dec_state *s);
+ unsigned long jbg_dec_getheight(struct jbg_dec_state *s);
+ int jbg_dec_getplanes(struct jbg_dec_state *s);
+ unsigned char *jbg_dec_getimage(struct jbg_dec_state *s, int plane);
+ unsigned long jbg_dec_getsize(struct jbg_dec_state *s);
+
+can be used to query the dimensions of the now completely decoded
+image and to get a pointer to all bitmap planes. The bitmaps are
+stored as described in section 2.1. The function jbg_dec_getsize()
+calculates the number of bytes which one bitmap requires.
+
+The function
+
+ void jbg_dec_merge_planes(const struct jbg_dec_state *s, int use_graycode,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file), void *file);
+
+allows you to merge the bit planes that can be accessed individually
+with jbg_dec_getimage() into an array with one or more bytes per pixel
+(i.e., the format provided to jbg_split_planes()). If use_graycode is
+zero, then a binary encoding will be used. The output array will be
+delivered via the callback function data_out, exactly in the same way
+in which the encoder provides the BIE. The function
+
+ unsigned long jbg_dec_getsize_merged(const struct jbg_dec_state *s);
+
+determines how long the data array delivered by jbg_dec_merge_planes()
+is going to be.
+
+Before calling jbg_dec_in() the first time, it is possible to specify with
+a call to
+
+ void jbg_dec_maxsize(struct jbg_dec_state *s, unsigned long xmax,
+ unsigned long ymax);
+
+an abort criterion for progressively encoded images. For instance if an
+application will display a whole document on a screen which is 1024 x
+768 pixels large, then this application should call
+
+ jbg_dec_maxsize(&sd, 1024, 768);
+
+before the decoding process starts. If the image has been encoded in
+progressive mode (i.e. with several resolution layers), then the
+decoder will stop with a return value JBG_EOK_INTR after the largest
+resolution layer that is still smaller than 1024 x 768. However this
+is no guarantee that the image which can then be read out using
+jbg_dec_getimage(), etc. is really not larger than the specified
+maximal size. The application will have to check the size of the
+image, because the decoder does not automatically apply a resolution
+reduction if no suitable resolution layer is available in the BIE.
+
+If jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, then it is possible
+to continue calling jbg_dec_in() with the remaining data in order to
+either decode the remaining resolution layers of the current BIE or in
+order to add another BIE with additional resolution layers. In both
+cases, after jbg_dec_in() returned JBG_EOK_INTR or JBG_EOK, *cnt is
+probably not equal to len and the remainder of the data block which
+has not yet been processed by the decoder has to be delivered to
+jbg_dec_in() again.
+
+If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN
+has been returned by jbg_dec_in(), then an error has occurred and
+
+ void jbg_dec_free(struct jbg_dec_state *s);
+
+should be called in order to release any allocated memory. The
+destructor jbg_dec_free() should of course also be called, once the
+decoded bitmap returned by jbg_dec_getimage() is no longer required
+and the memory can be released.
+
+The function
+
+ const char *jbg_strerror(int errnum);
+
+returns a pointer to a short single line test message that explains
+the return value of jbg_dec_in(). This message can be used in order to
+provide the user a brief informative message about what when wrong
+while decompressing a JBIG image. The po/ subdirectory contains *.po
+files that translate the English ASCII strings returned by
+jbg_strerror() into other languages (e.g., for use with GNU gettext).
+The four least-significant bits of the return value of jbg_dec_in()
+may contain additional detailed technical information about the exact
+test that spotted the error condition (see source code for details),
+i.e. more than the text message returned by jbg_strerror() reveals.
+Therefore it may be useful to display the return value itself as a
+hexadecimal number, in addition to the string returned by
+jbg_strerror().
+
+The current implementation of the jbig.c decoder has the following
+limitations:
+
+ - The maximal vertical offset MY of the adaptive template pixel
+ must be zero.
+
+ - HITOLO and SEQ bits must not be set in the order value.
+
+ - Not more than JBG_ATMOVES_MAX (currently set to 64) ATMOVE
+ marker segments can be handled per stripe.
+
+ - the number D of differential layers must be less than 32
+
+None of the above limitations can be exceeded by a JBIG data stream
+that conforms to the ITU-T T.85 application profile for the use of
+JBIG1 in fax machines.
+
+The maximum image size that a BIE header (BIH) can indicate is X_D =
+2^32-1 pixels wide, Y_D = 2^32-1 lines high, with P = 255 bits per
+pixel. Such an image would, in uncompressed form, require about 588
+exabytes. Once jbg_dec_in() has received the 20-byte long BIH at the
+start of the BIE, it will call malloc() to allocate enough memory to
+hold the uncompressed image planes. Users may, therefore, want to
+defend their application against excessive image-size parameters in a
+received BIH, by checking X_D, Y_D, and P against appropriate safety
+limits before handing over the BIE header to jbg_dec_in(). BIE headers
+indicating too large images might be abused for denial of service
+attacks, to exhaust the memory of a system (e.g., CVE-2017-9937). To
+manage this risk, the jbig.c decoder will now, by default, return "Not
+enough memory available" (JBG_ENOMEM) if the resulting final image
+layer would occupy more than 2 gigabytes. Users can adjust this limit
+by changing sd->maxmem right after having called jbg_dec_init(&sd).
+The actual amount of memory allocated with malloc() calls during the
+decoding process is somewhat higher (at least 25%) than the limit set
+in sd->maxmem, as the decoder requires additional heap memory that
+depends on the image dimensions.
+
+The jbg_dec_in() function will return "Input data stream uses
+unimplemented JBIG features" (JBG_EIMPL | 1) if Y_D equals 0xffffffff,
+which is an extreme value commonly used to encode images according to
+ITU-T T.85 where the height was unknown when the BIH was emitted.
+
+All malloc(), realloc() and free() functions called by jbig.c are
+wrapped by the functions checked_malloc(), checked_realloc() and
+checked_free(). These simply call abort() when memory allocation
+fails. Developpers of embedded systems may want to replace them with
+alternative forms of exception handling.
+
+There are two more limitations of the current implementation of the
+jbig.c decoder that might cause problems with processing JBIG data
+stream that conform to ITU-T T.85:
+
+ - The jbig.c decoder was designed to operate incrementally.
+ Each received byte is processed immediately as soon as it arrives.
+ As a result, it does not look beyond the SDRST/SDNORM at the end
+ of all stripes for any immediately following NEWLEN marker that
+ might reduce the number of lines encoded by the current stripe.
+ However section 6.2.6.2 of ITU-T T.82 says that a NEWLEN marker
+ segment "could refer to a line in the immediately preceding stripe
+ due to an unexpected termination of the image or the use of only
+ such stripe", and ITU-T.85 explicitly suggests the use of this
+ for fax machines that start transmission before having encountered
+ the end of the page.
+
+ - The image size initially indicated in the BIE header is used to
+ allocate memory for a bitmap of this size. This means that BIEs
+ that set initially Y_D = 0xffffffff (as suggested in ITU-T T.85
+ for fax machines that do not know the height of the page at the
+ start of the transmission) cannot be decoded directly by this
+ version.
+
+For both issues, there is a workaround available:
+
+If you encounter a BIE that has in the header the VLENGTH=1 option bit
+set, then first wait until you have received the entire BIE and stored
+it in memory. Then call the function
+
+ int jbg_newlen(unsigned char *bie, size_t len);
+
+where bie is a pointer to the first byte of the BIE and len its length
+in bytes. This function will scan the entire BIE for the first NEWLEN
+marker segment. It will then take the updated image-height value YD
+from it and use it to overwrite the YD value in the BIE header. The
+jbg_newlen() can return some of the same error codes as jbg_dec_in(),
+namely JBG_EOK if everything went fine, JBG_EAGAIN is the data
+provided is too short to be a valid BIE, JBG_EINVAL if a format error
+was encountered, and JBG_EABORT if an ABORT marker segment was found.
+After having patched the image-height value in the BIE using
+jbg_newlen(), simply hand over the BIE as usual to jbg_dec_in().
+
+In general, for applications where NEWLEN markers can appear, in
+particular fax reception, you should consider using the jbig85.c
+decoder instead, as it can process BIEs with NEWLEN markers in a
+single pass.
+
+A more detailed description of the JBIG-KIT implementation is
+
+ Markus Kuhn: Effiziente Kompression von bi-level Bilddaten durch
+ kontextsensitive arithmetische Codierung. Studienarbeit, Lehrstuhl
+ für Betriebssysteme, IMMD IV, Universität Erlangen-Nürnberg,
+ Erlangen, July 1995. (German, 62 pages)
+
+
+Please quote the above if you use JBIG-KIT in your research project.
+
+*** Happy compressing ***
+
+[end]
diff --git a/thirdparty/jbigkit/libjbig/jbig85.c b/thirdparty/jbigkit/libjbig/jbig85.c
new file mode 100644
index 000000000..924b51140
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig85.c
@@ -0,0 +1,1091 @@
+/*
+ * T.85 "light" version of the portable JBIG image compression library
+ *
+ * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ *
+ * This module implements a portable standard C encoder and decoder
+ * using the JBIG1 lossless bi-level image compression algorithm
+ * specified in International Standard ISO 11544:1993 and
+ * ITU-T Recommendation T.82. See the file jbig.txt for usage
+ * instructions and application examples.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * If you want to use this program under different license conditions,
+ * then contact the author for an arrangement.
+ */
+
+#ifdef DEBUG
+#include
+#else
+#define NDEBUG
+#endif
+
+#include
+#include
+#include
+
+#include "jbig85.h"
+
+#define TPB2CX 0x195 /* contexts for TP special pixels */
+#define TPB3CX 0x0e5
+
+/* marker codes */
+#define MARKER_STUFF 0x00
+#define MARKER_RESERVE 0x01
+#define MARKER_SDNORM 0x02
+#define MARKER_SDRST 0x03
+#define MARKER_ABORT 0x04
+#define MARKER_NEWLEN 0x05
+#define MARKER_ATMOVE 0x06
+#define MARKER_COMMENT 0x07
+#define MARKER_ESC 0xff
+
+/* object code version id */
+
+const char jbg85_version[] =
+ "JBIG-KIT " JBG85_VERSION " (T.85 version) -- (c) 1995-2014 Markus Kuhn -- "
+ "Licence: " JBG85_LICENCE "\n";
+
+#define _(String) String /* to mark translatable string for GNU gettext */
+
+/*
+ * Array with English ASCII error messages that correspond
+ * to return values from public functions in this library.
+ */
+static const char *errmsg[] = {
+ _("All OK"), /* JBG_EOK */
+ _("Reached specified image size"), /* JBG_EOK_INTR */
+ _("Unexpected end of input data stream"), /* JBG_EAGAIN */
+ _("Not enough memory available"), /* JBG_ENOMEM */
+ _("ABORT marker segment encountered"), /* JBG_EABORT */
+ _("Unknown marker segment encountered"), /* JBG_EMARKER */
+ _("Input data stream contains invalid data"), /* JBG_EINVAL */
+ _("Input data stream uses unimplemented JBIG features") /* JBG_EIMPL */
+};
+
+
+/*
+ * Callback adapter function for arithmetic encoder
+ */
+static void enc_byte_out(int byte, void *s)
+{
+ unsigned char c = byte;
+ ((struct jbg85_enc_state *)s)->data_out(&c, sizeof(unsigned char),
+ ((struct jbg85_enc_state *)s)->file);
+}
+
+
+/*
+ * Initialize the status struct for the encoder.
+ */
+void jbg85_enc_init(struct jbg85_enc_state *s,
+ unsigned long x0, unsigned long y0,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file)
+{
+ assert(x0 > 0 && y0 > 0);
+ s->x0 = x0;
+ s->y0 = y0;
+ s->newlen = 0; /* no NEWLEN pending or output */
+ s->data_out = data_out;
+ s->file = file;
+
+ s->l0 = s->y0 / 35; /* 35 stripes/image suggested default */
+ if (s->l0 > 128) s->l0 = 128;
+ else if (s->l0 < 2) s->l0 = 2;
+#if 1
+ s->l0 = 128; /* T.85 BASIC setting */
+#endif
+ s->mx = 127;
+ s->new_tx = -1; /* no ATMOVE pending */
+ s->tx = 0;
+ s->options = JBG_TPBON | JBG_VLENGTH;
+ s->comment = NULL; /* no COMMENT pending */
+ s->y = 0;
+ s->i = 0;
+ s->ltp_old = 0;
+
+ /* initialize arithmetic encoder */
+ arith_encode_init(&s->s, 0);
+ s->s.byte_out = &enc_byte_out;
+ s->s.file = s;
+
+ return;
+}
+
+
+/*
+ * The following function allows to specify the bits describing the
+ * options of the format as well as the maximum AT movement window and
+ * the number of layer 0 lines per stripes.
+ */
+void jbg85_enc_options(struct jbg85_enc_state *s, int options,
+ unsigned long l0, int mx)
+{
+ if (s->y > 0) return; /* too late to change anything now */
+
+ if (options >= 0) s->options = options;
+ if (l0 > 0) s->l0 = l0;
+ if (mx >= 0 && mx < 128) s->mx = mx;
+
+ return;
+}
+
+
+/* auxiliary routine to write out NEWLEN */
+static void output_newlen(struct jbg85_enc_state *s)
+{
+ unsigned char buf[6];
+
+ assert(s->i == 0);
+ if (s->newlen != 1)
+ return;
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_NEWLEN;
+ buf[2] = s->y0 >> 24;
+ buf[3] = (s->y0 >> 16) & 0xff;
+ buf[4] = (s->y0 >> 8) & 0xff;
+ buf[5] = s->y0 & 0xff;
+ s->data_out(buf, 6, s->file);
+ s->newlen = 2;
+ if (s->y == s->y0) {
+ /* if newlen refers to a line in the preceeding stripe, ITU-T T.82
+ * section 6.2.6.2 requires us to append another SDNORM */
+ buf[1] = MARKER_SDNORM;
+ s->data_out(buf, 2, s->file);
+ }
+}
+
+
+/*
+ * Encode one full BIE and pass the generated data to the specified
+ * call-back function
+ */
+void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line,
+ unsigned char *prevline, unsigned char *prevprevline)
+{
+ unsigned char buf[20];
+ unsigned long bpl;
+ unsigned char *hp1, *hp2, *hp3, *p1, *q1;
+ unsigned long line_h1 = 0, line_h2, line_h3;
+ unsigned long j; /* loop variable for pixel column */
+ long o;
+ unsigned a, p, t;
+ int ltp;
+ unsigned long cmin, cmax, clmin, clmax;
+ int tmax;
+#ifdef DEBUG
+ static long tp_lines;
+ static long encoded_pixels;
+#endif
+
+ if (s->y >= s->y0) {
+ /* we have already output the full image, go away */
+ return;
+ }
+
+ /* line 0 has no previous line */
+ if (s->y < 1)
+ prevline = NULL;
+ if (s->y < 2)
+ prevprevline = NULL;
+
+ /* things that need to be done before the first line is encoded */
+ if (s->y == 0) {
+ /* prepare BIH */
+ buf[0] = 0; /* DL = initial layer to be transmitted */
+ buf[1] = 0; /* D = number of differential layers */
+ buf[2] = 1; /* P = number of bit planes */
+ buf[3] = 0;
+ buf[4] = s->x0 >> 24;
+ buf[5] = (s->x0 >> 16) & 0xff;
+ buf[6] = (s->x0 >> 8) & 0xff;
+ buf[7] = s->x0 & 0xff;
+ buf[8] = s->y0 >> 24;
+ buf[9] = (s->y0 >> 16) & 0xff;
+ buf[10] = (s->y0 >> 8) & 0xff;
+ buf[11] = s->y0 & 0xff;
+ buf[12] = s->l0 >> 24;
+ buf[13] = (s->l0 >> 16) & 0xff;
+ buf[14] = (s->l0 >> 8) & 0xff;
+ buf[15] = s->l0 & 0xff;
+ buf[16] = s->mx;
+ buf[17] = 0; /* MY = maximum vertical offset allowed for AT pixel */
+ buf[18] = 0; /* order: HITOLO = SEQ = ILEAVE = SMID = 0 */
+ buf[19] = s->options & (JBG_LRLTWO | JBG_VLENGTH | JBG_TPBON);
+
+ /* output BIH */
+ s->data_out(buf, 20, s->file);
+ }
+
+ /* things that need to be done before the next SDE is encoded */
+ if (s->i == 0) {
+
+ /* output NEWLEN if there is any pending */
+ output_newlen(s);
+
+ /* output comment marker segment if there is any pending */
+ if (s->comment) {
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_COMMENT;
+ buf[2] = s->comment_len >> 24;
+ buf[3] = (s->comment_len >> 16) & 0xff;
+ buf[4] = (s->comment_len >> 8) & 0xff;
+ buf[5] = s->comment_len & 0xff;
+ s->data_out(buf, 6, s->file);
+ s->data_out(s->comment, s->comment_len, s->file);
+ s->comment = NULL;
+ }
+
+ /* output ATMOVE if there is any pending */
+ if (s->new_tx != -1 && s->new_tx != s->tx) {
+ s->tx = s->new_tx;
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_ATMOVE;
+ buf[2] = 0;
+ buf[3] = 0;
+ buf[4] = 0;
+ buf[5] = 0;
+ buf[6] = s->tx;
+ buf[7] = 0;
+ s->data_out(buf, 8, s->file);
+ }
+
+ /* initialize adaptive template movement algorithm */
+ if (s->mx == 0) {
+ s->new_tx = 0; /* ATMOVE has been disabled */
+ } else {
+ s->c_all = 0;
+ for (t = 0; t <= s->mx; t++)
+ s->c[t] = 0;
+ s->new_tx = -1; /* we have yet to determine ATMOVE ... */
+ }
+
+ /* restart arithmetic encoder */
+ arith_encode_init(&s->s, 1);
+ }
+
+#ifdef DEBUG
+ if (s->y == 0)
+ tp_lines = encoded_pixels = 0;
+ fprintf(stderr, "encode line %lu (%2lu of stripe)\n", s->y, s->i);
+#endif
+
+ /* bytes per line */
+ bpl = (s->x0 >> 3) + !!(s->x0 & 7);
+ /* ensure correct zero padding of bitmap at the final byte of each line */
+ if (s->x0 & 7) {
+ line[bpl - 1] &= ~((1 << (8 - (s->x0 & 7))) - 1);
+ }
+
+ /* typical prediction */
+ ltp = 0;
+ if (s->options & JBG_TPBON) {
+ p1 = line;
+ q1 = prevline;
+ ltp = 1;
+ if (q1)
+ while (p1 < line + bpl && (ltp = (*p1++ == *q1++)) != 0) ;
+ else
+ while (p1 < line + bpl && (ltp = (*p1++ == 0 )) != 0) ;
+ arith_encode(&s->s, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX,
+ ltp == s->ltp_old);
+#ifdef DEBUG
+ tp_lines += ltp;
+#endif
+ s->ltp_old = ltp;
+ }
+
+ if (!ltp) {
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently coded pixel X:
+ *
+ * 76543210765432107654321076543210 line_h3
+ * 76543210765432107654321076543210 line_h2
+ * 76543210765432107654321X76543210 line_h1
+ */
+
+ /* pointer to first image byte of the three lines of interest */
+ hp3 = prevprevline;
+ hp2 = prevline;
+ hp1 = line;
+
+ line_h1 = line_h2 = line_h3 = 0;
+ if (hp2) line_h2 = (long)*hp2 << 8;
+ if (hp3) line_h3 = (long)*hp3 << 8;
+
+ /* encode line */
+ for (j = 0; j < s->x0;) {
+ line_h1 |= *hp1;
+ if (j < bpl * 8 - 8 && hp2) {
+ line_h2 |= *(hp2 + 1);
+ if (hp3)
+ line_h3 |= *(hp3 + 1);
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx) {
+ if ((unsigned) s->tx > j)
+ a = 0;
+ else {
+ o = (j - s->tx) - (j & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx > 23 ||
+ a == ((line_h1 >> (4 + s->tx)) & 0x010));
+ arith_encode(&s->s, (((line_h2 >> 10) & 0x3e0) | a |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+ }
+ else
+ arith_encode(&s->s, (((line_h2 >> 10) & 0x3f0) |
+ ((line_h1 >> 9) & 0x00f)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (s->new_tx == -1 && j >= s->mx && j < s->x0 - 2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ s->c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 5; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ s->c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ s->c[t] += 0 == p;
+ }
+ ++s->c_all;
+ }
+ } while (++j & 7 && j < s->x0);
+ } else {
+ /* three line template */
+ do {
+ line_h1 <<= 1; line_h2 <<= 1; line_h3 <<= 1;
+ if (s->tx) {
+ if ((unsigned) s->tx > j)
+ a = 0;
+ else {
+ o = (j - s->tx) - (j & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(s->tx > 23 ||
+ a == ((line_h1 >> (6 + s->tx)) & 0x004));
+ arith_encode(&s->s, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x078) | a |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+ } else
+ arith_encode(&s->s, (((line_h3 >> 8) & 0x380) |
+ ((line_h2 >> 12) & 0x07c) |
+ ((line_h1 >> 9) & 0x003)),
+ (line_h1 >> 8) & 1);
+#ifdef DEBUG
+ encoded_pixels++;
+#endif
+ /* statistics for adaptive template changes */
+ if (s->new_tx == -1 && j >= s->mx && j < s->x0 - 2) {
+ p = (line_h1 & 0x100) != 0; /* current pixel value */
+ s->c[0] += ((line_h2 & 0x4000) != 0) == p; /* default position */
+ assert(!(((line_h2 >> 6) ^ line_h1) & 0x100) ==
+ (((line_h2 & 0x4000) != 0) == p));
+ for (t = 3; t <= s->mx && t <= j; t++) {
+ o = (j - t) - (j & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ assert(t > 23 ||
+ (a == p) == !(((line_h1 >> t) ^ line_h1) & 0x100));
+ s->c[t] += a == p;
+ }
+ for (; t <= s->mx; t++) {
+ s->c[t] += 0 == p;
+ }
+ ++s->c_all;
+ }
+ } while (++j & 7 && j < s->x0);
+ } /* if (s->options & JBG_LRLTWO) */
+ hp1++;
+ if (hp2) hp2++;
+ if (hp3) hp3++;
+ } /* for (j = ...) */
+ } /* if (!ltp) */
+
+ /* line is complete now, deal with end of stripe */
+ s->i++; s->y++;
+ if (s->i == s->l0 || s->y == s->y0) {
+ /* end of stripe reached */
+ arith_encode_flush(&s->s);
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_SDNORM;
+ s->data_out(buf, 2, s->file);
+ s->i = 0;
+
+ /* output NEWLEN if there is any pending */
+ output_newlen(s);
+ }
+
+ /* check whether it is worth to perform an ATMOVE */
+ if (s->new_tx == -1 && s->c_all > 2048) {
+ cmin = clmin = 0xffffffffL;
+ cmax = clmax = 0;
+ tmax = 0;
+ for (t = (s->options & JBG_LRLTWO) ? 5 : 3; t <= s->mx; t++) {
+ if (s->c[t] > cmax) cmax = s->c[t];
+ if (s->c[t] < cmin) cmin = s->c[t];
+ if (s->c[t] > s->c[tmax]) tmax = t;
+ }
+ clmin = (s->c[0] < cmin) ? s->c[0] : cmin;
+ clmax = (s->c[0] > cmax) ? s->c[0] : cmax;
+ if (s->c_all - cmax < (s->c_all >> 3) &&
+ cmax - s->c[s->tx] > s->c_all - cmax &&
+ cmax - s->c[s->tx] > (s->c_all >> 4) &&
+ /* ^ T.82 said < here, fixed in Cor.1/25 */
+ cmax - (s->c_all - s->c[s->tx]) > s->c_all - cmax &&
+ cmax - (s->c_all - s->c[s->tx]) > (s->c_all >> 4) &&
+ cmax - cmin > (s->c_all >> 2) &&
+ (s->tx || clmax - clmin > (s->c_all >> 3))) {
+ /* we have decided to perform an ATMOVE */
+ s->new_tx = tmax;
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: tx=%d, c_all=%lu\n",
+ s->new_tx, s->c_all);
+#endif
+ } else {
+ s->new_tx = s->tx; /* we have decided not to perform an ATMOVE */
+ }
+ }
+ assert(s->tx >= 0); /* i.e., tx can safely be cast to unsigned */
+
+#ifdef DEBUG
+ if (s->y == s->y0)
+ fprintf(stderr, "tp_lines = %ld, encoded_pixels = %ld\n",
+ tp_lines, encoded_pixels);
+#endif
+
+ return;
+}
+
+
+/*
+ * Inform encoder about new (reduced) height of image
+ */
+void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long newlen)
+{
+ unsigned char buf[6];
+
+ if (s->newlen == 2 || newlen >= s->y0 || newlen < 1 ||
+ !(s->options & JBG_VLENGTH)) {
+ /* invalid invocation or parameter */
+ return;
+ }
+ if (newlen < s->y) {
+ /* we are already beyond the new end, therefore move the new end */
+ newlen = s->y;
+ }
+ if (s->y > 0 && s->y0 != newlen)
+ s->newlen = 1;
+ s->y0 = newlen;
+ if (s->y == s->y0) {
+ /* we are already at the end; finish the current stripe if necessary */
+ if (s->i > 0) {
+ arith_encode_flush(&s->s);
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_SDNORM;
+ s->data_out(buf, 2, s->file);
+ s->i = 0;
+ }
+ /* output NEWLEN if there is any pending */
+ output_newlen(s);
+ }
+}
+
+
+/*
+ * Abort encoding process immediately by outputting an ABORT marker segment
+ */
+void jbg85_enc_abort(struct jbg85_enc_state *s)
+{
+ unsigned char buf[2];
+
+ buf[0] = MARKER_ESC;
+ buf[1] = MARKER_ABORT;
+ s->data_out(buf, 2, s->file);
+ s->y = s->y0; /* just to prevent further calls to jbg85_enc_lineout() */
+}
+
+
+/*
+ * Convert the error codes used by jbg85_dec_in() into an English ASCII string
+ */
+const char *jbg85_strerror(int errnum)
+{
+ errnum >>= 4;
+ if (errnum < 0 || (unsigned) errnum >= sizeof(errmsg)/sizeof(errmsg[0]))
+ return "Unknown error code passed to jbg85_strerror()";
+
+ return errmsg[errnum];
+}
+
+
+/*
+ * The constructor for a decoder
+ */
+void jbg85_dec_init(struct jbg85_dec_state *s,
+ unsigned char *buf, size_t buflen,
+ int (*line_out)(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len,
+ unsigned long y, void *file),
+ void *file)
+{
+ s->x0 = 0;
+ s->y0 = 0;
+ s->linebuf = buf;
+ s->linebuf_len = buflen;
+ s->line_out = line_out;
+ s->file = file;
+ s->bie_len = 0;
+ s->end_of_bie = 0;
+ s->x = 0;
+ s->y = 0;
+ s->i = 0;
+ s->comment_skip = 0;
+ s->buf_len = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+ s->tx = 0;
+ s->lntp = 1;
+ s->p[0] = 0;
+ s->p[1] = -1;
+ s->p[2] = -1;
+ arith_decode_init(&s->s, 0);
+ return;
+}
+
+
+/*
+ * Decode the new len PSCD bytes to which data points and output
+ * decoded lines as they are completed. Return the number of bytes
+ * which have actually been read. This will be less than len if a
+ * marker segment was part of the data or if the final byte was
+ * 0xff, meaning that this code can not determine whether we have a
+ * marker segment.
+ */
+static size_t decode_pscd(struct jbg85_dec_state *s, unsigned char *data,
+ size_t len)
+{
+ unsigned char *hp1, *hp2, *hp3, *p1;
+ register unsigned long line_h1, line_h2, line_h3;
+ unsigned long x;
+ long o;
+ unsigned a;
+ int n;
+ int pix, slntp;
+ int buflines = 3 - !!(s->options & JBG_LRLTWO);
+
+ /* forward data to arithmetic decoder */
+ s->s.pscd_ptr = data;
+ s->s.pscd_end = data + len;
+
+ /* restore a few local variables */
+ line_h1 = s->line_h1;
+ line_h2 = s->line_h2;
+ line_h3 = s->line_h3;
+ x = s->x;
+
+#ifdef DEBUG
+ if (x == 0 && s->i == 0 && s->pseudo)
+ fprintf(stderr, "decode_pscd(%p, %p, %ld)\n",
+ (void *) s, (void *) data, (long) len);
+#endif
+
+ s->intr = 0;
+ for (; s->i < s->l0 && s->y < s->y0 && !s->intr; s->i++, s->y++) {
+
+ /* pointer to image byte */
+ hp1 = s->linebuf + s->p[0] * s->bpl + (x >> 3);
+ hp2 = s->linebuf + s->p[1] * s->bpl + (x >> 3);
+ hp3 = s->linebuf + s->p[2] * s->bpl + (x >> 3);
+
+ /* adaptive template changes */
+ if (x == 0 && s->pseudo)
+ for (n = 0; n < s->at_moves; n++)
+ if (s->at_line[n] == s->i) {
+ s->tx = s->at_tx[n];
+#ifdef DEBUG
+ fprintf(stderr, "ATMOVE: line=%lu, tx=%d.\n", s->i, s->tx);
+#endif
+ }
+ assert(s->tx >= 0); /* i.e., tx can safely be cast to unsigned */
+
+ /* typical prediction */
+ if (s->options & JBG_TPBON && s->pseudo) {
+ slntp = arith_decode(&s->s, (s->options & JBG_LRLTWO) ? TPB2CX : TPB3CX);
+ if (slntp < 0)
+ goto leave;
+ s->lntp =
+ !(slntp ^ s->lntp);
+ if (!s->lntp) {
+ /* this line is 'typical' (i.e. identical to the previous one) */
+ if (s->p[1] < 0) {
+ /* first line of page or (following SDRST) of stripe */
+ for (p1 = hp1; p1 < hp1 + s->bpl; *p1++ = 0) ;
+ s->intr = s->line_out(s, hp1, s->bpl, s->y, s->file);
+ /* rotate the ring buffer that holds the last three lines */
+ s->p[2] = s->p[1];
+ s->p[1] = s->p[0];
+ if (++(s->p[0]) >= buflines) s->p[0] = 0;
+ } else {
+ s->intr = s->line_out(s, hp2, s->bpl, s->y, s->file);
+ /* duplicate the last line in the ring buffer */
+ s->p[2] = s->p[1];
+ }
+ continue;
+ }
+ /* this line is 'not typical' and has to be coded completely */
+ }
+ s->pseudo = 0;
+
+ /*
+ * Layout of the variables line_h1, line_h2, line_h3, which contain
+ * as bits the neighbour pixels of the currently decoded pixel X:
+ *
+ * 76543210 76543210 76543210 76543210 line_h3
+ * 76543210 76543210 76543210 76543210 line_h2
+ * 76543210 76543210 76543210 76543210 X line_h1
+ */
+
+ if (x == 0) {
+ line_h1 = line_h2 = line_h3 = 0;
+ if (s->p[1] >= 0)
+ line_h2 = (long)*hp2 << 8;
+ if (s->p[2] >= 0)
+ line_h3 = (long)*hp3 << 8;
+ }
+
+ /* decode line */
+ while (x < s->x0) {
+ if ((x & 7) == 0) {
+ if (x < (s->bpl - 1) * 8 && s->p[1] >= 0) {
+ line_h2 |= *(hp2 + 1);
+ if (s->p[2] >= 0)
+ line_h3 |= *(hp3 + 1);
+ }
+ }
+ if (s->options & JBG_LRLTWO) {
+ /* two line template */
+ do {
+ if (s->tx) {
+ if ((unsigned) s->tx > x)
+ a = 0;
+ else if (s->tx < 8)
+ a = ((line_h1 >> (s->tx - 5)) & 0x010);
+ else {
+ o = (x - s->tx) - (x & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 4;
+ }
+ assert(s->tx > 31 ||
+ a == ((line_h1 >> (s->tx - 5)) & 0x010));
+ pix = arith_decode(&s->s, (((line_h2 >> 9) & 0x3e0) | a |
+ (line_h1 & 0x00f)));
+ } else
+ pix = arith_decode(&s->s, (((line_h2 >> 9) & 0x3f0) |
+ (line_h1 & 0x00f)));
+ if (pix < 0)
+ goto leave;
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ } while ((++x & 7) && x < s->x0);
+ } else {
+ /* three line template */
+ do {
+ if (s->tx) {
+ if ((unsigned) s->tx > x)
+ a = 0;
+ else if (s->tx < 8)
+ a = ((line_h1 >> (s->tx - 3)) & 0x004);
+ else {
+ o = (x - s->tx) - (x & ~7L);
+ a = (hp1[o >> 3] >> (7 - (o & 7))) & 1;
+ a <<= 2;
+ }
+ assert(s->tx > 31 ||
+ a == ((line_h1 >> (s->tx - 3)) & 0x004));
+ pix = arith_decode(&s->s, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x078) | a |
+ (line_h1 & 0x003)));
+ } else
+ pix = arith_decode(&s->s, (((line_h3 >> 7) & 0x380) |
+ ((line_h2 >> 11) & 0x07c) |
+ (line_h1 & 0x003)));
+ if (pix < 0)
+ goto leave;
+ line_h1 = (line_h1 << 1) | pix;
+ line_h2 <<= 1;
+ line_h3 <<= 1;
+ } while ((++x & 7) && x < s->x0);
+ } /* if (s->options & JBG_LRLTWO) */
+ *hp1++ = line_h1;
+ hp2++;
+ hp3++;
+ } /* while (x < s->x0) */
+ *(hp1 - 1) <<= s->bpl * 8 - s->x0;
+ s->intr = s->line_out(s, s->linebuf + s->p[0] * s->bpl,
+ s->bpl, s->y, s->file);
+ x = 0;
+ s->pseudo = 1;
+ /* rotate the ring buffer that holds the last three lines */
+ s->p[2] = s->p[1];
+ s->p[1] = s->p[0];
+ if (++(s->p[0]) >= buflines) s->p[0] = 0;
+ } /* for (i = ...) */
+
+ leave:
+
+ /* save a few local variables */
+ s->line_h1 = line_h1;
+ s->line_h2 = line_h2;
+ s->line_h3 = line_h3;
+ s->x = x;
+
+ return s->s.pscd_ptr - data;
+}
+
+/*
+ * Helper routine for processing SDNORM/SDRST marker segment
+ * (which is found in s->buffer[0..1])
+ */
+static int finish_sde(struct jbg85_dec_state *s)
+{
+ /* decode final pixels based on trailing zero bytes */
+ s->s.nopadding = 0;
+ if (decode_pscd(s, s->buffer, 2) != 2 && s->intr)
+ return 1;
+
+ /* prepare decoder for next SDE */
+ arith_decode_init(&s->s, s->buffer[1] == MARKER_SDNORM);
+ s->s.nopadding = s->options & JBG_VLENGTH;
+
+ s->x = 0;
+ s->i = 0;
+ s->pseudo = 1;
+ s->at_moves = 0;
+ if (s->buffer[1] == MARKER_SDRST) {
+ s->tx = 0;
+ s->lntp = 1;
+ s->p[0] = 0;
+ s->p[1] = -1;
+ s->p[2] = -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Provide to the decoder a new BIE fragment of len bytes starting at data.
+ *
+ * Unless cnt is NULL, *cnt will contain the number of actually read bytes
+ * on return.
+ *
+ * Normal return values:
+ *
+ * JBG_EAGAIN All data bytes provided so far have been processed
+ * (*cnt == len) but the end of the data stream has
+ * not yet been recognized. Call the function again
+ * with additional BIE bytes.
+ * JBG_EOK The function has reached the end of the BIE and
+ * the full image has been decoded.
+ * JBG_EOK_INTR Parsing the BIE has been interrupted as had been
+ * requested by a non-zero return value of line_out().
+ * This function can be called again with the
+ * rest of the BIE to continue the decoding process.
+ * The remaining len - *cnt bytes of the previous
+ * data block will then have to be passed to this
+ * function again (only if len > *cnt).
+ *
+ * Any other return value indicates that the decoding process was
+ * aborted by a serious problem and the only function you can then
+ * still call is jbg85_strerror() to find out what to tell the user.
+ * (Looking at the least significant bits of the return value will
+ * provide additional information by identifying which test exactly
+ * has failed.)
+ */
+int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt)
+{
+ int required_length;
+ unsigned long y;
+ size_t dummy_cnt;
+
+ if (!cnt) cnt = &dummy_cnt;
+ *cnt = 0;
+
+ /* read in 20-byte BIH */
+ if (s->bie_len < 20) {
+ while (s->bie_len < 20 && *cnt < len)
+ s->buffer[s->bie_len++] = data[(*cnt)++];
+ if (s->bie_len < 20)
+ return JBG_EAGAIN;
+ /* parse header parameters */
+ s->x0 = (((long) s->buffer[ 4] << 24) | ((long) s->buffer[ 5] << 16) |
+ ((long) s->buffer[ 6] << 8) | (long) s->buffer[ 7]);
+ s->y0 = (((long) s->buffer[ 8] << 24) | ((long) s->buffer[ 9] << 16) |
+ ((long) s->buffer[10] << 8) | (long) s->buffer[11]);
+ s->l0 = (((long) s->buffer[12] << 24) | ((long) s->buffer[13] << 16) |
+ ((long) s->buffer[14] << 8) | (long) s->buffer[15]);
+ s->bpl = (s->x0 >> 3) + !!(s->x0 & 7); /* bytes per line */
+ s->mx = s->buffer[16];
+ s->options = s->buffer[19];
+ s->s.nopadding = s->options & JBG_VLENGTH;
+ /* test whether this looks like a valid JBIG header at all */
+ if (s->buffer[1] < s->buffer[0]) return JBG_EINVAL | 1;
+ /* are padding bits zero as required? */
+ if (s->buffer[3] != 0) return JBG_EINVAL | 2; /* padding != 0 */
+ if ((s->buffer[18] & 0xf0) != 0) return JBG_EINVAL | 3; /* padding != 0 */
+ if ((s->buffer[19] & 0x80) != 0) return JBG_EINVAL | 4; /* padding != 0 */
+ if (!s->buffer[2]) return JBG_EINVAL | 5;
+ if (!s->x0) return JBG_EINVAL | 6;
+ if (!s->y0) return JBG_EINVAL | 7;
+ if (!s->l0) return JBG_EINVAL | 8;
+ if (s->mx > 127)
+ return JBG_EINVAL | 9;
+ if (s->buffer[ 0] != 0) return JBG_EIMPL | 8; /* parameter outside T.85 */
+ if (s->buffer[ 1] != 0) return JBG_EIMPL | 9; /* parameter outside T.85 */
+ if (s->buffer[ 2] != 1) return JBG_EIMPL |10; /* parameter outside T.85 */
+ if (s->buffer[17] != 0) return JBG_EIMPL |11; /* parameter outside T.85 */
+#if JBG85_STRICT_ORDER_BITS
+ if (s->buffer[18] != 0) return JBG_EIMPL |12; /* parameter outside T.85 */
+#endif
+ if (s->options & 0x17) return JBG_EIMPL |13; /* parameter outside T.85 */
+ if (s->x0 > (s->linebuf_len / ((s->options & JBG_LRLTWO) ? 2 : 3)) * 8)
+ return JBG_ENOMEM; /* provided line buffer is too short */
+ }
+
+ /*
+ * BID processing loop
+ */
+
+ while (*cnt < len || s->end_of_bie == 1) {
+ if (s->end_of_bie == 1) s->end_of_bie = 2;
+
+ /* process floating marker segments */
+
+ /* skip COMMENT contents */
+ if (s->comment_skip) {
+ if (s->comment_skip <= len - *cnt) {
+ *cnt += s->comment_skip;
+ s->comment_skip = 0;
+ } else {
+ s->comment_skip -= len - *cnt;
+ *cnt = len;
+ }
+ continue;
+ }
+
+ /* load marker segments into s->buffer for processing */
+ if (s->buf_len > 0) {
+ assert(s->buffer[0] == MARKER_ESC);
+ /* load enough bytes to determine length of marker segment */
+ while (s->buf_len < 2 && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < 2) continue;
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT: required_length = 6; break;
+ case MARKER_ATMOVE: required_length = 8; break;
+ case MARKER_NEWLEN: required_length = 6; break;
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ if ((s->options & JBG_VLENGTH) && !s->end_of_bie) {
+ /* peek ahead whether a NEWLEN marker segment follows */
+ required_length = 2 + 1;
+ if (s->buf_len == 2 + 1 && s->buffer[2] == MARKER_ESC)
+ required_length = 2 + 2; /* SDNORM + 2 marker sequence bytes */
+ else if (s->buf_len >= 2 + 2 && s->buffer[3] == MARKER_NEWLEN)
+ required_length = 2 + 6; /* SDNORM + NEWLEN */
+ } else {
+ /* no further NEWLEN allowed or end of BIE reached */
+ required_length = 2;
+ }
+ break;
+ case MARKER_ABORT:
+ s->buf_len = 0;
+ return JBG_EABORT;
+ case MARKER_STUFF:
+ /* forward stuffed 0xff to arithmetic decoder */
+ if (decode_pscd(s, s->buffer, 2) == 2 || !s->intr)
+ s->buf_len = 0;
+ if (s->intr)
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ continue;
+ default:
+ return JBG_EMARKER;
+ }
+ /* load minimal number of additional bytes required for processing */
+ while (s->buf_len < required_length && *cnt < len)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+ if (s->buf_len < required_length) continue;
+ /* now the buffer is filled with exactly one marker segment
+ * (or in the case of SDNORM/SDRST sometimes also with
+ * two additional peek-ahead bytes) */
+ switch (s->buffer[1]) {
+ case MARKER_COMMENT:
+ s->comment_skip =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ break;
+ case MARKER_ATMOVE:
+ if (s->at_moves < JBG85_ATMOVES_MAX) {
+ s->at_line[s->at_moves] =
+ (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ s->at_tx[s->at_moves] = (signed char) s->buffer[6];
+ if (s->at_tx[s->at_moves] > (int) s->mx ||
+ (s->at_tx[s->at_moves] < ((s->options & JBG_LRLTWO) ? 5 : 3) &&
+ s->at_tx[s->at_moves] != 0) ||
+ s->buffer[7] != 0)
+ return JBG_EINVAL | 11;
+ s->at_moves++;
+ } else
+ return JBG_EIMPL | 14; /* more than JBG85_ATMOVES_MAX ATMOVES */
+ break;
+ case MARKER_NEWLEN:
+ y = (((long) s->buffer[2] << 24) | ((long) s->buffer[3] << 16) |
+ ((long) s->buffer[4] << 8) | (long) s->buffer[5]);
+ if (y > s->y0) return JBG_EINVAL | 12;
+#ifndef JBG85_TOLERATE_MULTIPLE_NEWLEN
+ if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13;
+ s->options &= ~JBG_VLENGTH;
+#endif
+ s->y0 = y;
+ break;
+
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+
+ switch (s->buf_len) {
+ case 2:
+ /* process regular SDNORM/SDRST without peek-ahead bytes */
+ if (finish_sde(s))
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ /* check whether this was the last SDE */
+ if (s->y >= s->y0) return JBG_EOK;
+ break;
+ case 2+1:
+ /* process single peek-ahead byte */
+ if (s->buffer[2] == MARKER_ESC)
+ continue; /* next time we'll have s->buf_len == 2 + 2 */
+ else {
+ /* push back the single peek-ahead PCSD byte */
+ assert(*cnt > 0);
+ (*cnt)--;
+ s->buf_len--;
+ if (finish_sde(s)) {
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ }
+ }
+ break;
+ case 2+2:
+ /* process 2-byte peek-ahead marker sequence */
+ if (s->buffer[2] == MARKER_ESC && s->buffer[3] == MARKER_NEWLEN)
+ continue; /* next time we'll have s->buf_len == 2 + 6 */
+ else {
+ if (finish_sde(s))
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ /* recycle the two peek-ahead marker sequence bytes */
+ s->buffer[0] = s->buffer[2];
+ s->buffer[1] = s->buffer[3];
+ s->buf_len = 2;
+ if (s->intr)
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ continue;
+ }
+ case 2+6:
+ /* process peek-ahead NEWLEN marker sequence */
+ y = (((long) s->buffer[4] << 24) | ((long) s->buffer[5] << 16) |
+ ((long) s->buffer[6] << 8) | (long) s->buffer[7]);
+ if (y > s->y0) return JBG_EINVAL | 12;
+ if (!(s->options & JBG_VLENGTH)) return JBG_EINVAL | 13;
+ s->y0 = y;
+ if (finish_sde(s))
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ s->buf_len = 0;
+ s->options &= ~JBG_VLENGTH;
+ /* we leave returning JBG_EOK to the following SDNORM/RST */
+ break;
+ }
+
+ if (s->intr) {
+ s->buf_len = 0;
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ }
+
+ } /* switch (s->buffer[1]) */
+ s->buf_len = 0;
+
+ } else if (*cnt < len && data[*cnt] == MARKER_ESC)
+ s->buffer[s->buf_len++] = data[(*cnt)++];
+
+ else {
+
+ /* we have found PSCD bytes */
+ *cnt += decode_pscd(s, data + *cnt, len - *cnt);
+ if (s->intr)
+ return JBG_EOK_INTR; /* line_out() requested interrupt */
+ if (*cnt < len && data[*cnt] != MARKER_ESC) {
+#ifdef DEBUG
+ fprintf(stderr, "PSCD was longer than expected, unread bytes "
+ "%02x %02x %02x %02x ...\n", data[*cnt], data[*cnt+1],
+ data[*cnt+2], data[*cnt+3]);
+#endif
+ return JBG_EINVAL | 14; /* PSCD was longer than expected */
+ }
+
+ }
+ } /* of BID processing loop 'while (*cnt < len) ...' */
+
+ return JBG_EAGAIN;
+}
+
+
+/*
+ * After the final BIE byte has been delivered to jbg85_dec_in(), it
+ * may still return with JBG_EAGAIN in case the VLENGTH=1 option was
+ * used and no NEWLEN marker section has appeared yet. This is because
+ * such a BIE is not self-terminating (i.e., there could still be a
+ * NEWLEN followed by an SDNORM or SDRST lurk after the final stripe,
+ * which needs to be processed before the final line is output, see
+ * ITU-T Recommendation T.85, Appendix I). Therefore, after the last
+ * byte has been delivered, call this routine to signal the end of the
+ * BIE. This is necessary to allow the routine to finish processing
+ * BIEs with option VLENGTH=1 that do not actually contain any NEWLEN
+ * marker section.
+ */
+int jbg85_dec_end(struct jbg85_dec_state *s)
+{
+ s->end_of_bie = 1;
+ return jbg85_dec_in(s, NULL, 0, NULL);
+}
diff --git a/thirdparty/jbigkit/libjbig/jbig85.h b/thirdparty/jbigkit/libjbig/jbig85.h
new file mode 100644
index 000000000..7bdf9a018
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig85.h
@@ -0,0 +1,173 @@
+/*
+ * Header file for the T.85 "light" version of the portable
+ * JBIG image compression library
+ *
+ * Copyright 1995-2014 -- Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#ifndef JBG85_H
+#define JBG85_H
+
+#include
+#include "jbig_ar.h"
+
+/*
+ * JBIG-KIT version number
+ */
+
+#define JBG85_VERSION "2.1"
+#define JBG85_VERSION_MAJOR 2
+#define JBG85_VERSION_MINOR 1
+
+/*
+ * JBIG-KIT licence agreement reference code:
+ * If you use JBIG-KIT under a commercial licence, please replace
+ * below the letters GPL with the reference code that you received
+ * with your licence agreement. (This code is typically a letter "A"
+ * followed by four decimal digits, e.g. "A1234".)
+ */
+
+#define JBG85_LICENCE "GPL"
+
+/*
+ * Maximum number of ATMOVEs per stripe that decoder can handle
+ */
+
+#define JBG85_ATMOVES_MAX 1
+
+#ifndef JBG_LRLTWO
+
+/*
+ * Option and order flags
+ */
+
+#define JBG_LRLTWO 0x40
+#define JBG_VLENGTH 0x20
+#define JBG_TPBON 0x08
+
+/*
+ * Possible error code return values
+ */
+
+#define JBG_EOK (0 << 4)
+#define JBG_EOK_INTR (1 << 4)
+#define JBG_EAGAIN (2 << 4)
+#define JBG_ENOMEM (3 << 4)
+#define JBG_EABORT (4 << 4)
+#define JBG_EMARKER (5 << 4)
+#define JBG_EINVAL (6 << 4)
+#define JBG_EIMPL (7 << 4)
+
+#endif
+
+/*
+ * Status of a JBIG encoder
+ */
+
+struct jbg85_enc_state {
+ unsigned long x0, y0; /* size of the input image */
+ unsigned long l0; /* number of lines per stripe */
+ int options; /* encoding parameters */
+ int newlen; /* 0 = jbg85_enc_newlen() has not yet been called
+ 1 = jbg85_enc_newlen() has updated y0, NEWLEN pending
+ 2 = NEWLEN has already been output */
+ unsigned mx; /* maximum ATMOVE window size */
+ unsigned long y; /* next line number to be encoded */
+ unsigned long i; /* next per-stripe line number to be encoded */
+ int tx; /* x-offset of adaptive template pixel */
+ unsigned long c_all, c[128]; /* adaptive template algorithm variables */
+ int new_tx; /* -1 = no ATMOVE pending, otherwise new TX value */
+ int ltp_old; /* true if line y-1 was "typical" */
+ struct jbg_arenc_state s; /* arithmetic encoder status */
+ void (*data_out)(unsigned char *start, size_t len, void *file);
+ /* data write callback */
+ void *file; /* parameter passed to data_out() */
+ unsigned char *comment; /* content of comment marker segment to be added
+ at next opportunity (will be reset to NULL
+ as soon as comment has been written) */
+ unsigned long comment_len; /* length of data pointed to by comment */
+};
+
+
+/*
+ * Status of a JBIG decoder
+ */
+
+struct jbg85_dec_state {
+ /* data from BIH */
+ unsigned long x0, y0; /* size of the full image */
+ unsigned long l0; /* number of lines per stripe */
+ int options; /* encoding parameters */
+ int mx; /* maximum ATMOVE window size */
+ /* image data */
+ int p[3]; /* curr. line starts at linebuf+bpl*p[0], prev. line starts
+ * at linebuf+bpl*p[1], its predecessor at linebuf+bpl*p[2] */
+ unsigned char *linebuf; /* buffer region provided by caller */
+ size_t linebuf_len;
+ size_t bpl; /* bytes per line */
+ /* status information */
+ int tx; /* x-offset of AT pixel */
+ struct jbg_ardec_state s; /* arithmetic decoder status */
+ unsigned long bie_len; /* number of bytes read so far */
+ unsigned char buffer[20]; /* used to store BIH or marker segments fragm. */
+ int buf_len; /* number of bytes in buffer */
+ unsigned long comment_skip; /* remaining bytes of a COMMENT segment */
+ unsigned long x; /* x position of next pixel */
+ unsigned long stripe; /* current stripe */
+ unsigned long y; /* line in image (first line is 0) */
+ unsigned long i; /* line in current stripe (first line of stripe is 0) */
+ int at_moves; /* number of AT moves in the current stripe */
+ unsigned long at_line[JBG85_ATMOVES_MAX]; /* lines at which an *
+ * AT move will happen */
+ int at_tx[JBG85_ATMOVES_MAX]; /* ATMOVE x-offsets in current stripe */
+ unsigned long line_h1, line_h2, line_h3; /* variables of decode_pscd */
+ int pseudo; /* flag for TPBON/TPDON: next pixel is pseudo pixel */
+ int lntp; /* flag for TP: line is not typical */
+ int (*line_out)(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len,
+ unsigned long y, void *file);
+ /* data write callback */
+ void *file; /* parameter passed to data_out() */
+ int intr; /* flag that line_out requested interrupt */
+ int end_of_bie; /* flag that the end of the BIE has been signalled */
+};
+
+
+/* function prototypes */
+
+void jbg85_enc_init(struct jbg85_enc_state *s,
+ unsigned long x0, unsigned long y0,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file);
+void jbg85_enc_options(struct jbg85_enc_state *s, int options,
+ unsigned long l0, int mx);
+void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line,
+ unsigned char *prevline, unsigned char *prevprevline);
+void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long y0);
+void jbg85_enc_abort(struct jbg85_enc_state *s);
+
+void jbg85_dec_init(struct jbg85_dec_state *s,
+ unsigned char *buf, size_t buflen,
+ int (*line_out)(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len,
+ unsigned long y, void *file),
+ void *file);
+int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt);
+int jbg85_dec_end(struct jbg85_dec_state *s);
+const char *jbg85_strerror(int errnum);
+
+/* some macros for examining decoder state */
+
+#define jbg85_dec_finished(s) ((s)->bie_len == 20 && (s)->y >= (s)->y0)
+/* enquire about image size */
+#define jbg85_dec_getwidth(s) ((s)->x0)
+#define jbg85_dec_getheight(s) ((s)->y0)
+/* enquire about validity of image-size results */
+#define jbg85_dec_validwidth(s) ((s)->bie_len == 20)
+#define jbg85_dec_finalheight(s) ((s)->bie_len == 20 && \
+ ((((s)->options & JBG_VLENGHT) == 0) || \
+ ((s)->y >= (s)->y0)))
+
+#endif /* JBG85_H */
diff --git a/thirdparty/jbigkit/libjbig/jbig85.txt b/thirdparty/jbigkit/libjbig/jbig85.txt
new file mode 100644
index 000000000..fc2d6fa6f
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig85.txt
@@ -0,0 +1,618 @@
+
+Using the T.85 "light" version of the JBIG-KIT library
+------------------------------------------------------
+
+Markus Kuhn -- 2008-08-30
+
+
+This text explains how to use the functions provided by the JBIG-KIT
+portable image compression library jbig85.c in your application
+software.
+
+
+1 Distinguishing features
+
+The jbig85.c library implements only the "single-progression
+sequential coding" subset of the JBIG1 standard, which is defined in
+ITU-T Recommendation T.85 , also
+known as the "facsimile application profile". This means that the
+JBIG1 data streams that the jbig85.c library can process can have
+
+ - no progressive encoding, i.e. the image is always encoded in a
+ single resolution layer (and not as a sequence of layers of a
+ resolution pyramid);
+
+ - only a single plane, i.e. the raw data are black/white images with
+ only one bit per pixel information.
+
+The jbig85.c library is not suitable for continuous-tone (colour or
+grey-scale) image applications, including the fax method described in
+ITU-R Recommendation T.43. For these applications, use the full jbig.c
+library instead.
+
+The T.85 restrictions are sufficient for black/white fax transmission
+and several other common bi-level image applications (printer drivers,
+document archiving, etc.). They simplify the design of the encoder and
+decoder and allow the jbig85.c library to provide several advantages
+over the full-featured jbig.c:
+
+ - Only the last three lines of the uncompressed image need to be
+ kept in RAM at any time.
+
+ - All memory allocation is done outside the jbig85.c library, which
+ performs no calls to malloc(), free(), etc.
+
+ - The implementation can handle images whose height (number of pixel
+ rows) is not yet known before the last line has been encoded or
+ decoded.
+
+ - All usage modes of the NEWLEN marker segment are supported,
+ including a NEWLEN occurring after the final stripe, as required by
+ ITU-T Recommendation T.85, using only a single pass over the data.
+
+ - The code is smaller and there is no need to store tables related
+ to the resolution-reduction algorithms.
+
+This makes the jbig85.c library particularly suited for very small
+embedded applications, e.g. low-end fax machines, along with the fact
+that the library is non-recursive and requires only a very small stack
+(typically just a bit over 100 bytes on a 32-bit system). The jbig85.c
+library may also be a good choice where very large black/white images
+are processed.
+
+The jbig85.c and jbig.c libraries both can be linked simultaneously
+with the same application if you #include jbig85.h after jbig.h into
+your source code.
+
+
+2 Introduction to JBIG (T.85 subset)
+
+We start with a short introduction to the T.85 subset of JBIG1. More
+detailed information is provided in the "Introduction and overview"
+section of the JBIG1 standard. Information on how to obtain a copy of
+the standard is available from
+or .
+
+The JBIG1 standard allows the encoder to divide an image into several
+horizontal stripes. All stripes have equal size, except perhaps the
+final one.
+
+The compressed data stream specified by the JBIG standard is called a
+bi-level image entity (BIE). A BIE consists of a 20-byte header,
+followed by a sequence of stripe data entities (SDE). Each SDE encodes
+the content of one single stripe in one plane of one resolution layer.
+Between the SDEs, other information blocks (called floating marker
+segments) can also be present. They are used to change certain
+parameters of the algorithm in the middle of an image or contain
+additional application specific information. A BIE looks like this:
+
+
+ +------------------------------------------------+
+ | |
+ | 20-byte header (specifying image size, stripe |
+ | size, and options) |
+ | |
+ +------------------------------------------------+
+ | |
+ | optional floating marker segments |
+ | |
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+ | |
+ | optional floating marker segments |
+ | |
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+ ...
+ +------------------------------------------------+
+ | |
+ | stripe data entity |
+ | |
+ +------------------------------------------------+
+
+It is possible to use the raw BIE data stream as specified by the JBIG
+standard directly as the format of a file used for storing images.
+This is what the pbmtojbg, jbgtopbm, pbmtojbg85, and jbgtopbm85
+conversion tools do that are provided in this package as demonstration
+applications. However, as the BIE format has been designed for a large
+number of very different applications, and to allow efficient direct
+processing by special JBIG hardware chip implementations, the BIE
+header contains only the minimum amount of information absolutely
+required by the decompression algorithm. Many features expected from a
+good file format are missing in the BIE data stream:
+
+ - no "magic code" in the first few bytes to allow identification
+ of the file format on a typeless file system and to allow
+ automatic distinction from other compression algorithms
+
+ - no standardized way to encode additional information such as a
+ textual description, the physical size and resolution of the
+ document, etc.
+
+ - a checksum to ensure image integrity
+
+ - encryption and signature mechanisms
+
+ - many things more
+
+Raw BIE data streams alone may therefore not be a suitable format for
+document archiving and exchange. A standard format for this purpose
+would typically combine a BIE representing the image data with an
+additional header providing auxiliary information into one file.
+Existing established multi-purpose file formats with a rich set of
+auxiliary information attributes like TIFF could be extended easily to
+also hold JBIG compressed data.
+
+On the other hand, in e.g. database applications, a BIE might be
+stored directly in a binary variable-length field. Auxiliary
+information would then be stored in other fields of the same record,
+to simplify search operations.
+
+
+2 Compressing an image
+
+2.1 Format of the source image
+
+To be processed by the jbig85.c encoder, the image has to be present
+in memory a bitmap. Each byte of a bitmap contains eight pixels, where
+the most significant bit represents the leftmost of these. Each line
+of a bitmap has to be stored in an integral number of bytes. If the
+image width is not an integral multiple of eight, then the final byte
+has to be padded with zero bits.
+
+For example the 23x5 pixels large single plane image:
+
+ .XXXXX..XXX...X...XXX..
+ .....X..X..X..X..X.....
+ .....X..XXX...X..X.XXX.
+ .X...X..X..X..X..X...X.
+ ..XXX...XXX...X...XXX..
+
+is represented by the 15 bytes
+
+ 01111100 11100010 00111000
+ 00000100 10010010 01000000
+ 00000100 11100010 01011100
+ 01000100 10010010 01000100
+ 00111000 11100010 00111000
+
+or in hexadecimal notation
+
+ 7c e2 38 04 92 40 04 e2 5c 44 92 44 38 e2 38
+
+This is the format used in binary PBM files and it can also be handled
+directly by the Xlib library of the X Window System.
+
+The standard recommends that a 0 pixel represents the background and a
+1 pixel represents the foreground colour of an image, in other words, 0
+is white and 1 is black for scanned paper documents.
+
+
+2.2 A simple compression application
+
+In order to use jbig85.c in your application, just link your
+executable with both jbig85.c and jbig_ar.c. Both are already combined
+into libjbig85.a by the provided Makefile, so on Unix systems, just
+add -ljbig85 and -L. to the command line options of your compiler. On
+other systems you will probably have to write a new Makefile. Make
+sure your compiler can find the file jbig85.h and put the line
+
+ #include "jbig85.h"
+
+into your source code.
+
+The library interface follows object-oriented programming principles.
+You have to declare a variable (object)
+
+ struct jbg85_enc_state s;
+
+which contains the current status of an encoder. Then you initialize
+the encoder by calling
+
+ void jbg85_enc_init(struct jbg85_enc_state *s,
+ unsigned long x, unsigned long y,
+ void (*data_out)(unsigned char *start, size_t len,
+ void *file),
+ void *file);
+
+The parameters have the following meaning:
+
+ s A pointer to the jbg85_enc_state structure that you want
+ to initialize.
+
+ x The width of your image in pixels.
+
+ y The height of your image in pixels (lines). This can be
+ a larger value than the actual height of the image, or
+ even 2^32-1 (or equally -1), if the height of the
+ image is not yet known. In that case, leave the
+ JBG_VLENGTH option set (see below) and call
+ jbg85_enc_newlen() as soon as the actual image height
+ is known.
+
+ data_out This is a call-back function that the encoder will
+ call during the compression process in order to
+ deliver the BIE data to your application. The
+ parameters of the function data_out are a pointer
+ start to the new block of data being delivered, as
+ well as the number len of delivered bytes. The pointer
+ file is transparently delivered to data_out, as
+ specified in jbg85_enc_init(). Typically, data_out
+ will write the BIE portion to a file, send it to a
+ network connection, or append it to some memory
+ buffer.
+
+ file A pointer parameter that is passed on to data_out()
+ and can be used, for instance, to allow data_out() to
+ distinguish by which compression task it has been
+ called in multi-threaded applications.
+
+The compression can then be started by calling the function
+
+ void jbg85_enc_lineout(struct jbg85_enc_state *s, unsigned char *line,
+ unsigned char *prevline, unsigned char *prevprevline);
+
+successively for each line of the image, top to bottom. The parameters
+are:
+
+ line A pointer to the first byte of the line to be encoded.
+
+ prevline A pointer to the data that the line parameter pointed
+ to in the previous call. The value will be ignored
+ if this is the first call.
+
+ prevprevline A pointer to the data that the prevline parameter pointed
+ to in the previous call. The value will be ignored
+ if this is the first or second call.
+
+After jbg85_enc_lineout() has been called for all lines of the image,
+the complete BIE will have been delivered via several callbacks to
+data_out(). These BIE bytes are delivered as soon as possible, as the
+encoder cannot buffer more than a few bytes internally.
+
+A minimal example application, which sends the BIE of the above bitmap
+to stdout, looks like this:
+
+---------------------------------------------------------------------------
+/* A sample JBIG T.85 encoding application */
+
+#include
+#include "jbig85.h"
+
+void output_bie(unsigned char *start, size_t len, void *file)
+{
+ fwrite(start, 1, len, (FILE *) file);
+
+ return;
+}
+
+int main()
+{
+ unsigned char bitmap[15] = {
+ /* 23 x 5 pixels, "JBIG" */
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2,
+ 0x5c, 0x44, 0x92, 0x44, 0x38, 0xe2, 0x38
+ };
+ struct jbg85_enc_state se;
+ int i;
+
+ jbg85_enc_init(&se, 23, 5, output_bie, stdout); /* initialize encoder */
+ jbg85_enc_options(&se, JBG_TPBON, 0, -1); /* clear JBG_VLENGTH option */
+ for (i = 0; i < 5; i++) {
+ /* encode line */
+ jbg85_enc_lineout(&se, bitmap+i*3, bitmap+(i-1)*3, bitmap+(i-2)*3);
+ }
+
+ return 0;
+}
+---------------------------------------------------------------------------
+
+This software produces a 37 byte long BIE. (JBIG is not very good at
+compressing extremely small images like in this example, because the
+arithmetic encoder requires some startup data in order to generate
+reasonable statistics which influence the compression process and
+because there is some header overhead.)
+
+
+2.3 More about compression
+
+If jbg85_enc_lineout() is called directly after jbg85_enc_init(), the
+following default values are used for various compression parameters:
+
+ - The number of lines per stripe (l0) is set to 128, which is the
+ T.85 BASIC setting.
+
+ - The typical-prediction (TPBON) and variable-length (VLENGTH) options
+ are activated, but the two-line template (LRLTWO) option is not.
+
+ - The maximal horizontal offset of the adaptive template pixel is 127
+ (mx = 127, my = 0).
+
+In order to change any of these default parameters, an additional
+function has to be called between jbg85_enc_init() and the first
+jbg85_enc_lineout():
+
+ void jbg85_enc_options(struct jbg85_enc_state *s, int options,
+ unsigned long l0, int mx)
+
+The options value can contain the following bits, which activate some
+of the optional algorithms defined by JBIG:
+
+ JBG_LRLTWO This option bit changes the JBIG algorithm such that the
+ context in which the probability of a pixel is
+ estimated includes only the previous line (two-line
+ template), rather than the previous two lines
+ (three-line template). This option is off by default
+ and the author cannot think of a good reason to set it.
+ [Some people in the JBIG committee seem to have
+ argued that using a two-line template will make
+ software implementations a little bit faster, while
+ others have argued that using only two lines will
+ decrease compression efficiency by around 5%. As you
+ might expect from a committee, now both alternatives
+ are allowed (and add to the implementation and testing
+ complexity of every decoder).]
+
+ JBG_TPBON This bit activates the "typical prediction" algorithm. It
+ is set by default. Typical prediction means that JBIG
+ prefixes each line to be encoded with a "pseudopixel"
+ that indicates if the line is identical to the
+ previous line, and skips encoding the line if it is.
+ This helps to encode empty parts of a page very
+ efficiently in just a few bytes, therefore this
+ option should be left on. (The only reason the author
+ could think of for ever deactivating this option is
+ if you know in advance that there will never be two
+ identical lines follow each other in the image to be
+ encoded, in which case deactivating this option might
+ provide a tiny performance improvement.)
+
+ JBG_VLENGTH This bit indicates that the image height y provided
+ to jbg85_enc_init() was only an estimate and may
+ be lowered sometimes during the encoding process
+ using a call to jbg85_enc_newlen(). This feature
+ is intended for fax machines that start transmitting
+ a page while still scanning it and without knowing
+ how long the page is going to be.
+
+Value -1 for options keeps the current setting, the default is
+JBG_TPBON | JBG_VLENGTH.
+
+The other parameters are:
+
+ l0 Sets the number of lines per stripe (valid range:
+ 1 to 2^32-1, default 128, value 0 keeps the current
+ setting).
+
+ mx Changes the maximal offset allowed for the adaptive
+ template pixel (valid range: 0 to 127, default 127,
+ value -1 keeps the current setting).
+
+If the JBG_VLENGTH option was set, then you can call at any time the
+function
+
+ void jbg85_enc_newlen(struct jbg85_enc_state *s, unsigned long newlen)
+
+in order to announce the actual height of the image. You can call this
+function only once per image, and the provided new height value newlen
+must not be larger than the estimate y originally provided. It is good
+practice to call jbg85_enc_newlen() as soon as the height of the image
+is known. However, it is even possible to call it after the last line
+has already been encoded using jbg85_enc_lineout(). The latter case
+will result in a somewhat odd BIE, where an additional empty stripe
+has to be appended just to announce the new length. This is not pretty
+and was not described in great detail in the original JBIG1 standard,
+but decoders are required by ITU-T T.85 to understand even this
+extremely late announcement of the end of the image.
+
+If the image height y initially given to jbg85_enc_init() is already
+the correct final value and you will therefore never call
+jbg85_enc_newlen(), then it is good practice to clear the JBG_VLENGTH
+option bit, which is set by default, e.g. by calling
+
+ jbg85_enc_options(&s, JBG_TPBON, 0, -1);
+
+between jbg85_enc_init() and jbg85_enc_lineout().
+
+The JBIG standard also has a provision for aborting a BIE with a
+special abort marker segment, and calling
+
+ void jbg85_enc_abort(struct jbg85_enc_state *s);
+
+does that. This is probably only needed if there is no other way
+(e.g., end-of-file) of telling the decoder that no further data bytes
+will be coming.
+
+
+3 Decompressing an image
+
+Like with the compression functions, if you want to use the jbig85.c
+library, you have to put the line
+
+ #include "jbig85.h"
+
+into your source code and link your executable with libjbig85.a.
+
+The state of a JBIG decoder is stored completely in a struct and you
+will have to define a variable like
+
+ struct jbg85_dec_state s;
+
+which is initialized by a call to
+
+ void jbg85_dec_init(struct jbg85_dec_state *s,
+ unsigned char *buf, size_t buflen,
+ int (*line_out)(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len,
+ unsigned long y, void *file),
+ void *file);
+
+The parameters are:
+
+ buf A memory buffer that is long enough to store up to
+ three lines of the image. This buffer will be used
+ by the decoder to temporarily store decoded lines.
+ If the decoded image uses the LRLTWO option, the buffer
+ has to be only sufficient for two uncompressed
+ image lines.
+
+ buflen The length in bytes of the buffer area to which buf
+ points. Knowing this value prevents accidental buffer
+ overflows and allows the decoder to abort with
+ JBG_ENOMEM if the provided buffer was too small, once
+ it knows the width of the image to be decoded from
+ parsing its 20-byte header. If xmax is the expected
+ maximum width of the image in pixels, then buflen
+ should be at least ((xmax >> 3) + !!(xmax & 7)) * 3
+ bytes. [If only BIEs with option LRLTWO set will be
+ received, then ((xmax >> 3) + !!(xmax & 7)) * 2
+ bytes will be sufficient.]
+
+ line_out This call-back function will be used whenever the decoder
+ has completed another line. The start parameter will
+ point to the location in buf where the len bytes of
+ the just decoded line reside. The line_out() function
+ has to read (and copy or output) this line, but it is
+ not allowed to modify it in-place, as the decoder will
+ also need to access it while decoding the following
+ two lines. The parameter y is just the line number
+ (starting from 0) and file is the jbg85_dec_init()
+ parameter of the same name passed on. The normal
+ return value of line_out is zero; a non-zero value
+ can be returned to request an interrupt of the decoding
+ process (see discussion of JBG_EOK_INTR below).
+
+ file A pointer parameter that is passed on to line_out()
+ and can be used, for instance, to allow line_out() to
+ distinguish by which compression task it has been
+ called in multi-threaded applications.
+
+After this, you can directly start to pass data from the BIE to the decoder
+by calling the function
+
+ int jbg85_dec_in(struct jbg85_dec_state *s, unsigned char *data, size_t len,
+ size_t *cnt);
+
+The pointer data points to the first byte of a data block with length
+len, which contains bytes from a BIE. It is not necessary to pass a
+whole BIE at once to jbg85_dec_in(), it can arrive fragmented in any
+way by calling jbg85_dec_in() several times. Only a single BIE can be
+delivered via jbg85_dec_in() calls and the decoder has to be
+reinitialized with jbg85_dec_init() before it is ready to accept
+another BIE.
+
+If pointer cnt is not NULL, then the number of bytes actually read
+from the data block will be stored there. In case the decoder did not
+recognize the end of the BIE in the data block, then the value
+JBG_EAGAIN will be returned and *cnt equals len.
+
+Once the end of a BIE has been reached, the return value of
+jbg85_dec_in() will be JBG_EOK.
+
+The decoder can recognize the end of a BIE only if either the VLENGTH
+option is not set, or if there has been a NEWLEN marker segment before
+the start of the last stripe. Otherwise, the decoder cannot know
+whether there is or is not a NEWLEN marker segment following the last
+stripe. For this reason, jbg85_dec_in() can return JBG_EAGAIN even
+though you have already given it the last byte of the BIE. In this
+case, call
+
+ int jbg85_dec_end(struct jbg85_dec_state *s);
+
+to explicitely signal to the decoder that it has already received all
+bytes of the BIE. This function will then output any remaining lines
+and return JBG_EOK if no problem has occurred.
+
+The macros
+
+ unsigned long jbg85_dec_getwidth(struct jbg85_dec_state *s);
+ unsigned long jbg85_dec_getheight(struct jbg85_dec_state *s);
+
+can be used to query the dimensions of the image. The width will be
+known already after the first 20 bytes of the BIE have been provided,
+and also during the first callback to line_out(). But the height might
+not have reached its final value before jbg85_dec_in() has returned
+JBG_EOK. The additional boolean macros
+
+ int jbg85_dec_validwidth(struct jbg85_dec_state *s);
+ int jbg85_dec_finalheight(struct jbg85_dec_state *s);
+ int jbg85_dec_finished(struct jbg85_dec_state *s);
+
+tell, whether the width and final height are already known, and
+whether the decoder has finished outputting all lines.
+
+If one of the callbacks to line_out() provides a non-zero return
+value, then the decoder will interrupt the decoding process and
+jbg85_dec_in() or jbg85_dec_end() will return JBG_EOK_INTR. This
+feature might be useful to stop the decoding process temporarily, e.g.
+to load a new sheet of paper, where performing this task is
+inconvenient to complete inside line_out(). It is then possible to
+continue calling jbg85_dec_in() with the remaining data (or
+jbg85_dec_end() if there isn't any left) in order to decode the
+remaining lines of the BIE. After jbg85_dec_in() returned
+JBG_EOK_INTR, *cnt is probably not equal to len and the remainder of
+the data block which has not yet been processed by the decoder has to
+be delivered to jbg85_dec_in() again. Any line that has already been
+delivered to line_out() will not be delivered again.
+
+If any other return value than JBG_EOK, JBG_EOK_INTR or JBG_EAGAIN has
+been returned by jbg85_dec_in() or jbg85_dec_end(), then an error has
+occurred and the decoding process has been aborted. The function
+
+ const char *jbg85_strerror(int errnum);
+
+returns a pointer to a short single-line test message that explains
+the return value of jbg85_dec_in() or jbg85_dec_end(). This message
+can be used in order to provide the user a brief informative message
+about what when wrong while decompressing a JBIG image. The po/
+subdirectory contains *.po files that translate the English ASCII
+strings returned by jbg85_strerror() into other languages (e.g., for
+use with GNU gettext). The four least-significant bits of the return
+value of jbg85_dec_in() or jbg85_dec_end() may contain additional
+detailed technical information about the exact test that spotted the
+error condition (see source code for details), i.e. more than the text
+message returned by jbg85_strerror() reveals. Therefore it may be
+useful to display the return value itself as a hexadecimal number, in
+addition to the string returned by jbg85_strerror().
+
+
+4 Additional notes
+
+The following remarks will not affect the normal user of the library
+but might be of interest to some users who have to deal with exotic
+cases, in particular dealing with broken non-JBIG-KIT encoders out
+there:
+
+ - There has been one report about malformed BIEs produced by another
+ JBIG implementation that violates the standard by containing
+ several NEWLEN marker segments in the same BIE. The jbig85.c
+ decoder will normally abort with JBG_EINVALID when it encounters
+ such an illegal BIE. The compile-time option
+ JBG85_TOLERATE_MULTIPLE_NEWLEN can be used to make the decoder
+ more tolerant to this type of syntax error.
+
+ - Even though the T.85 standard prescribes all-zero values for the
+ order bits HITOLO, SEQ, ILEAVE, SMID, the jbig85.c decoder will
+ not complain about any other values of these bits, as they do not
+ affect the decoding process when there is only a single plane and
+ resolution layer (the only case supported by this decoder). The
+ compile-time option JBG85_STRICT_ORDER_BITS will make the decoder
+ less tolerant and abort with JBG_EIMPL if the received order bits
+ do not comply with the T.85 "single-progression sequential coding"
+ requirements.
+
+ - The T.85 standard allows only a single ATMOVE marker segment per
+ SDE, and the jbig85.c decoder enforces this limit by default. This
+ limit can be increased by setting JBG85_ATMOVES_MAX in jbig85.h to
+ the desired value. The encoder will never output more than a
+ single ATMOVE marker segment per stripe.
+
+*** Happy decompressing ***
+
+[end]
diff --git a/thirdparty/jbigkit/libjbig/jbig_ar.c b/thirdparty/jbigkit/libjbig/jbig_ar.c
new file mode 100644
index 000000000..32e5bf64d
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig_ar.c
@@ -0,0 +1,417 @@
+/*
+ * Arithmetic encoder and decoder of the portable JBIG
+ * compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ *
+ * This module implements a portable standard C arithmetic encoder
+ * and decoder used by the JBIG lossless bi-level image compression
+ * algorithm as specified in International Standard ISO 11544:1993
+ * and ITU-T Recommendation T.82.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * If you want to use this program under different license conditions,
+ * then contact the author for an arrangement.
+ */
+
+#include
+#include "jbig_ar.h"
+
+/*
+ * Probability estimation tables for the arithmetic encoder/decoder
+ * given by ITU T.82 Table 24.
+ */
+
+static short lsztab[113] = {
+ 0x5a1d, 0x2586, 0x1114, 0x080b, 0x03d8, 0x01da, 0x00e5, 0x006f,
+ 0x0036, 0x001a, 0x000d, 0x0006, 0x0003, 0x0001, 0x5a7f, 0x3f25,
+ 0x2cf2, 0x207c, 0x17b9, 0x1182, 0x0cef, 0x09a1, 0x072f, 0x055c,
+ 0x0406, 0x0303, 0x0240, 0x01b1, 0x0144, 0x00f5, 0x00b7, 0x008a,
+ 0x0068, 0x004e, 0x003b, 0x002c, 0x5ae1, 0x484c, 0x3a0d, 0x2ef1,
+ 0x261f, 0x1f33, 0x19a8, 0x1518, 0x1177, 0x0e74, 0x0bfb, 0x09f8,
+ 0x0861, 0x0706, 0x05cd, 0x04de, 0x040f, 0x0363, 0x02d4, 0x025c,
+ 0x01f8, 0x01a4, 0x0160, 0x0125, 0x00f6, 0x00cb, 0x00ab, 0x008f,
+ 0x5b12, 0x4d04, 0x412c, 0x37d8, 0x2fe8, 0x293c, 0x2379, 0x1edf,
+ 0x1aa9, 0x174e, 0x1424, 0x119c, 0x0f6b, 0x0d51, 0x0bb6, 0x0a40,
+ 0x5832, 0x4d1c, 0x438e, 0x3bdd, 0x34ee, 0x2eae, 0x299a, 0x2516,
+ 0x5570, 0x4ca9, 0x44d9, 0x3e22, 0x3824, 0x32b4, 0x2e17, 0x56a8,
+ 0x4f46, 0x47e5, 0x41cf, 0x3c3d, 0x375e, 0x5231, 0x4c0f, 0x4639,
+ 0x415e, 0x5627, 0x50e7, 0x4b85, 0x5597, 0x504f, 0x5a10, 0x5522,
+ 0x59eb
+};
+
+static unsigned char nmpstab[113] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 13, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 9, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 32,
+ 65, 66, 67, 68, 69, 70, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 48,
+ 81, 82, 83, 84, 85, 86, 87, 71,
+ 89, 90, 91, 92, 93, 94, 86, 96,
+ 97, 98, 99, 100, 93, 102, 103, 104,
+ 99, 106, 107, 103, 109, 107, 111, 109,
+ 111
+};
+
+/*
+ * least significant 7 bits (mask 0x7f) of nlpstab[] contain NLPS value,
+ * most significant bit (mask 0x80) contains SWTCH bit
+ */
+static unsigned char nlpstab[113] = {
+ 129, 14, 16, 18, 20, 23, 25, 28,
+ 30, 33, 35, 9, 10, 12, 143, 36,
+ 38, 39, 40, 42, 43, 45, 46, 48,
+ 49, 51, 52, 54, 56, 57, 59, 60,
+ 62, 63, 32, 33, 165, 64, 65, 67,
+ 68, 69, 70, 72, 73, 74, 75, 77,
+ 78, 79, 48, 50, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 61, 61,
+ 193, 80, 81, 82, 83, 84, 86, 87,
+ 87, 72, 72, 74, 74, 75, 77, 77,
+ 208, 88, 89, 90, 91, 92, 93, 86,
+ 216, 95, 96, 97, 99, 99, 93, 223,
+ 101, 102, 103, 104, 99, 105, 106, 107,
+ 103, 233, 108, 109, 110, 111, 238, 112,
+ 240
+};
+
+/*
+ * The next functions implement the arithmedic encoder and decoder
+ * required for JBIG. The same algorithm is also used in the arithmetic
+ * variant of JPEG.
+ */
+
+/* marker codes */
+#define MARKER_STUFF 0x00
+#define MARKER_ESC 0xff
+
+void arith_encode_init(struct jbg_arenc_state *s, int reuse_st)
+{
+ int i;
+
+ if (!reuse_st)
+ for (i = 0; i < 4096; s->st[i++] = 0) ;
+ s->c = 0;
+ s->a = 0x10000L;
+ s->sc = 0;
+ s->ct = 11;
+ s->buffer = -1; /* empty */
+
+ return;
+}
+
+
+void arith_encode_flush(struct jbg_arenc_state *s)
+{
+ unsigned long temp;
+
+ /* find the s->c in the coding interval with the largest
+ * number of trailing zero bits */
+ if ((temp = (s->a - 1 + s->c) & 0xffff0000L) < s->c)
+ s->c = temp + 0x8000;
+ else
+ s->c = temp;
+ /* send remaining bytes to output */
+ s->c <<= s->ct;
+ if (s->c & 0xf8000000L) {
+ /* one final overflow has to be handled */
+ if (s->buffer >= 0) {
+ s->byte_out(s->buffer + 1, s->file);
+ if (s->buffer + 1 == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ /* output 0x00 bytes only when more non-0x00 will follow */
+ if (s->c & 0x7fff800L)
+ for (; s->sc; --s->sc)
+ s->byte_out(0x00, s->file);
+ } else {
+ if (s->buffer >= 0)
+ s->byte_out(s->buffer, s->file);
+ /* T.82 figure 30 says buffer+1 for the above line! Typo? */
+ for (; s->sc; --s->sc) {
+ s->byte_out(0xff, s->file);
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ }
+ /* output final bytes only if they are not 0x00 */
+ if (s->c & 0x7fff800L) {
+ s->byte_out((s->c >> 19) & 0xff, s->file);
+ if (((s->c >> 19) & 0xff) == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ if (s->c & 0x7f800L) {
+ s->byte_out((s->c >> 11) & 0xff, s->file);
+ if (((s->c >> 11) & 0xff) == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ }
+
+ return;
+}
+
+
+void arith_encode(struct jbg_arenc_state *s, int cx, int pix)
+{
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ long temp;
+
+ assert(cx >= 0 && cx < 4096);
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = lsztab[ss];
+
+#if 0
+ fprintf(stderr, "pix = %d, cx = %d, mps = %d, st = %3d, lsz = 0x%04x, "
+ "a = 0x%05lx, c = 0x%08lx, ct = %2d, buf = 0x%02x\n",
+ pix, cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct,
+ s->buffer);
+#endif
+
+ if (((pix << 7) ^ s->st[cx]) & 0x80) {
+ /* encode the less probable symbol */
+ if ((s->a -= lsz) >= lsz) {
+ /* If the interval size (lsz) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency, otherwise code the LPS
+ * as usual: */
+ s->c += s->a;
+ s->a = lsz;
+ }
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= nlpstab[ss];
+ } else {
+ /* encode the more probable symbol */
+ if ((s->a -= lsz) & 0xffff8000L)
+ return; /* A >= 0x8000 -> ready, no renormalization required */
+ if (s->a < lsz) {
+ /* If the interval size (lsz) for the less probable symbol (LPS)
+ * is larger than the interval size for the MPS, then exchange
+ * the two symbols for coding efficiency: */
+ s->c += s->a;
+ s->a = lsz;
+ }
+ /* chose next probability estimator status */
+ *st &= 0x80;
+ *st |= nmpstab[ss];
+ }
+
+ /* renormalization of coding interval */
+ do {
+ s->a <<= 1;
+ s->c <<= 1;
+ --s->ct;
+ if (s->ct == 0) {
+ /* another byte is ready for output */
+ temp = s->c >> 19;
+ if (temp & 0xffffff00L) {
+ /* handle overflow over all buffered 0xff bytes */
+ if (s->buffer >= 0) {
+ ++s->buffer;
+ s->byte_out(s->buffer, s->file);
+ if (s->buffer == MARKER_ESC)
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ for (; s->sc; --s->sc)
+ s->byte_out(0x00, s->file);
+ s->buffer = temp & 0xff; /* new output byte, might overflow later */
+ assert(s->buffer != 0xff);
+ /* can s->buffer really never become 0xff here? */
+ } else if (temp == 0xff) {
+ /* buffer 0xff byte (which might overflow later) */
+ ++s->sc;
+ } else {
+ /* output all buffered 0xff bytes, they will not overflow any more */
+ if (s->buffer >= 0)
+ s->byte_out(s->buffer, s->file);
+ for (; s->sc; --s->sc) {
+ s->byte_out(0xff, s->file);
+ s->byte_out(MARKER_STUFF, s->file);
+ }
+ s->buffer = temp; /* buffer new output byte (can still overflow) */
+ }
+ s->c &= 0x7ffffL;
+ s->ct = 8;
+ }
+ } while (s->a < 0x8000);
+
+ return;
+}
+
+
+void arith_decode_init(struct jbg_ardec_state *s, int reuse_st)
+{
+ int i;
+
+ if (!reuse_st)
+ for (i = 0; i < 4096; s->st[i++] = 0) ;
+ s->c = 0;
+ s->a = 1;
+ s->ct = 0;
+ s->startup = 1;
+ s->nopadding = 0;
+ return;
+}
+
+/*
+ * Decode and return one symbol from the provided PSCD byte stream
+ * that starts in s->pscd_ptr and ends in the byte before s->pscd_end.
+ * The context cx is a 12-bit integer in the range 0..4095. This
+ * function will advance s->pscd_ptr each time it has consumed all
+ * information from that PSCD byte.
+ *
+ * If a symbol has been decoded successfully, the return value will be
+ * 0 or 1 (depending on the symbol).
+ *
+ * If the decoder was not able to decode a symbol from the provided
+ * PSCD, then the return value will be -1, and two cases can be
+ * distinguished:
+ *
+ * s->pscd_ptr == s->pscd_end:
+ *
+ * The decoder has used up all information in the provided PSCD
+ * bytes. Further PSCD bytes have to be provided (via new values of
+ * s->pscd_ptr and/or s->pscd_end) before another symbol can be
+ * decoded.
+ *
+ * s->pscd_ptr == s->pscd_end - 1:
+ *
+ * The decoder has used up all provided PSCD bytes except for the
+ * very last byte, because that has the value 0xff. The decoder can
+ * at this point not yet tell whether this 0xff belongs to a
+ * MARKER_STUFF sequence or marks the end of the PSCD. Further PSCD
+ * bytes have to be provided (via new values of s->pscd_ptr and/or
+ * s->pscd_end), including the not yet processed 0xff byte, before
+ * another symbol can be decoded successfully.
+ *
+ * If s->nopadding != 0, the decoder will return -2 when it reaches
+ * the first two bytes of the marker segment that follows (and
+ * terminates) the PSCD, but before decoding the first symbol that
+ * depends on a bit in the input data that could have been the result
+ * of zero padding, and might, therefore, never have been encoded.
+ * This gives the caller the opportunity to lookahead early enough
+ * beyond a terminating SDNORM/SDRST for a trailing NEWLEN (as
+ * required by T.85) before decoding remaining symbols. Call the
+ * decoder again afterwards as often as necessary (leaving s->pscd_ptr
+ * pointing to the start of the marker segment) to retrieve any
+ * required remaining symbols that might depend on padding.
+ *
+ * [Note that each PSCD can be decoded into an infinitely long
+ * sequence of symbols, because the encoder might have truncated away
+ * an arbitrarily long sequence of trailing 0x00 bytes, which the
+ * decoder will append automatically as needed when it reaches the end
+ * of the PSCD. Therefore, the decoder cannot report any end of the
+ * symbol sequence and other means (external to the PSCD and
+ * arithmetic decoding process) are needed to determine that.]
+ */
+
+int arith_decode(struct jbg_ardec_state *s, int cx)
+{
+ register unsigned lsz, ss;
+ register unsigned char *st;
+ int pix;
+
+ /* renormalization */
+ while (s->a < 0x8000 || s->startup) {
+ while (s->ct <= 8 && s->ct >= 0) {
+ /* first we can move a new byte into s->c */
+ if (s->pscd_ptr >= s->pscd_end) {
+ return -1; /* more bytes needed */
+ }
+ if (*s->pscd_ptr == 0xff)
+ if (s->pscd_ptr + 1 >= s->pscd_end) {
+ return -1; /* final 0xff byte not processed */
+ } else {
+ if (*(s->pscd_ptr + 1) == MARKER_STUFF) {
+ s->c |= 0xffL << (8 - s->ct);
+ s->ct += 8;
+ s->pscd_ptr += 2;
+ } else {
+ s->ct = -1; /* start padding with zero bytes */
+ if (s->nopadding) {
+ s->nopadding = 0;
+ return -2; /* subsequent symbols might depend on zero padding */
+ }
+ }
+ }
+ else {
+ s->c |= (long)*(s->pscd_ptr++) << (8 - s->ct);
+ s->ct += 8;
+ }
+ }
+ s->c <<= 1;
+ s->a <<= 1;
+ if (s->ct >= 0) s->ct--;
+ if (s->a == 0x10000L)
+ s->startup = 0;
+ }
+
+ st = s->st + cx;
+ ss = *st & 0x7f;
+ assert(ss < 113);
+ lsz = lsztab[ss];
+
+#if 0
+ fprintf(stderr, "cx = %d, mps = %d, st = %3d, lsz = 0x%04x, a = 0x%05lx, "
+ "c = 0x%08lx, ct = %2d\n",
+ cx, !!(s->st[cx] & 0x80), ss, lsz, s->a, s->c, s->ct);
+#endif
+
+ if ((s->c >> 16) < (s->a -= lsz))
+ if (s->a & 0xffff8000L)
+ return *st >> 7;
+ else {
+ /* MPS_EXCHANGE */
+ if (s->a < lsz) {
+ pix = 1 - (*st >> 7);
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= nlpstab[ss];
+ } else {
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= nmpstab[ss];
+ }
+ }
+ else {
+ /* LPS_EXCHANGE */
+ if (s->a < lsz) {
+ s->c -= s->a << 16;
+ s->a = lsz;
+ pix = *st >> 7;
+ *st &= 0x80;
+ *st |= nmpstab[ss];
+ } else {
+ s->c -= s->a << 16;
+ s->a = lsz;
+ pix = 1 - (*st >> 7);
+ /* Check whether MPS/LPS exchange is necessary
+ * and chose next probability estimator status */
+ *st &= 0x80;
+ *st ^= nlpstab[ss];
+ }
+ }
+
+ return pix;
+}
diff --git a/thirdparty/jbigkit/libjbig/jbig_ar.h b/thirdparty/jbigkit/libjbig/jbig_ar.h
new file mode 100644
index 000000000..d58b1ae02
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/jbig_ar.h
@@ -0,0 +1,53 @@
+/*
+ * Header file for the arithmetic encoder and decoder of
+ * the portable JBIG compression library
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#ifndef JBG_AR_H
+#define JBG_AR_H
+
+/*
+ * Status of arithmetic encoder
+ */
+
+struct jbg_arenc_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* register C: base of coding intervall, *
+ * layout as in Table 23 */
+ unsigned long a; /* register A: normalized size of coding interval */
+ long sc; /* number of buffered 0xff values that might still overflow */
+ int ct; /* bit shift counter, determines when next byte will be written */
+ int buffer; /* buffer for most recent output byte != 0xff */
+ void (*byte_out)(int, void *); /* function that receives all PSCD bytes */
+ void *file; /* parameter passed to byte_out */
+};
+
+/*
+ * Status of arithmetic decoder
+ */
+
+struct jbg_ardec_state {
+ unsigned char st[4096]; /* probability status for contexts, MSB = MPS */
+ unsigned long c; /* register C: base of coding intervall, *
+ * layout as in Table 25 */
+ unsigned long a; /* register A: normalized size of coding interval */
+ unsigned char *pscd_ptr; /* pointer to next PSCD data byte */
+ unsigned char *pscd_end; /* pointer to byte after PSCD */
+ int ct; /* bit-shift counter, determines when next byte will be read;
+ * special value -1 signals that zero-padding has started */
+ int startup; /* boolean flag that controls initial fill of s->c */
+ int nopadding; /* boolean flag that triggers return -2 between
+ * reaching PSCD end and decoding the first symbol
+ * that might never have been encoded in the first
+ * place */
+};
+
+void arith_encode_init(struct jbg_arenc_state *s, int reuse_st);
+void arith_encode_flush(struct jbg_arenc_state *s);
+void arith_encode(struct jbg_arenc_state *s, int cx, int pix);
+void arith_decode_init(struct jbg_ardec_state *s, int reuse_st);
+int arith_decode(struct jbg_ardec_state *s, int cx);
+
+#endif /* JBG_AR_H */
diff --git a/thirdparty/jbigkit/libjbig/po/README.txt b/thirdparty/jbigkit/libjbig/po/README.txt
new file mode 100644
index 000000000..64ba523cd
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/po/README.txt
@@ -0,0 +1,20 @@
+Older versions of jbig.c contained a list of human-readable
+result/error messages in both English and German.
+
+These messages are highly technical and unlikely to be of much use to
+end users who are not familiar with the JBIG1 standard (which has only
+been published in English, Spanish and French). Therefore, in the
+interest of simplicity, since release 2.0 the source code contains in
+errmsg[] now only the English version of these messages.
+
+The German version is preserved here in the form of a PO translation
+file, as used by the GNU gettext package, just in case anyone still
+finds it of use.
+
+See http://www.gnu.org/software/gettext/manual/gettext.html for
+information on the PO file format and tools for creating and using
+them.
+
+JBIG-KIT itself does not use gettext, but the included po files might
+help users of the library to translate the strings returned by
+jbg_strerror() or jbg85_strerror() into other languages.
diff --git a/thirdparty/jbigkit/libjbig/po/de.po b/thirdparty/jbigkit/libjbig/po/de.po
new file mode 100644
index 000000000..f29ead8f4
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/po/de.po
@@ -0,0 +1,52 @@
+# German translations for jbigkit package
+# Copyright (C) 2008 Markus Kuhn
+# This file is distributed under the same license as the jbigkit package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jbigkit 2.0\n"
+"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n"
+"POT-Creation-Date: 2014-03-24 15:35+0000\n"
+"PO-Revision-Date: 2008-08-27 20:16+0100\n"
+"Last-Translator: Markus Kuhn \n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: jbig.c:98 jbig85.c:69
+msgid "All OK"
+msgstr "Kein Problem"
+
+#: jbig.c:99 jbig85.c:70
+msgid "Reached specified image size"
+msgstr "Angeforderte Bildgröße erreicht"
+
+#: jbig.c:100 jbig85.c:71
+msgid "Unexpected end of input data stream"
+msgstr "Unerwartetes Ende des Eingabedatenstroms"
+
+#: jbig.c:101 jbig85.c:72
+msgid "Not enough memory available"
+msgstr "Nicht genügend Speicher vorhanden"
+
+#: jbig.c:102 jbig85.c:73
+msgid "ABORT marker segment encountered"
+msgstr "Es wurde eine Abbruch-Sequenz gefunden"
+
+#: jbig.c:103 jbig85.c:74
+msgid "Unknown marker segment encountered"
+msgstr "Es wurde eine unbekannte Marker-Sequenz gefunden"
+
+#: jbig.c:104 jbig85.c:75
+msgid "Input data stream contains invalid data"
+msgstr "Es wurden ungültige Daten gefunden"
+
+#: jbig.c:105 jbig85.c:76
+msgid "Input data stream uses unimplemented JBIG features"
+msgstr "Eingabedatenstrom benutzt nicht implementierte JBIG Optionen"
+
+#: jbig.c:106
+msgid "Incremental BIE does not continue previous one"
+msgstr "Neue Bilddaten passen nicht zu vorangegangenen"
diff --git a/thirdparty/jbigkit/libjbig/po/pl.po b/thirdparty/jbigkit/libjbig/po/pl.po
new file mode 100644
index 000000000..18864f44b
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/po/pl.po
@@ -0,0 +1,51 @@
+# Polish translation for jbigkit.
+# This file is distributed under the same license as the jbigkit package.
+# Jakub Bogusz , 2010-2014
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jbigkit 2.0\n"
+"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n"
+"POT-Creation-Date: 2014-03-24 15:35+0000\n"
+"PO-Revision-Date: 2014-11-16 16:45+0100\n"
+"Last-Translator: Jakub Bogusz \n"
+"Language-Team: Polish \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: jbig.c:98 jbig85.c:69
+msgid "All OK"
+msgstr "Poprawnie"
+
+#: jbig.c:99 jbig85.c:70
+msgid "Reached specified image size"
+msgstr "Osiągnięto określony rozmiar obrazu"
+
+#: jbig.c:100 jbig85.c:71
+msgid "Unexpected end of input data stream"
+msgstr "Nieoczekiwany koniec strumienia danych wejściowych"
+
+#: jbig.c:101 jbig85.c:72
+msgid "Not enough memory available"
+msgstr "Zbyt mało dostępnej pamięci"
+
+#: jbig.c:102 jbig85.c:73
+msgid "ABORT marker segment encountered"
+msgstr "Napotkano segment znacznika ABORT"
+
+#: jbig.c:103 jbig85.c:74
+msgid "Unknown marker segment encountered"
+msgstr "Napotkano segment nieznanego znacznika"
+
+#: jbig.c:104 jbig85.c:75
+msgid "Input data stream contains invalid data"
+msgstr "Strumień danych wejściowych zawiera błędne dane"
+
+#: jbig.c:105 jbig85.c:76
+msgid "Input data stream uses unimplemented JBIG features"
+msgstr "Strumień danych wejściowych korzysta z niezaimplementowanych cech JBIG"
+
+#: jbig.c:106
+msgid "Incremental BIE does not continue previous one"
+msgstr "Przyrostowe dane obrazu nie są kontynuacją poprzednich"
diff --git a/thirdparty/jbigkit/libjbig/po/ru.po b/thirdparty/jbigkit/libjbig/po/ru.po
new file mode 100644
index 000000000..6e0711398
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/po/ru.po
@@ -0,0 +1,53 @@
+# Russian translations for jbigkit package.
+# This file is distributed under the same license as the jbigkit package.
+# Russian translation by ghostmansd@gmil.com,
+# with some changes by Sergei Skorobogatov.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jbigkit 2.1\n"
+"Report-Msgid-Bugs-To: http://www.cl.cam.ac.uk/~mgk25/jbigkit/\n"
+"POT-Creation-Date: 2014-03-24 15:35+0000\n"
+"PO-Revision-Date: 2014-03-21 18:06+0000\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#: jbig.c:98 jbig85.c:69
+msgid "All OK"
+msgstr "Успешное завершение"
+
+#: jbig.c:99 jbig85.c:70
+msgid "Reached specified image size"
+msgstr "Указанный размер достигнут"
+
+#: jbig.c:100 jbig85.c:71
+msgid "Unexpected end of input data stream"
+msgstr "Неожиданный конец входного потока"
+
+#: jbig.c:101 jbig85.c:72
+msgid "Not enough memory available"
+msgstr "Недостаточно памяти"
+
+#: jbig.c:102 jbig85.c:73
+msgid "ABORT marker segment encountered"
+msgstr "Обнаружен сегмент прерывания"
+
+#: jbig.c:103 jbig85.c:74
+msgid "Unknown marker segment encountered"
+msgstr "Обнаружен неизвестный сегмент"
+
+#: jbig.c:104 jbig85.c:75
+msgid "Input data stream contains invalid data"
+msgstr "Входной поток содержит неверные данные"
+
+#: jbig.c:105 jbig85.c:76
+msgid "Input data stream uses unimplemented JBIG features"
+msgstr "Входной поток использует нереализованные функции"
+
+#: jbig.c:106
+msgid "Incremental BIE does not continue previous one"
+msgstr "Следующий тип данных BIE не продолжает предыдущий"
diff --git a/thirdparty/jbigkit/libjbig/tstcodec.c b/thirdparty/jbigkit/libjbig/tstcodec.c
new file mode 100644
index 000000000..4e7bb74e7
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/tstcodec.c
@@ -0,0 +1,550 @@
+/*
+ * A sequence of test procedures for this JBIG implementation
+ *
+ * Run this test sequence after each modification on the JBIG library.
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#include
+#include
+#include
+#include
+
+#include "jbig.h"
+
+#define TESTBUF_SIZE 400000L
+#define TESTPIC_SIZE 477995L
+
+#define FAILED "F\bFA\bAI\bIL\bLE\bED\bD"
+#define PASSED "PASSED"
+
+unsigned char *testbuf;
+unsigned char *testpic;
+
+long testbuf_len;
+
+
+static void *checkedmalloc(size_t n)
+{
+ void *p;
+
+ if ((p = malloc(n)) == NULL) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ return p;
+}
+
+static void testbuf_write(int v, void *dummy)
+{
+ if (testbuf_len < TESTBUF_SIZE)
+ testbuf[testbuf_len++] = v;
+ (void) dummy;
+ return;
+}
+
+
+static void testbuf_writel(unsigned char *start, size_t len, void *dummy)
+{
+ if (testbuf_len < TESTBUF_SIZE) {
+ if (testbuf_len + len < TESTBUF_SIZE)
+ memcpy(testbuf + testbuf_len, start, len);
+ else
+ memcpy(testbuf + testbuf_len, start, TESTBUF_SIZE - testbuf_len);
+ }
+ testbuf_len += len;
+
+#ifdef DEBUG
+ {
+ unsigned char *p;
+ unsigned sum = 0;
+
+ for (p = start; p - start < (ptrdiff_t) len; sum = (sum ^ *p++) << 1);
+ printf(" testbuf_writel: %4lu bytes, checksum %04x\n",
+ (unsigned long) len, sum & 0xffff);
+ }
+#endif
+
+ (void) dummy;
+ return;
+}
+
+
+/*
+ * Store the artificial test image defined in T.82, clause 7.2.1 at
+ * pic. The image requires 477995 bytes of memory, is 1960 x 1951 pixels
+ * large and has one plane.
+ */
+static void testimage(unsigned char *pic)
+{
+ unsigned long i, j, sum;
+ unsigned int prsg, repeat[8];
+ unsigned char *p;
+
+ memset(pic, 0, TESTPIC_SIZE);
+ p = pic;
+ prsg = 1;
+ for (j = 0; j < 1951; j++)
+ for (i = 0; i < 1960; i++) {
+ if (j >= 192) {
+ if (j < 1023 || ((i >> 3) & 3) == 0) {
+ sum = (prsg & 1) + ((prsg >> 2) & 1) + ((prsg >> 11) & 1) +
+ ((prsg >> 15) & 1);
+ prsg = (prsg << 1) + (sum & 1);
+ if ((prsg & 3) == 0) {
+ *p |= 1 << (7 - (i & 7));
+ repeat[i & 7] = 1;
+ } else {
+ repeat[i & 7] = 0;
+ }
+ } else {
+ if (repeat[i & 7])
+ *p |= 1 << (7 - (i & 7));
+ }
+ }
+ if ((i & 7) == 7) ++p;
+ }
+
+ /* verify test image */
+ sum = 0;
+ for (i = 0; i < TESTPIC_SIZE; i++)
+ for (j = 0; j < 8; j++)
+ sum += (pic[i] >> j) & 1;
+ if (sum != 861965L)
+ printf("WARNING: Artificial test image has %lu (not 861965) "
+ "foreground pixels!\n", sum);
+
+ return;
+}
+
+
+/*
+ * Perform a full test cycle with one set of parameters. Encode an image
+ * and compare the length of the result with correct_length. Then decode
+ * the image again both in one single chunk or byte by byte and compare
+ * the results with the original input image.
+ */
+static int test_cycle(unsigned char **orig_image, int width, int height,
+ int options, int order, int layers, int planes,
+ unsigned long l0, int mx, long correct_length,
+ const char *test_id)
+{
+ struct jbg_enc_state sje;
+ struct jbg_dec_state sjd;
+ int trouble = 0;
+ long l;
+ size_t plane_size;
+ int i, result;
+ unsigned char **image;
+
+ plane_size = ((width + 7) / 8) * height;
+ image = (unsigned char **) checkedmalloc(planes * sizeof(unsigned char *));
+ for (i = 0; i < planes; i++) {
+ image[i] = (unsigned char *) checkedmalloc(plane_size);
+ memcpy(image[i], orig_image[i], plane_size);
+ }
+
+ printf("\nTest %s.1: Encoding ...\n", test_id);
+ testbuf_len = 0;
+ jbg_enc_init(&sje, width, height, planes, image, testbuf_writel, NULL);
+ jbg_enc_layers(&sje, layers);
+ jbg_enc_options(&sje, order, options, l0, mx, 0);
+ jbg_enc_out(&sje);
+ jbg_enc_free(&sje);
+ for (i = 0; i < planes; i++)
+ free(image[i]);
+ free(image);
+ printf("Encoded BIE has %6ld bytes: ", testbuf_len);
+ if (correct_length >= 0)
+ if (testbuf_len == correct_length)
+ puts(PASSED);
+ else {
+ trouble++;
+ printf(FAILED ", correct would have been %ld\n", correct_length);
+ }
+ else
+ puts("");
+
+ printf("Test %s.2: Decoding whole chunk ...\n", test_id);
+ jbg_dec_init(&sjd);
+ result = jbg_dec_in(&sjd, testbuf, testbuf_len, NULL);
+ if (result != JBG_EOK) {
+ printf("Decoder complained with return value %d: " FAILED "\n"
+ "Cause: '%s'\n", result, jbg_strerror(result));
+ trouble++;
+ } else {
+ printf("Image comparison: ");
+ result = 1;
+ for (i = 0; i < planes; i++) {
+ if (memcmp(orig_image[i], sjd.lhp[layers & 1][i],
+ ((width + 7) / 8) * height)) {
+ result = 0;
+ trouble++;
+ printf(FAILED " for plane %d\n", i);
+ }
+ }
+ if (result)
+ puts(PASSED);
+ }
+ jbg_dec_free(&sjd);
+
+ printf("Test %s.3: Decoding with single-byte feed ...\n", test_id);
+ jbg_dec_init(&sjd);
+ result = JBG_EAGAIN;
+ for (l = 0; l < testbuf_len; l++) {
+ result = jbg_dec_in(&sjd, testbuf + l, 1, NULL);
+ if (l < testbuf_len - 1 && result != JBG_EAGAIN) {
+ printf("Decoder complained with return value %d at byte %ld: " FAILED
+ "\nCause: '%s'\n", result, l, jbg_strerror(result));
+ trouble++;
+ break;
+ }
+ }
+ if (l == testbuf_len) {
+ if (result != JBG_EOK) {
+ printf("Decoder complained with return value %d at final byte: " FAILED
+ "\nCause: '%s'\n", result, jbg_strerror(result));
+ trouble++;
+ } else {
+ printf("Image comparison: ");
+ result = 1;
+ for (i = 0; i < planes; i++) {
+ if (memcmp(orig_image[i], sjd.lhp[layers & 1][i],
+ ((width + 7) / 8) * height)) {
+ result = 0;
+ trouble++;
+ printf(FAILED " for plane %d\n", i);
+ }
+ }
+ if (result)
+ puts(PASSED);
+ }
+ }
+
+ jbg_dec_free(&sjd);
+ puts("");
+
+ return trouble != 0;
+}
+
+
+int main(int argc, char **argv)
+{
+ int trouble, problems = 0;
+ struct jbg_arenc_state *se;
+ struct jbg_ardec_state *sd;
+ long i;
+ int pix, order, layers;
+ char test[10];
+ size_t st;
+ unsigned char *pp;
+ unsigned char *ppp[4];
+
+ int t82pix[16] = {
+ 0x05e0, 0x0000, 0x8b00, 0x01c4, 0x1700, 0x0034, 0x7fff, 0x1a3f,
+ 0x951b, 0x05d8, 0x1d17, 0xe770, 0x0000, 0x0000, 0x0656, 0x0e6a
+ };
+ int t82cx[16] = {
+ 0x0fe0, 0x0000, 0x0f00, 0x00f0, 0xff00, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+ unsigned char t82sde[32] = {
+ 0x69, 0x89, 0x99, 0x5c, 0x32, 0xea, 0xfa, 0xa0,
+ 0xd5, 0xff, 0x00, 0x52, 0x7f, 0xff, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f,
+ 0xff, 0x00, 0x2d, 0x20, 0x82, 0x91, 0xff, 0x02
+ };
+
+ /* three 23x5 pixel test images with the letters JBIG */
+ unsigned char jbig_normal[15*4] = {
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44,
+ 0x92, 0x44, 0x38, 0xe2, 0x38,
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44,
+ 0x92, 0x44, 0x38, 0xe2, 0x38,
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44,
+ 0x92, 0x44, 0x38, 0xe2, 0x38,
+ 0x7c, 0xe2, 0x38, 0x04, 0x92, 0x40, 0x04, 0xe2, 0x5c, 0x44,
+ 0x92, 0x44, 0x38, 0xe2, 0x38
+ };
+ unsigned char jbig_upsidedown[15*4] = {
+ 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04,
+ 0x92, 0x40, 0x7c, 0xe2, 0x38,
+ 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04,
+ 0x92, 0x40, 0x7c, 0xe2, 0x38,
+ 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04,
+ 0x92, 0x40, 0x7c, 0xe2, 0x38,
+ 0x38, 0xe2, 0x38, 0x44, 0x92, 0x44, 0x04, 0xe2, 0x5c, 0x04,
+ 0x92, 0x40, 0x7c, 0xe2, 0x38
+ };
+ unsigned char jbig_inverse[15*4] = {
+ 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92,
+ 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44,
+ 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38,
+ 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92,
+ 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44,
+ 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38,
+ 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92,
+ 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44,
+ 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38,
+ 0xff^0x7c, 0xff^0xe2, 0xfe^0x38, 0xff^0x04, 0xff^0x92,
+ 0xfe^0x40, 0xff^0x04, 0xff^0xe2, 0xfe^0x5c, 0xff^0x44,
+ 0xff^0x92, 0xfe^0x44, 0xff^0x38, 0xff^0xe2, 0xfe^0x38
+ };
+ int orders[] = {
+ 0,
+ JBG_ILEAVE,
+ JBG_ILEAVE | JBG_SMID,
+#if 0
+ JBG_SEQ,
+ JBG_SEQ | JBG_SMID,
+ JBG_SEQ | JBG_ILEAVE,
+ JBG_HITOLO,
+ JBG_HITOLO | JBG_ILEAVE,
+ JBG_HITOLO | JBG_ILEAVE | JBG_SMID,
+ JBG_HITOLO | JBG_SEQ,
+ JBG_HITOLO | JBG_SEQ | JBG_SMID,
+ JBG_HITOLO | JBG_SEQ | JBG_ILEAVE
+#endif
+ };
+
+ printf("\nAutomatic JBIG Compatibility Test Suite\n"
+ "---------------------------------------\n\n"
+ "JBIG-KIT Version " JBG_VERSION
+ " -- This test may take a few minutes.\n\n\n");
+
+ /* allocate test buffer memory */
+ testbuf = (unsigned char *) checkedmalloc(TESTBUF_SIZE);
+ testpic = (unsigned char *) checkedmalloc(TESTPIC_SIZE);
+ se = (struct jbg_arenc_state *) checkedmalloc(sizeof(struct jbg_arenc_state));
+ sd = (struct jbg_ardec_state *) checkedmalloc(sizeof(struct jbg_ardec_state));
+
+ /* test a few properties of the machine architecture */
+ testbuf[0] = 42;
+ testbuf[0x10000L] = 0x42;
+ st = 1 << 16;
+ testbuf[st]++;
+ pp = testbuf + 0x4000;
+ pp += 0x4000;
+ pp += 0x4000;
+ pp += 0x4000;
+ if (testbuf[0] != 42 || *pp != 0x43) {
+ printf("Porting error detected:\n\n"
+ "Pointer arithmetic with this compiler has not at least 32 bits!\n"
+ "Are you sure, you have not compiled this program on an 8-bit\n"
+ "or 16-bit architecture? This compiler mode can obviously not\n"
+ "handle arrays with a size of more than 65536 bytes. With this\n"
+ "memory model, JBIG-KIT can only handle very small images and\n"
+ "not even this compatibility test suite will run. :-(\n\n");
+ exit(1);
+ }
+
+ /* only supported command line option:
+ * output file name for exporting test image */
+ if (argc > 1) {
+ FILE *f;
+
+ puts("Generating test image ...");
+ testimage(testpic);
+ printf("Storing in '%s' ...\n", argv[1]);
+
+ /* write out test image as PBM file */
+ f = fopen(argv[1], "wb");
+ if (!f) abort();
+ fprintf(f, "P4\n");
+#if 0
+ fprintf(f, "# Test image as defined in ITU-T T.82, clause 7.2.1\n");
+#endif
+ fprintf(f, "%10lu\n%10lu\n", 1960LU, 1951LU);
+ fwrite(testpic, 1, TESTPIC_SIZE, f);
+ fclose(f);
+ exit(0);
+ }
+
+#if 1
+ puts("1) Arithmetic encoder test sequence from ITU-T T.82, clause 7.1\n"
+ "---------------------------------------------------------------\n");
+ arith_encode_init(se, 0);
+ testbuf_len = 0;
+ se->byte_out = testbuf_write;
+ for (i = 0; i < 16 * 16; i++)
+ arith_encode(se, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1,
+ (t82pix[i >> 4] >> ((15 - i) & 15)) & 1);
+ arith_encode_flush(se);
+ printf("result of encoder:\n ");
+ for (i = 0; i < testbuf_len && i < TESTBUF_SIZE; i++)
+ printf("%02x", testbuf[i]);
+ printf("\nexpected result:\n ");
+ for (i = 0; i < 30; i++)
+ printf("%02x", t82sde[i]);
+ printf("\n\nTest 1: ");
+ if (testbuf_len != 30 || memcmp(testbuf, t82sde, 30)) {
+ problems++;
+ printf(FAILED);
+ } else
+ printf(PASSED);
+ printf("\n\n");
+
+
+ puts("2) Arithmetic decoder test sequence from ITU-T T.82, clause 7.1\n"
+ "---------------------------------------------------------------\n");
+ printf("Test 2.1: Decoding whole chunk ...\n");
+ arith_decode_init(sd, 0);
+ sd->pscd_ptr = t82sde;
+ sd->pscd_end = t82sde + 32;
+ trouble = 0;
+ for (i = 0; i < 16 * 16 && !trouble; i++) {
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ if (pix < 0) {
+ printf("Problem at pixel %ld, byte %ld.\n\n",
+ i+1, (long) (sd->pscd_ptr - sd->pscd_end));
+ trouble++;
+ break;
+ }
+ if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) {
+ printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1);
+ trouble++;
+ break;
+ }
+ }
+ if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) {
+ printf("%ld bytes left after decoder finished.\n\n",
+ (long) (sd->pscd_end - sd->pscd_ptr - 2));
+ trouble++;
+ }
+ printf("Test result: ");
+ if (trouble) {
+ problems++;
+ puts(FAILED);
+ } else
+ puts(PASSED);
+ printf("\n");
+
+ printf("Test 2.2: Decoding with single byte feed ...\n");
+ arith_decode_init(sd, 0);
+ pp = t82sde;
+ sd->pscd_ptr = pp;
+ sd->pscd_end = pp + 1;
+ trouble = 0;
+ for (i = 0; i < 16 * 16 && !trouble; i++) {
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ while (pix < 0 && sd->pscd_end < t82sde + 32) {
+ pp++;
+ if (sd->pscd_ptr != pp - 1)
+ sd->pscd_ptr = pp;
+ sd->pscd_end = pp + 1;
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ }
+ if (pix < 0) {
+ printf("Problem at pixel %ld, byte %ld.\n\n",
+ i+1, (long) (sd->pscd_ptr - sd->pscd_end));
+ trouble++;
+ break;
+ }
+ if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) {
+ printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1);
+ trouble++;
+ break;
+ }
+ }
+ if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) {
+ printf("%ld bytes left after decoder finished.\n\n",
+ (long) (sd->pscd_end - sd->pscd_ptr - 2));
+ trouble++;
+ }
+ printf("Test result: ");
+ if (trouble) {
+ problems++;
+ puts(FAILED);
+ } else
+ puts(PASSED);
+ printf("\n");
+
+ puts("3) Parametric algorithm test sequence from ITU-T T.82, clause 7.2\n"
+ "-----------------------------------------------------------------\n");
+ puts("Generating test image ...");
+ testimage(testpic);
+ putchar('\n');
+ pp = testpic;
+
+ puts("Test 3.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT,
+ 0, 0, 1, 1951, 0, 317384L, "3.1");
+ puts("Test 3.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT | JBG_LRLTWO,
+ 0, 0, 1, 1951, 0, 317132L, "3.2");
+ puts("Test 3.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_DELAY_AT | JBG_TPBON,
+ 0, 0, 1, 128, 8, 253653L, "3.3");
+ puts("Test 3.4: TPBON=1, DPON=1, TPDON=1, Mx=8, LRLTWO=0, L0=2, 6 layers");
+ problems += test_cycle(&pp, 1960, 1951,
+ JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON,
+ 0, 6, 1, 2, 8, 279314L, "3.4");
+ puts("Test 3.5: as Test 3.4 but with DPPRIV=1");
+ problems += test_cycle(&pp, 1960, 1951,
+ JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON |
+ JBG_DPPRIV,
+ 0, 6, 1, 2, 8, 279314L + 1728, "3.5");
+#if 0 /* Note: option SEQ is currently not supported by the decoder */
+ puts("Test 3.6: as Test 3.4 but with order bit SEQ set");
+ problems += test_cycle(&pp, 1960, 1951,
+ JBG_DELAY_AT | JBG_TPBON | JBG_TPDON | JBG_DPON,
+ JBG_SEQ, 6, 1, 2, 8, 279314L, "3.6");
+#endif
+#endif
+
+ puts("4) Same T.82 tests with SDRST instead of SDNORM\n"
+ "-----------------------------------------------\n");
+
+ puts("Test 4.0: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_SDRST | JBG_TPBON,
+ 0, 0, 1, 128, 8, -1, "4.0");
+
+ puts("Test 4.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_SDRST,
+ 0, 0, 1, 1951, 0, -1, "4.1");
+ puts("Test 4.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_LRLTWO | JBG_SDRST,
+ 0, 0, 1, 1951, 0, -1, "4.2");
+ puts("Test 4.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_TPBON | JBG_SDRST,
+ 0, 0, 1, 128, 8, -1, "4.3");
+ puts("Test 4.4: TPBON=1, DPON=1, TPDON=1, Mx=8, LRLTWO=0, L0=2, 6 layers");
+ problems += test_cycle(&pp, 1960, 1951,
+ JBG_TPBON | JBG_TPDON |
+ JBG_DPON | JBG_SDRST,
+ 0, 6, 1, 2, 8, -1, "4.4");
+
+ puts("5) Small test image, 0-3 layers, 4 planes, different orders\n"
+ "-----------------------------------------------------------\n");
+
+ /* test a simple multi-plane image */
+ ppp[0] = jbig_normal;
+ ppp[1] = jbig_upsidedown;
+ ppp[2] = jbig_inverse;
+ ppp[3] = jbig_inverse;
+
+ i = 0;
+ for (layers = 0; layers <= 3; layers++)
+ for (order = 0; order < (int) (sizeof(orders)/sizeof(int)); order++) {
+ sprintf(test, "5.%ld", ++i);
+ printf("Test %s: order=%d, %d layers, 4 planes", test, orders[order],
+ layers);
+ problems += test_cycle(ppp, 23, 5*4, JBG_TPBON | JBG_TPDON | JBG_DPON,
+ orders[order], layers, 4, 2, 8, -1, test);
+ }
+
+
+ printf("\nTest result summary: the library has %s the test suite.\n\n",
+ problems ? FAILED : PASSED);
+ if (problems)
+ puts("This is bad. If you cannot identify the problem yourself, please "
+ "send\nthis output plus a detailed description of your "
+ "compile environment\n(OS, compiler, version, options, etc.) to "
+ "Markus Kuhn\n.");
+ else
+ puts("Congratulations, everything is fine.\n");
+
+ return problems != 0;
+}
diff --git a/thirdparty/jbigkit/libjbig/tstcodec85.c b/thirdparty/jbigkit/libjbig/tstcodec85.c
new file mode 100644
index 000000000..7e4940328
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/tstcodec85.c
@@ -0,0 +1,450 @@
+/*
+ * A sequence of test procedures for this JBIG implementation
+ *
+ * Run this test sequence after each modification on the JBIG library.
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include "jbig85.h"
+
+#define TESTBUF_SIZE 400000L
+#define TESTPIC_SIZE 477995L
+
+#define FAILED "F\bFA\bAI\bIL\bLE\bED\bD"
+#define PASSED "PASSED"
+
+unsigned char *testbuf;
+unsigned char *testpic;
+
+long testbuf_len;
+
+
+static void *checkedmalloc(size_t n)
+{
+ void *p;
+
+ if ((p = calloc(1, n)) == NULL) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ return p;
+}
+
+static void testbuf_write(int v, void *dummy)
+{
+ if (testbuf_len < TESTBUF_SIZE)
+ testbuf[testbuf_len++] = v;
+ (void) dummy;
+ return;
+}
+
+
+static void testbuf_writel(unsigned char *start, size_t len, void *dummy)
+{
+ if (testbuf_len < TESTBUF_SIZE) {
+ if (testbuf_len + len < TESTBUF_SIZE)
+ memcpy(testbuf + testbuf_len, start, len);
+ else
+ memcpy(testbuf + testbuf_len, start, TESTBUF_SIZE - testbuf_len);
+ }
+ testbuf_len += len;
+
+#ifdef DEBUG
+ {
+ unsigned char *p;
+ unsigned sum = 0;
+
+ for (p = start; p - start < (ptrdiff_t) len; sum = (sum ^ *p++) << 1);
+ printf(" testbuf_writel: %4lu bytes, checksum %04x\n",
+ (unsigned long) len, sum & 0xffff);
+ }
+#endif
+
+ (void) dummy;
+ return;
+}
+
+
+static int line_out(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len,
+ unsigned long y, void *bitmap)
+{
+ assert(jbg85_dec_validwidth(s));
+ assert(len == (jbg85_dec_getwidth(s) >> 3) + !!(jbg85_dec_getwidth(s) & 7));
+ assert(y < jbg85_dec_getheight(s));
+ memcpy((unsigned char *) bitmap + len * y, start, len);
+ return 0;
+}
+
+
+/*
+ * Store the artificial test image defined in T.82, clause 7.2.1 at
+ * pic. The image requires 477995 bytes of memory, is 1960 x 1951 pixels
+ * large and has one plane.
+ */
+static void testimage(unsigned char *pic)
+{
+ unsigned long i, j, sum;
+ unsigned int prsg, repeat[8];
+ unsigned char *p;
+
+ memset(pic, 0, TESTPIC_SIZE);
+ p = pic;
+ prsg = 1;
+ for (j = 0; j < 1951; j++)
+ for (i = 0; i < 1960; i++) {
+ if (j >= 192) {
+ if (j < 1023 || ((i >> 3) & 3) == 0) {
+ sum = (prsg & 1) + ((prsg >> 2) & 1) + ((prsg >> 11) & 1) +
+ ((prsg >> 15) & 1);
+ prsg = (prsg << 1) + (sum & 1);
+ if ((prsg & 3) == 0) {
+ *p |= 1 << (7 - (i & 7));
+ repeat[i & 7] = 1;
+ } else {
+ repeat[i & 7] = 0;
+ }
+ } else {
+ if (repeat[i & 7])
+ *p |= 1 << (7 - (i & 7));
+ }
+ }
+ if ((i & 7) == 7) ++p;
+ }
+
+ /* verify test image */
+ sum = 0;
+ for (i = 0; i < TESTPIC_SIZE; i++)
+ for (j = 0; j < 8; j++)
+ sum += (pic[i] >> j) & 1;
+ if (sum != 861965L)
+ printf("WARNING: Artificial test image has %lu (not 861965) "
+ "foreground pixels!\n", sum);
+
+ return;
+}
+
+
+/*
+ * Perform a full test cycle with one set of parameters. Encode an image
+ * and compare the length of the result with correct_length. Then decode
+ * the image again both in one single chunk or byte by byte and compare
+ * the results with the original input image.
+ */
+static int test_cycle(unsigned char *orig_image, int width, int height,
+ int options, unsigned long l0, int mx,
+ long correct_length, const char *test_id)
+{
+ struct jbg85_enc_state sje;
+ struct jbg85_dec_state sjd;
+ int trouble = 0;
+ long l;
+ size_t plane_size, buffer_len;
+ int i, result;
+ unsigned char *image, *buffer;
+ size_t bpl;
+ size_t cnt;
+
+ bpl = (width + 7) / 8;
+ plane_size = bpl * height;
+ image = (unsigned char *) checkedmalloc(plane_size);
+ memcpy(image, orig_image, plane_size);
+
+ printf("\nTest-85 %s.1: Encoding ...\n", test_id);
+ testbuf_len = 0;
+ jbg85_enc_init(&sje, width, height, testbuf_writel, NULL);
+ jbg85_enc_options(&sje, options, l0, mx);
+ for (i = 0; i < height; i++)
+ jbg85_enc_lineout(&sje,
+ image + i * bpl,
+ image + (i-1) * bpl,
+ image + (i-2) * bpl);
+ free(image);
+ printf("Encoded BIE has %6ld bytes: ", testbuf_len);
+ if (correct_length >= 0)
+ if (testbuf_len == correct_length)
+ puts(PASSED);
+ else {
+ trouble++;
+ printf(FAILED ", correct would have been %ld\n", correct_length);
+ }
+ else
+ puts("");
+
+#if 1
+ buffer_len = ((width >> 3) + !!(width & 7)) * 3;
+ buffer = (unsigned char *) checkedmalloc(buffer_len);
+ image = (unsigned char *) checkedmalloc(plane_size);
+ printf("Test-85 %s.2: Decoding whole chunk ...\n", test_id);
+ jbg85_dec_init(&sjd, buffer, buffer_len, line_out, image);
+ result = jbg85_dec_in(&sjd, testbuf, testbuf_len, &cnt);
+ if (result != JBG_EOK) {
+ printf("Decoder complained with return value 0x%02x: "
+ FAILED "\nCause: '%s'\n", result, jbg85_strerror(result));
+ printf("%ld bytes of BIE read, %lu lines decoded.\n",
+ (long) cnt, sjd.y);
+ trouble++;
+ } else {
+ printf("Image comparison: ");
+ result = 1;
+ if (memcmp(orig_image, image, plane_size)) {
+ result = 0;
+ trouble++;
+ printf(FAILED);
+ }
+ if (result)
+ puts(PASSED);
+ }
+ free(image);
+
+ image = (unsigned char *) checkedmalloc(plane_size);
+ printf("Test-85 %s.3: Decoding with single-byte feed ...\n", test_id);
+ jbg85_dec_init(&sjd, buffer, buffer_len, line_out, image);
+ result = JBG_EAGAIN;
+ for (l = 0; l < testbuf_len; l++) {
+ result = jbg85_dec_in(&sjd, testbuf + l, 1, NULL);
+ if (l < testbuf_len - 1 && result != JBG_EAGAIN) {
+ printf("Decoder complained with return value 0x%02x at byte %ld: "
+ FAILED "\nCause: '%s'\n", result, l, jbg85_strerror(result));
+ trouble++;
+ break;
+ }
+ }
+ if (l == testbuf_len) {
+ if (result != JBG_EOK) {
+ printf("Decoder complained with return value 0x%02x at final byte: "
+ FAILED "\nCause: '%s'\n", result, jbg85_strerror(result));
+ trouble++;
+ } else {
+ printf("Image comparison: ");
+ result = 1;
+ if (memcmp(orig_image, image, plane_size)) {
+ result = 0;
+ trouble++;
+ printf(FAILED);
+ }
+ if (result)
+ puts(PASSED);
+ }
+ }
+ free(image);
+
+#endif
+ puts("");
+
+ return trouble != 0;
+}
+
+
+int main(int argc, char **argv)
+{
+ int trouble, problems = 0;
+ struct jbg_arenc_state *se;
+ struct jbg_ardec_state *sd;
+ long i;
+ int pix;
+ unsigned char *pp;
+
+ int t82pix[16] = {
+ 0x05e0, 0x0000, 0x8b00, 0x01c4, 0x1700, 0x0034, 0x7fff, 0x1a3f,
+ 0x951b, 0x05d8, 0x1d17, 0xe770, 0x0000, 0x0000, 0x0656, 0x0e6a
+ };
+ int t82cx[16] = {
+ 0x0fe0, 0x0000, 0x0f00, 0x00f0, 0xff00, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ };
+ unsigned char t82sde[32] = {
+ 0x69, 0x89, 0x99, 0x5c, 0x32, 0xea, 0xfa, 0xa0,
+ 0xd5, 0xff, 0x00, 0x52, 0x7f, 0xff, 0x00, 0xff,
+ 0x00, 0xff, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x3f,
+ 0xff, 0x00, 0x2d, 0x20, 0x82, 0x91, 0xff, 0x02
+ };
+
+ printf("\nAutomatic JBIG Compatibility Test Suite\n"
+ "---------------------------------------\n\n"
+ "JBIG-KIT Version " JBG85_VERSION " (T.85 version)"
+ " -- This test may take a few minutes.\n\n\n");
+
+ /* allocate test buffer memory */
+ testbuf = (unsigned char *) checkedmalloc(TESTBUF_SIZE);
+ testpic = (unsigned char *) checkedmalloc(TESTPIC_SIZE);
+ se = (struct jbg_arenc_state *) checkedmalloc(sizeof(struct jbg_arenc_state));
+ sd = (struct jbg_ardec_state *) checkedmalloc(sizeof(struct jbg_ardec_state));
+
+ /* only supported command line option:
+ * output file name for exporting test image */
+ if (argc > 1) {
+ FILE *f;
+
+ puts("Generating test image ...");
+ testimage(testpic);
+ printf("Storing in '%s' ...\n", argv[1]);
+
+ /* write out test image as PBM file */
+ f = fopen(argv[1], "wb");
+ if (!f) abort();
+ fprintf(f, "P4\n");
+#if 0
+ fprintf(f, "# Test image as defined in ITU-T T.82, clause 7.2.1\n");
+#endif
+ fprintf(f, "1960 1951\n");
+ fwrite(testpic, 1, TESTPIC_SIZE, f);
+ fclose(f);
+ exit(0);
+ }
+
+#if 1
+ puts("1) Arithmetic encoder test sequence from ITU-T T.82, clause 7.1\n"
+ "---------------------------------------------------------------\n");
+ arith_encode_init(se, 0);
+ testbuf_len = 0;
+ se->byte_out = testbuf_write;
+ for (i = 0; i < 16 * 16; i++)
+ arith_encode(se, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1,
+ (t82pix[i >> 4] >> ((15 - i) & 15)) & 1);
+ arith_encode_flush(se);
+ printf("result of encoder:\n ");
+ for (i = 0; i < testbuf_len && i < TESTBUF_SIZE; i++)
+ printf("%02x", testbuf[i]);
+ printf("\nexpected result:\n ");
+ for (i = 0; i < 30; i++)
+ printf("%02x", t82sde[i]);
+ printf("\n\nTest 1: ");
+ if (testbuf_len != 30 || memcmp(testbuf, t82sde, 30)) {
+ problems++;
+ printf(FAILED);
+ } else
+ printf(PASSED);
+ printf("\n\n");
+
+
+ puts("2) Arithmetic decoder test sequence from ITU-T T.82, clause 7.1\n"
+ "---------------------------------------------------------------\n");
+ printf("Test 2.1: Decoding whole chunk ...\n");
+ arith_decode_init(sd, 0);
+ sd->pscd_ptr = t82sde;
+ sd->pscd_end = t82sde + 32;
+ trouble = 0;
+ for (i = 0; i < 16 * 16 && !trouble; i++) {
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ if (pix < 0) {
+ printf("Problem at pixel %ld, byte %ld.\n\n",
+ i+1, (long) (sd->pscd_ptr - sd->pscd_end));
+ trouble++;
+ break;
+ }
+ if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) {
+ printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1);
+ trouble++;
+ break;
+ }
+ }
+ if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) {
+ printf("%ld bytes left after decoder finished.\n\n",
+ (long) (sd->pscd_end - sd->pscd_ptr - 2));
+ trouble++;
+ }
+ printf("Test result: ");
+ if (trouble) {
+ problems++;
+ puts(FAILED);
+ } else
+ puts(PASSED);
+ printf("\n");
+
+ printf("Test 2.2: Decoding with single byte feed ...\n");
+ arith_decode_init(sd, 0);
+ pp = t82sde;
+ sd->pscd_ptr = pp;
+ sd->pscd_end = pp + 1;
+ trouble = 0;
+ for (i = 0; i < 16 * 16 && !trouble; i++) {
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ while (pix < 0 && sd->pscd_end < t82sde + 32) {
+ pp++;
+ if (sd->pscd_ptr != pp - 1)
+ sd->pscd_ptr = pp;
+ sd->pscd_end = pp + 1;
+ pix = arith_decode(sd, (t82cx[i >> 4] >> ((15 - i) & 15)) & 1);
+ }
+ if (pix < 0) {
+ printf("Problem at pixel %ld, byte %ld.\n\n",
+ i+1, (long) (sd->pscd_ptr - sd->pscd_end));
+ trouble++;
+ break;
+ }
+ if (pix != ((t82pix[i >> 4] >> ((15 - i) & 15)) & 1)) {
+ printf("Wrong PIX answer (%d) at pixel %ld.\n\n", pix, i+1);
+ trouble++;
+ break;
+ }
+ }
+ if (!trouble && sd->pscd_ptr != sd->pscd_end - 2) {
+ printf("%ld bytes left after decoder finished.\n\n",
+ (long) (sd->pscd_end - sd->pscd_ptr - 2));
+ trouble++;
+ }
+ printf("Test result: ");
+ if (trouble) {
+ problems++;
+ puts(FAILED);
+ } else
+ puts(PASSED);
+ printf("\n");
+
+ puts("3) Parametric algorithm test sequence from ITU-T T.82, clause 7.2\n"
+ "-----------------------------------------------------------------\n");
+ puts("Generating test image ...");
+ testimage(testpic);
+ putchar('\n');
+
+ puts("Test-85 3.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers");
+ problems += test_cycle(testpic, 1960, 1951, 0,
+ 1951, 0, 317384L, "3.1");
+ puts("Test-85 3.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers");
+ problems += test_cycle(testpic, 1960, 1951, JBG_LRLTWO,
+ 1951, 0, 317132L, "3.2");
+ puts("Test-85 3.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(testpic, 1960, 1951, JBG_TPBON,
+ 128, 8, 253653L, "3.3");
+#endif
+
+#if 0
+ puts("4) Same T.82 tests with SDRST instead of SDNORM\n"
+ "-----------------------------------------------\n");
+
+ puts("Test-85 4.0: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_SDRST | JBG_TPBON,
+ 128, 8, -1, "4.0");
+
+ puts("Test-85 4.1: TPBON=0, Mx=0, LRLTWO=0, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_SDRST,
+ 1951, 0, -1, "4.1");
+ puts("Test-85 4.2: TPBON=0, Mx=0, LRLTWO=1, L0=1951, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_LRLTWO | JBG_SDRST,
+ 1951, 0, -1, "4.2");
+ puts("Test-85 4.3: TPBON=1, Mx=8, LRLTWO=0, L0=128, 0 layers");
+ problems += test_cycle(&pp, 1960, 1951, JBG_TPBON | JBG_SDRST,
+ 128, 8, -1, "4.3");
+#endif
+
+ printf("\nTest result summary: the T.85 library has %s the test suite.\n\n",
+ problems ? FAILED : PASSED);
+ if (problems)
+ puts("This is bad. If you cannot identify the problem yourself, please "
+ "send\nthis output plus a detailed description of your "
+ "compile environment\n(OS, compiler, version, options, etc.) to "
+ "Markus Kuhn\n.");
+ else
+ puts("Congratulations, everything is fine.\n");
+
+ return problems != 0;
+}
diff --git a/thirdparty/jbigkit/libjbig/tstjoint.c b/thirdparty/jbigkit/libjbig/tstjoint.c
new file mode 100644
index 000000000..511d2947d
--- /dev/null
+++ b/thirdparty/jbigkit/libjbig/tstjoint.c
@@ -0,0 +1,14 @@
+/*
+ * This test file exists to check for any compile-time problems
+ * when linking an application with both jbig.c and jbig85.c simultanenously.
+ *
+ * Markus Kuhn -- http://www.cl.cam.ac.uk/~mgk25/
+ */
+
+#include "jbig.h"
+#include "jbig85.h"
+
+int main()
+{
+ return 0;
+}
diff --git a/thirdparty/jbigkit/pbmtools/Makefile b/thirdparty/jbigkit/pbmtools/Makefile
new file mode 100644
index 000000000..95545a486
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/Makefile
@@ -0,0 +1,182 @@
+# GNU makefile for the JBIG-KIT PBM tools
+
+.DELETE_ON_ERROR:
+
+# Select an ANSI/ISO C compiler here, e.g. GNU gcc is recommended
+CC = gcc
+
+# Options for the compiler
+CFLAGS = -g -O -W -Wall -Wno-unused-result -ansi -pedantic # --coverage
+CPPFLAGS = -I../libjbig
+LDFLAGS = -L../libjbig
+
+.PHONY: txt pdf test test82 test85 clean
+
+all: pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85 txt
+
+txt: pbmtojbg.txt jbgtopbm.txt pbm.txt pgm.txt
+
+pdf: pbmtojbg.pdf jbgtopbm.pdf pbm.pdf pgm.pdf
+
+pbmtojbg: pbmtojbg.o ../libjbig/libjbig.a
+ $(CC) $(LDFLAGS) $(CFLAGS) -o pbmtojbg pbmtojbg.o -ljbig
+
+jbgtopbm: jbgtopbm.o ../libjbig/libjbig.a
+ $(CC) $(LDFLAGS) $(CFLAGS) -o jbgtopbm jbgtopbm.o -ljbig
+
+pbmtojbg85: pbmtojbg85.o ../libjbig/libjbig85.a
+ $(CC) $(LDFLAGS) $(CFLAGS) -o pbmtojbg85 pbmtojbg85.o -ljbig85
+
+jbgtopbm85: jbgtopbm85.o ../libjbig/libjbig85.a
+ $(CC) $(LDFLAGS) $(CFLAGS) -o jbgtopbm85 jbgtopbm85.o -ljbig85
+
+jbgtopbm.o: jbgtopbm.c ../libjbig/jbig.h
+pbmtojbg.o: pbmtojbg.c ../libjbig/jbig.h
+jbgtopbm85.o: jbgtopbm85.c ../libjbig/jbig85.h
+pbmtojbg85.o: pbmtojbg85.c ../libjbig/jbig85.h
+
+../libjbig/libjbig.a: ../libjbig/jbig.c ../libjbig/jbig.h \
+ ../libjbig/jbig_ar.c ../libjbig/jbig_ar.h
+ $(MAKE) -C ../libjbig libjbig.a
+
+../libjbig/libjbig85.a: ../libjbig/jbig85.c ../libjbig/jbig85.h \
+ ../libjbig/jbig_ar.c ../libjbig/jbig_ar.h
+ $(MAKE) -C ../libjbig libjbig85.a
+
+analyze:
+ clang $(CPPFLAGS) --analyze *.c
+
+test: test82 test85
+
+test82: pbmtojbg jbgtopbm
+ $(MAKE) IMG=ccitt1 OPTIONSP= dotest1
+ $(MAKE) IMG=ccitt2 OPTIONSP= dotest1
+ $(MAKE) IMG=ccitt3 OPTIONSP= dotest1
+ $(MAKE) IMG=xvlogo "OPTIONSP=-d 3" dotest1
+ $(MAKE) IMG=sandra OPTIONSP= OPTIONSJ= dotest2g
+ $(MAKE) IMG=sandra OPTIONSP=-b OPTIONSJ=-b dotest2g
+ $(MAKE) IMG=sandra OPTIONSP=-q OPTIONSJ= dotest2g
+ $(MAKE) IMG=sandra "OPTIONSP=-o 0" OPTIONSJ= dotest2g
+ $(MAKE) IMG=sandra "OPTIONSP=-o 2" OPTIONSJ= dotest2g
+ $(MAKE) IMG=multi OPTIONSP= OPTIONSJ= dotest2g
+ $(MAKE) IMG=multi OPTIONSP=-b OPTIONSJ=-b dotest2g
+ $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127" dotest1
+ $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127" dotest2b
+ $(MAKE) IMG=mx "OPTIONSP=-q -s 3 -m 127 -p 92" dotest2b
+ $(MAKE) IMG=mx "OPTIONSP=-q -Y -1" dotest2b
+ $(MAKE) IMG=mx "OPTIONSP=-Y -1" dotest2b
+ rm -f test-*.jbg test-*.pbm test-*.pgm
+ ./jbgtopbm ../examples/ccitt1.jbg | ./pbmtojbg > test-ccitt1.jbg
+ cmp ../examples/ccitt1.jbg test-ccitt1.jbg
+ rm -f test-*.jbg test-*.pbm test-*.pgm
+ ./jbgtopbm < ../examples/ccitt1.jbg | ./pbmtojbg - test-ccitt1.jbg
+ cmp ../examples/ccitt1.jbg test-ccitt1.jbg
+ rm -f test-*.jbg test-*.pbm test-*.pgm
+ ./jbgtopbm < ../examples/ccitt1.jbg - test-ccitt1.pbm ; \
+ ./pbmtojbg test-ccitt1.pbm test-ccitt1.jbg
+ cmp ../examples/ccitt1.jbg test-ccitt1.jbg
+ rm -f test-*.jbg test-*.pbm test-*.pgm
+ ./jbgtopbm ../examples/ccitt1.jbg test-ccitt1.pbm ; \
+ ./pbmtojbg test-ccitt1.pbm >test-ccitt1.jbg
+ cmp ../examples/ccitt1.jbg test-ccitt1.jbg
+ rm -f test-*.jbg test-*.pbm test-*.pgm
+ @echo
+ @echo "The pbmtools have PASSED the functional tests. Good!"
+ @echo
+
+dotest1:
+ ./jbgtopbm ../examples/$(IMG).jbg test-$(IMG).pbm
+ ./pbmtojbg $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg
+ cmp test-$(IMG).jbg ../examples/$(IMG).jbg
+
+dotest2b:
+ ./pbmtojbg $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg
+ ./jbgtopbm $(OPTIONSJ) test-$(IMG).jbg test-$(IMG)-2.pbm
+ cmp test-$(IMG).pbm test-$(IMG)-2.pbm
+
+dotest2g:
+ ./pbmtojbg $(OPTIONSP) ../examples/$(IMG).pgm test-$(IMG).jbg
+ ./jbgtopbm $(OPTIONSJ) test-$(IMG).jbg test-$(IMG).pgm
+ cmp test-$(IMG).pgm ../examples/$(IMG).pgm
+
+test85: pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85 test-t82.pbm
+ $(MAKE) IMG=t82 "OPTIONSP=-p 0" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-p 8" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-p 8 -r" dotest85b
+ $(MAKE) IMG=t82 "OPTIONSP=-p 64" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-p 72" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-s 2 -C c" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-s 99999" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y 9999 0" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y 1951 0" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 127" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 128" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1919" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1920" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1949" dotest85
+ $(MAKE) IMG=t82 "OPTIONSP=-Y -1 1950" dotest85
+ $(MAKE) IMG=ccitt1 dotest85
+ $(MAKE) IMG=ccitt2 dotest85
+ $(MAKE) IMG=ccitt3 dotest85
+ rm -f test-*.jbg test-*.jbg85 test-*.pbm
+ @echo
+ @echo "The T.85 pbmtools have PASSED the functional tests. Good!"
+ @echo
+
+dotest85: test-$(IMG).pbm
+ ./pbmtojbg85 $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg85
+ ls -l test-$(IMG).jbg85
+ ./jbgtopbm test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+ rm test-$(IMG).pbm85
+ ./jbgtopbm85 test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+ rm test-$(IMG).pbm85
+ ./jbgtopbm85 -B 1 test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+
+dotest85b: test-$(IMG).pbm
+ ./pbmtojbg -f $(OPTIONSP) test-$(IMG).pbm test-$(IMG).jbg85
+ ls -l test-$(IMG).jbg85
+ ./jbgtopbm test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+ rm test-$(IMG).pbm85
+ ./jbgtopbm85 test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+ rm test-$(IMG).pbm85
+ ./jbgtopbm85 -B 1 test-$(IMG).jbg85 test-$(IMG).pbm85
+ cmp test-$(IMG).pbm test-$(IMG).pbm85
+
+test-%.pbm: ../examples/%.jbg
+ ./jbgtopbm $< $@
+
+test-t82.pbm:
+ $(MAKE) -C ../libjbig tstcodec
+ ../libjbig/tstcodec $@
+
+FOPT=-c 1000 -p 300000 -m 3
+fuzz: test-t82.pbm
+ while \
+ ./pbmtojbg -f test-t82.pbm | ./jbgfuzz.pl $(FOPT) && \
+ ./pbmtojbg test-t82.pbm | ./jbgfuzz.pl $(FOPT) -d jbgtopbm ; \
+ do true; done
+
+MAN2TXT=groff -man -Tascii -P -c -P -b -P -u
+%.txt: %.1
+ $(MAN2TXT) $< >$@
+%.txt: %.5
+ $(MAN2TXT) $< >$@
+MAN2PS=groff -man -Tps
+%.ps: %.1
+ $(MAN2PS) $< >$@
+%.ps: %.5
+ $(MAN2PS) $< >$@
+%.pdf: %.ps
+ ps2pdf $<
+
+
+clean:
+ rm -f *.o *~ core pbmtojbg jbgtopbm pbmtojbg85 jbgtopbm85
+ rm -f test-*.jbg test-*.pbm test-*.pgm test-*.jbg85 test-*.pbm85
+ rm -f *.gcda *.gcno *.plist
+ rm -f *.ps *.pdf
diff --git a/thirdparty/jbigkit/pbmtools/jbgfuzz.pl b/thirdparty/jbigkit/pbmtools/jbgfuzz.pl
new file mode 100755
index 000000000..6f366a19a
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/jbgfuzz.pl
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+# Simple fuzz tester for JBIG-KIT decoder -- Markus Kuhn
+#
+# Usage example:
+#
+# $ ../libjbig/tstcodec t.pbm
+# $ ./pbmtojbg -f t.pbm | ./jbgfuzz.pl
+
+use strict;
+
+my $fntst = '/tmp/test.jbg'; # fuzz testing file to be generated
+my $fntmp = $fntst . '~'; # temporary file (for atomic update)
+my $fnvalid = '-'; # valid example BIE file
+my $pbmtools = '.'; # location of jbgtopbm and jbgtopbm85
+my $count = "inf"; # how many times shall we try?
+my @decoders;
+
+my $prefix_len = 2000;
+my $rnd_suffix_len = 2000;
+my $mutation_rate = 10; # percentage of bytes substituted in prefix
+
+while ($_ = shift @ARGV) {
+ if ($_ eq '-c') {
+ $count = shift @ARGV;
+ } elsif ($_ eq '-m') {
+ $mutation_rate = shift @ARGV;
+ } elsif ($_ eq '-p') {
+ $prefix_len = shift @ARGV;
+ } elsif ($_ eq '-r') {
+ $rnd_suffix_len = shift @ARGV;
+ } elsif ($_ eq '-d') {
+ push @decoders, shift @ARGV;
+ } elsif ($_ eq '-t') {
+ $pbmtools = shift @ARGV;
+ } else {
+ $fnvalid = $_;
+ }
+}
+
+@decoders = ('jbgtopbm', 'jbgtopbm85') unless @decoders;
+
+# read some bytes from a valid BIE
+my $valid_prefix;
+my $in;
+open($in, "<$fnvalid") || die("$fnvalid: $!\n");
+read $in, $valid_prefix, $prefix_len;
+close $in || die("$fnvalid: $!\n");
+
+# open a source of random bytes
+my $fn_rnd = '/dev/urandom';
+my $rnd;
+open($rnd, '<', $fn_rnd) || die;
+
+for (my $i = 0; $i < $count; $i++) {
+ my $out;
+ open($out, '>', $fntmp) || die("$fntmp: $!\n");
+ my $prefix;
+ # randomly substitute some prefix bytes with random bytes
+ $prefix = $valid_prefix;
+ if (length($prefix) != $prefix_len) {
+ warn("Truncating requested $prefix_len byte prefix to available ".
+ length($prefix)." bytes.\n");
+ $prefix_len = length($prefix);
+ }
+ #print "\nB: ".join(',', unpack('C4N3C4', substr($prefix, 0, 20)))."\n";
+ for (my $p = 0; $p < $prefix_len; $p++) {
+ if (rand(100) < $mutation_rate) {
+ substr($prefix, $p, 1) = chr(int(rand(256)));
+ }
+ }
+ #print "A: ".join(',', unpack('C4N3C4', substr($prefix, 0, 20)))."\n";
+ # constrain header
+ my ($dl,$d,$p,$res,$xd,$yd,$l0,$mx,$my,$order,$options,$rest) =
+ unpack('C4N3C4a*', $prefix);
+ redo if $xd * $yd > 1e9; # eliminate excessive image sizes
+ $prefix = pack('C4N3C4a*', $dl,$d,$p,$res,$xd,$yd,$l0,$mx,$my,
+ $order,$options,$rest);
+ print $out $prefix;
+ # append random suffix
+ my $data;
+ read $rnd, $data, $rnd_suffix_len;
+ print $out $data;
+ close($out) || die("$fntmp: $!\n");
+ rename($fntmp, $fntst) || die("mv $fntmp $fntst: $!\n");
+ # now feed fuzz input into decoder(s)
+ for my $jbgtopbm (@decoders) {
+ printf "%5d: ", $i;
+ $_ = `$pbmtools/$jbgtopbm $fntst /dev/null 2>&1`;
+ my $r = $?;
+ if ($r == 0) {
+ print "no error encountered\n";
+ next;
+ } elsif ($r == 256) {
+ my $err;
+ if (/(\(error code.*\))/) {
+ $err = $1;
+ print $err, "\n";
+ } else {
+ die("$_\nno error code found\n");
+ }
+ } else {
+ die("$_\nreturn value: $r\n");
+ }
+ }
+}
diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm.1 b/thirdparty/jbigkit/pbmtools/jbgtopbm.1
new file mode 100644
index 000000000..66d3c3839
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/jbgtopbm.1
@@ -0,0 +1,114 @@
+.TH JBGTOPBM 1 "2014-08-22"
+.SH NAME
+jbgtopbm \- JBIG1 to portable bitmap file converter
+.SH SYNOPSIS
+.B jbgtopbm
+[
+.I options
+]
+[
+.I input-file
+| \- [
+.I output-file
+]]
+.br
+.SH DESCRIPTION
+Reads in a
+.I JBIG1
+bi-level image entity (BIE), decompresses it, and outputs a portable
+bitmap (PBM) file.
+
+.I JBIG1
+is a highly effective lossless compression algorithm for
+bi-level images (one bit per pixel), which is particularly suitable
+for scanned document pages.
+
+A
+.I JBIG1
+encoded image can be stored in several resolutions in one or several
+BIEs. All resolution layers except the lowest one are stored
+efficiently as differences to the next lower resolution layer. Options
+.B -x
+and
+.B -y
+can be used to stop the decompression at a specified maximal output
+image size. With option
+.B -m
+the input file can consist of multiple concatenated BIEs
+which contain different increasing resolution layers of the same
+image.
+
+If more than one bit per pixel is stored in the JBIG1 file, then a PGM
+file will be produced.
+.SH OPTIONS
+.TP 12
+.B \-
+A single hyphen instead of an input file name will cause
+.I jbgtopbm
+to read the data from standard input instead from a file.
+.TP
+.BI \-x " number"
+Decode only up to the largest resolution layer which is still not
+more than
+.I number
+pixels wide. If no such resolution layer exists, then use the smallest
+one available.
+.TP
+.BI \-y " number"
+Decode only up to the largest resolution layer which is still not
+more than
+.I number
+pixels high. If no such resolution layer exists, then use the smallest
+one available. Options
+.B \-x
+and
+.B \-y
+can also be used together in which case the largest layer that satisfies
+both limits will be selected.
+.TP
+.B \-m
+Process multiple concatenated BIEs. If there are bytes left after the
+final SDE in the first BIE, then with this option
+.I jbgtopbm
+will attempt to decode these as the start of another BIE that may
+contain higher resolution data. Normally, any remaining bytes will
+generate a warning message.
+.TP
+.B \-b
+Use binary values instead of Gray code words in order to decode pixel
+values from multiple bitplanes. This option has only an effect if the
+input has more than one bitplane and a PGM output file is produced.
+Note that the decoder has to be used in the same mode as the encoder
+and cannot determine from the BIE, whether Gray or binary code words
+were used by the encoder.
+.TP
+.B \-d
+Diagnose a single BIE. With this option,
+.I jbgtopbm
+will print a summary of the header information found in the input
+file, followed by a list of all PSCD and ESC marker sequences
+encountered until the end of the file is reached.
+.TP
+.BI \-p " number"
+If the input contains multiple bitplanes, then extract only the
+specified single plane as a PBM file. The first plane has number 0.
+.SH BUGS
+Using standard input and standard output for binary data works only on
+systems where there is no difference between binary and text streams
+(e.g., Unix). On other systems (e.g., MS-DOS), using standard input or
+standard output may cause control characters like CR or LF to be
+inserted or deleted and this will damage the binary data.
+.SH STANDARDS
+This program implements the
+.I JBIG1
+image coding algorithm as specified in international standard ISO/IEC
+11544:1993 and ITU-T Recommendation T.82(1993).
+.SH AUTHOR
+Markus Kuhn wrote
+.UR http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+.I JBIG-KIT
+.UE ,
+which includes
+.IR jbgtopbm .
+.SH SEE ALSO
+pbm(5), pgm(5), pbmtojbg(1)
diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm.c b/thirdparty/jbigkit/pbmtools/jbgtopbm.c
new file mode 100644
index 000000000..097087e44
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/jbgtopbm.c
@@ -0,0 +1,489 @@
+/*
+ * jbgtopbm - JBIG to Portable Bitmap converter
+ *
+ * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#include
+#include
+#include
+#include
+#include "jbig.h"
+
+char *progname; /* global pointer to argv[0] */
+
+
+/*
+ * Print usage message and abort
+ */
+static void usage(void)
+{
+ fprintf(stderr, "JBIGtoPBM converter " JBG_VERSION " -- "
+ "reads a bi-level image entity (BIE) as input file\n\n"
+ "usage: %s [] [ | - []]\n\n"
+ "options:\n\n", progname);
+ fprintf(stderr,
+ " -x number\tif possible decode only up to a resolution layer not\n"
+ "\t\twider than the given number of pixels\n"
+ " -y number\tif possible decode only up to a resolution layer not\n"
+ "\t\thigher than the given number of pixels\n"
+ " -m\t\tdecode a progressive sequence of multiple concatenated BIEs\n"
+ " -b\t\tuse binary code for multiple bit planes (default: Gray code)\n"
+ " -d\t\tdiagnose single BIE, print header, list marker sequences\n"
+ " -p number\tdecode only one single bit plane (0 = first plane)\n\n");
+ exit(1);
+}
+
+
+/*
+ * Call-back routine for merged image output
+ */
+void write_it(unsigned char *data, size_t len, void *file)
+{
+ fwrite(data, len, 1, (FILE *) file);
+}
+
+/*
+ * Remalloc a buffer and append a file f into its content.
+ * If *buflen == 0, then malloc a buffer first.
+ */
+void read_file(unsigned char **buf, size_t *buflen, size_t *len, FILE *f)
+{
+ if (*buflen == 0) {
+ *buflen = 4000;
+ *len = 0;
+ *buf = (unsigned char *) malloc(*buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+ }
+ do {
+ *len += fread(*buf + *len, 1, *buflen - *len, f);
+ if (*len == *buflen) {
+ *buflen *= 2;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+ }
+ if (ferror(f)) {
+ perror("Problem while reading input file");
+ exit(1);
+ }
+ } while (!feof(f));
+ if (!*len) return;
+ *buflen = *len;
+ *buf = (unsigned char *) realloc(*buf, *buflen);
+ if (!*buf) {
+ fprintf(stderr, "Oops, realloc failed when shrinking buffer!\n");
+ exit(1);
+ }
+
+ return;
+}
+
+
+/* marker codes */
+#define MARKER_STUFF 0x00
+#define MARKER_SDNORM 0x02
+#define MARKER_SDRST 0x03
+#define MARKER_ABORT 0x04
+#define MARKER_NEWLEN 0x05
+#define MARKER_ATMOVE 0x06
+#define MARKER_COMMENT 0x07
+#define MARKER_ESC 0xff
+
+
+/*
+ * Output (prefix of) a short byte sequence in hexadecimal
+ * for diagnostic purposes
+ */
+void fprint_bytes(FILE *f, unsigned char *p, size_t len, int width)
+{
+ size_t i;
+ size_t max = width / 3;
+ if (len > max)
+ max -= 7;
+ for (i = 0; i < len && i < max; i++)
+ fprintf(f, "%02x ", p[i]);
+ if (len > i)
+ fprintf(f, "... %lu bytes total", (unsigned long) len);
+ fprintf(f, "\n");
+}
+
+/*
+ * Read BIE and output human readable description of content
+ */
+void diagnose_bie(FILE *fin)
+{
+ unsigned char *bie, *p, *pnext;
+ size_t buflen = 0, len;
+ unsigned long xd, yd, l0;
+ int dl, d;
+ FILE *f = stdout;
+ extern unsigned char *jbg_next_pscdms(unsigned char *p, size_t len);
+ extern unsigned long jbg_stripes(unsigned long l0, unsigned long yd,
+ unsigned long d);
+ unsigned long stripes;
+ int layers, planes;
+ unsigned long sdes, sde = 0;
+ double size;
+
+ /* read BIH */
+ read_file(&bie, &buflen, &len, fin);
+ if (len < 20) {
+ fprintf(f, "Error: Input file is %lu < 20 bytes long and therefore "
+ "does not contain an intact BIE header!\n", (unsigned long) len);
+ free(bie);
+ return;
+ }
+
+ /* parse BIH */
+ fprintf(f, "BIH:\n\n DL = %d\n D = %d\n P = %d\n"
+ " - = %d\n XD = %lu\n YD = %lu\n L0 = %lu\n MX = %d\n"
+ " MY = %d\n",
+ dl = bie[0], d = bie[1], planes = bie[2], bie[3],
+ xd = ((unsigned long)bie[ 4] << 24) | ((unsigned long)bie[ 5] << 16)|
+ ((unsigned long) bie[ 6] << 8) | ((unsigned long) bie[ 7]),
+ yd = ((unsigned long)bie[ 8] << 24) | ((unsigned long)bie[ 9] << 16)|
+ ((unsigned long) bie[10] << 8) | ((unsigned long) bie[11]),
+ l0 = ((unsigned long)bie[12] << 24) | ((unsigned long)bie[13] << 16)|
+ ((unsigned long) bie[14] << 8) | ((unsigned long) bie[15]),
+ bie[16], bie[17]);
+ fprintf(f, " order = %d %s%s%s%s%s\n", bie[18],
+ bie[18] & JBG_HITOLO ? " HITOLO" : "",
+ bie[18] & JBG_SEQ ? " SEQ" : "",
+ bie[18] & JBG_ILEAVE ? " ILEAVE" : "",
+ bie[18] & JBG_SMID ? " SMID" : "",
+ bie[18] & 0xf0 ? " other" : "");
+ fprintf(f, " options = %d %s%s%s%s%s%s%s%s\n\n", bie[19],
+ bie[19] & JBG_LRLTWO ? " LRLTWO" : "",
+ bie[19] & JBG_VLENGTH ? " VLENGTH" : "",
+ bie[19] & JBG_TPDON ? " TPDON" : "",
+ bie[19] & JBG_TPBON ? " TPBON" : "",
+ bie[19] & JBG_DPON ? " DPON" : "",
+ bie[19] & JBG_DPPRIV ? " DPPRIV" : "",
+ bie[19] & JBG_DPLAST ? " DPLAST" : "",
+ bie[19] & 0x80 ? " other" : "");
+ if (d < dl) { fprintf(f, "D >= DL required!\n"); return; }
+ if (l0 == 0) { fprintf(f, "L0 > 0 required!\n"); return; }
+ stripes = jbg_stripes(l0, yd, d);
+ layers = d - dl + 1;
+ fprintf(f, " %lu stripes, %d layers, %d planes => ",
+ stripes, layers, planes);
+ if (planes == 0 || (ULONG_MAX / layers) / planes >= stripes) {
+ sdes = stripes * layers * planes;
+ fprintf(f, "%lu SDEs\n", sdes);
+ } else {
+ /* handle integer overflow */
+ fprintf(f, ">%lu SDEs!\n", ULONG_MAX);
+ return;
+ }
+ size = (double) planes * (double) yd * (double) jbg_ceil_half(xd, 3);
+ fprintf(f, " decompressed %.15g bytes\n\n", size);
+ if (planes == 0) { fprintf(f, "P > 0 required!\n\n"); }
+
+ /* parse BID */
+ fprintf(f, "BID:\n\n");
+ p = bie + 20; /* skip BIH */
+ if ((bie[19] & (JBG_DPON | JBG_DPPRIV | JBG_DPLAST))
+ == (JBG_DPON | JBG_DPPRIV))
+ p += 1728; /* skip DPTABLE */
+ if (p > bie + len) {
+ fprintf(f, "Error: Input file is %lu < 20+1728 bytes long and therefore "
+ "does not contain an intact BIE header with DPTABLE!\n",
+ (unsigned long) len);
+ return;
+ }
+ while (p != bie + len) {
+ if (p > bie + len - 2) {
+ fprintf(f, "%06lx: Error: single byte 0x%02x left\n",
+ (long) (p - bie), *p);
+ return;
+ }
+ pnext = jbg_next_pscdms(p, len - (p - bie));
+ if (p[0] != MARKER_ESC || p[1] == MARKER_STUFF) {
+ fprintf(f, "%06lx: PSCD: ", (long) (p - bie));
+ fprint_bytes(f, p, pnext ? (size_t) (pnext - p) : len - (p - bie), 60);
+ if (!pnext) {
+ fprintf(f, "Error: PSCD not terminated by SDNORM or SDRST marker\n");
+ return;
+ }
+ } else
+ switch (p[1]) {
+ case MARKER_SDNORM:
+ case MARKER_SDRST:
+ fprintf(f, "%06lx: ESC %s, ending SDE #%lu", (long) (p - bie),
+ (p[1] == MARKER_SDNORM) ? "SDNORM" : "SDRST", ++sde);
+ if (sde == sdes)
+ fprintf(f, " (final SDE)");
+ else if (sde == sdes + 1)
+ fprintf(f, " (first surplus SDE, VLENGTH = %d)",
+ (bie[19] & JBG_VLENGTH) > 0);
+ fprintf(f, "\n");
+ break;
+ case MARKER_ABORT:
+ fprintf(f, "%06lx: ESC ABORT\n", (long) (p - bie));
+ break;
+ case MARKER_NEWLEN:
+ fprintf(f, "%06lx: ESC NEWLEN ", (long) (p - bie));
+ if (p + 5 < bie + len) {
+ fprintf(f, "YD = %lu\n",
+ yd = (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]));
+ stripes = jbg_stripes(l0, yd, d);
+ fprintf(f, " %lu stripes, %d layers, %d planes => ",
+ stripes, layers, planes);
+ if ((ULONG_MAX / layers) / planes >= stripes) {
+ sdes = stripes * layers * planes;
+ fprintf(f, "%lu SDEs\n", sdes);
+ } else {
+ /* handle integer overflow */
+ fprintf(f, ">%lu SDEs!\n", ULONG_MAX);
+ return;
+ }
+ } else
+ fprintf(f, "unexpected EOF\n");
+ break;
+ case MARKER_ATMOVE:
+ fprintf(f, "%06lx: ESC ATMOVE ", (long) (p - bie));
+ if (p + 7 < bie + len)
+ fprintf(f, "YAT = %lu, tX = %d, tY = %d\n",
+ (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]), p[6], p[7]);
+ else
+ fprintf(f, "unexpected EOF\n");
+ break;
+ case MARKER_COMMENT:
+ fprintf(f, "%06lx: ESC COMMENT ", (long) (p - bie));
+ if (p + 5 < bie + len)
+ fprintf(f, "LC = %lu\n",
+ (((long) p[2] << 24) | ((long) p[3] << 16) |
+ ((long) p[4] << 8) | (long) p[5]));
+ else
+ fprintf(f, "unexpected EOF\n");
+ break;
+ default:
+ fprintf(f, "%06lx: ESC 0x%02x\n", (long) (p - bie), p[1]);
+ }
+ if (!pnext) {
+ fprintf(f, "Error encountered!\n");
+ return;
+ }
+ p = pnext;
+ }
+
+ free(bie);
+
+ return;
+}
+
+
+int main (int argc, char **argv)
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, j, result;
+ int all_args = 0, files = 0;
+ struct jbg_dec_state s;
+ unsigned char *buffer, *p;
+ size_t buflen, len, cnt;
+ size_t bytes_read = 0;
+ unsigned long xmax = 4294967295UL, ymax = 4294967295UL, max;
+ int plane = -1, use_graycode = 1, diagnose = 0, multi = 0;
+
+ buflen = 8000;
+ buffer = (unsigned char *) malloc(buflen);
+ if (!buffer) {
+ printf("Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ /* parse command line arguments */
+ progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (!all_args && argv[i][0] == '-')
+ if (argv[i][1] == 0) {
+ if (files++) usage();
+ } else
+ for (j = 1; j > 0 && argv[i][j]; j++)
+ switch(argv[i][j]) {
+ case '-' :
+ all_args = 1;
+ break;
+ case 'b':
+ use_graycode = 0;
+ break;
+ case 'm':
+ multi = 1;
+ break;
+ case 'd':
+ diagnose = 1;
+ break;
+ case 'x':
+ if (++i >= argc) usage();
+ xmax = atol(argv[i]);
+ j = -1;
+ break;
+ case 'y':
+ if (++i >= argc) usage();
+ ymax = atol(argv[i]);
+ j = -1;
+ break;
+ case 'p':
+ if (++i >= argc) usage();
+ plane = atoi(argv[i]);
+ j = -1;
+ break;
+ default:
+ usage();
+ }
+ else
+ switch (files++) {
+ case 0: fnin = argv[i]; break;
+ case 1: fnout = argv[i]; break;
+ default:
+ usage();
+ }
+ }
+
+ if (fnin) {
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ fprintf(stderr, "Can't open input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnin = "";
+ if (diagnose) {
+ diagnose_bie(fin);
+ exit(0);
+ }
+ if (fnout) {
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fprintf(stderr, "Can't open input file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnout = "";
+
+ /* send input file to decoder */
+ jbg_dec_init(&s);
+ jbg_dec_maxsize(&s, xmax, ymax);
+ /* read BIH first to check VLENGTH */
+ len = fread(buffer, 1, 20, fin);
+ if (len < 20) {
+ fprintf(stderr, "Input file '%s' (%lu bytes) must be at least "
+ "20 bytes long\n", fnin, (unsigned long) len);
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+ if (buffer[19] & JBG_VLENGTH) {
+ /* VLENGTH = 1 => we might encounter a NEWLEN, therefore read entire
+ * input file into memory and run two passes over it */
+ read_file(&buffer, &buflen, &len, fin);
+ /* scan for NEWLEN marker segments and update BIE header accordingly */
+ result = jbg_newlen(buffer, len);
+ /* feed data to decoder */
+ if (result == JBG_EOK) {
+ p = (unsigned char *) buffer;
+ result = JBG_EAGAIN;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ bytes_read += cnt;
+ }
+ }
+ } else {
+ /* VLENGTH = 0 => we can simply pass the input file directly to decoder */
+ result = JBG_EAGAIN;
+ do {
+ cnt = 0;
+ p = (unsigned char *) buffer;
+ while (len > 0 &&
+ (result == JBG_EAGAIN || (result == JBG_EOK && multi))) {
+ result = jbg_dec_in(&s, p, len, &cnt);
+ p += cnt;
+ len -= cnt;
+ bytes_read += cnt;
+ }
+ if (!(result == JBG_EAGAIN || (result == JBG_EOK && multi)))
+ break;
+ len = fread(buffer, 1, buflen, fin);
+ } while (len > 0);
+ if (ferror(fin)) {
+ fprintf(stderr, "Problem while reading input file '%s", fnin);
+ perror("'");
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+ }
+ if (result != JBG_EOK && result != JBG_EOK_INTR) {
+ fprintf(stderr, "Problem with input file '%s': %s\n"
+ "(error code 0x%02x, %lu = 0x%04lx BIE bytes processed)\n",
+ fnin, jbg_strerror(result), result,
+ (unsigned long) bytes_read, (unsigned long) bytes_read);
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+ if (plane >= 0 && jbg_dec_getplanes(&s) <= plane) {
+ fprintf(stderr, "Image has only %d planes!\n", jbg_dec_getplanes(&s));
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+
+ if (jbg_dec_getplanes(&s) == 1 || plane >= 0) {
+ /* write PBM output file */
+ fprintf(fout, "P4\n%10lu\n%10lu\n", jbg_dec_getwidth(&s),
+ jbg_dec_getheight(&s));
+ fwrite(jbg_dec_getimage(&s, plane < 0 ? 0 : plane), 1,
+ jbg_dec_getsize(&s), fout);
+ } else {
+ /* write PGM output file */
+ if ((size_t) jbg_dec_getplanes(&s) > sizeof(unsigned long) * 8) {
+ fprintf(stderr, "Image has too many planes (%d)!\n",
+ jbg_dec_getplanes(&s));
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+ max = 0;
+ for (i = jbg_dec_getplanes(&s); i > 0; i--)
+ max = (max << 1) | 1;
+ fprintf(fout, "P5\n%10lu\n%10lu\n%lu\n", jbg_dec_getwidth(&s),
+ jbg_dec_getheight(&s), max);
+ jbg_dec_merge_planes(&s, use_graycode, write_it, fout);
+ }
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+
+ jbg_dec_free(&s);
+
+ return 0;
+}
diff --git a/thirdparty/jbigkit/pbmtools/jbgtopbm85.c b/thirdparty/jbigkit/pbmtools/jbgtopbm85.c
new file mode 100644
index 000000000..9bce58755
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/jbgtopbm85.c
@@ -0,0 +1,205 @@
+/*
+ * jbgtopbm85 - JBIG to Portable Bitmap converter (T.85 version)
+ *
+ * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#include
+#include
+#include
+#include
+#include "jbig85.h"
+
+char *progname; /* global pointer to argv[0] */
+unsigned long y_0;
+fpos_t ypos;
+int ypos_error = 1;
+unsigned long ymax = 0;
+
+/*
+ * Print usage message and abort
+ */
+static void usage(void)
+{
+ fprintf(stderr, "JBIGtoPBM converter " JBG85_VERSION " (T.85 version) --\n"
+ "reads a bi-level image entity (BIE) as input file\n\n"
+ "usage: %s [ | - []]\n\n", progname);
+ fprintf(stderr, "options:\n\n"
+ " -x number\tmaximum number of pixels per line for which memory\n"
+ "\t\tis allocated (default: 8192)\n"
+ " -y number\tinterrupt decoder after this number of lines\n"
+ " -B number\tinput buffer size\n\n");
+ exit(1);
+}
+
+
+/*
+ * Call-back routine for merged image output
+ */
+int line_out(const struct jbg85_dec_state *s,
+ unsigned char *start, size_t len, unsigned long y, void *file)
+{
+ if (y == 0) {
+ /* prefix first line with PBM header */
+ fprintf((FILE *) file, "P4\n");
+ fprintf((FILE *) file, "%10lu\n", jbg85_dec_getwidth(s));
+ /* store file position of height, so we can update it after NEWLEN */
+ y_0 = jbg85_dec_getheight(s);
+ ypos_error = fgetpos((FILE *) file, &ypos);
+ fprintf((FILE *) file, "%10lu\n", y_0); /* pad number to 10 bytes */
+ }
+ fwrite(start, len, 1, (FILE *) file);
+ return y == ymax - 1;
+}
+
+
+int main (int argc, char **argv)
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, j, result;
+ int all_args = 0, files = 0;
+ struct jbg85_dec_state s;
+ unsigned char *inbuf, *outbuf;
+ size_t inbuflen = 8192, outbuflen, len, cnt, cnt2;
+ unsigned long xmax = 8192;
+ size_t bytes_read = 0;
+
+ /* parse command line arguments */
+ progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (!all_args && argv[i][0] == '-')
+ if (argv[i][1] == 0) {
+ if (files++) usage();
+ } else
+ for (j = 1; j > 0 && argv[i][j]; j++)
+ switch(argv[i][j]) {
+ case '-' :
+ all_args = 1;
+ break;
+ case 'x':
+ if (++i >= argc) usage();
+ j = -1;
+ xmax = atol(argv[i]);
+ break;
+ case 'y':
+ if (++i >= argc) usage();
+ j = -1;
+ ymax = atol(argv[i]);
+ break;
+ case 'B':
+ if (++i >= argc) usage();
+ j = -1;
+ inbuflen = atol(argv[i]);
+ if (inbuflen < 1) usage();
+ break;
+ default:
+ usage();
+ }
+ else
+ switch (files++) {
+ case 0: fnin = argv[i]; break;
+ case 1: fnout = argv[i]; break;
+ default:
+ usage();
+ }
+ }
+
+ inbuf = (unsigned char *) malloc(inbuflen);
+ outbuflen = ((xmax >> 3) + !!(xmax & 7)) * 3;
+ outbuf = (unsigned char *) malloc(outbuflen);
+ if (!inbuf || !outbuf) {
+ printf("Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ if (fnin) {
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ fprintf(stderr, "Can't open input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnin = "";
+ if (fnout) {
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fprintf(stderr, "Can't open input file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnout = "";
+
+ /* send input file to decoder */
+ jbg85_dec_init(&s, outbuf, outbuflen, line_out, fout);
+ result = JBG_EAGAIN;
+ while ((len = fread(inbuf, 1, inbuflen, fin))) {
+ result = jbg85_dec_in(&s, inbuf, len, &cnt);
+ bytes_read += cnt;
+ while (result == JBG_EOK_INTR) {
+ /* demonstrate decoder interrupt at given line number */
+ printf("Decoding interrupted after %lu lines and %lu BIE bytes "
+ "... continuing ...\n", s.y, (unsigned long) bytes_read);
+ /* and now continue decoding */
+ result = jbg85_dec_in(&s, inbuf + cnt, len - cnt, &cnt2);
+ bytes_read += cnt2;
+ cnt += cnt2;
+ }
+ if (result != JBG_EAGAIN)
+ break;
+ }
+ if (ferror(fin)) {
+ fprintf(stderr, "Problem while reading input file '%s", fnin);
+ perror("'");
+ if (fout != stdout) {
+ fclose(fout);
+ remove(fnout);
+ }
+ exit(1);
+ }
+ if (result == JBG_EAGAIN || result == JBG_EOK_INTR) {
+ /* signal end-of-BIE explicitely */
+ result = jbg85_dec_end(&s);
+ while (result == JBG_EOK_INTR) {
+ /* demonstrate decoder interrupt at given line number */
+ printf("Decoding interrupted after %lu lines and %lu BIE bytes "
+ "... continuing ...\n", s.y, (unsigned long) bytes_read);
+ result = jbg85_dec_end(&s);
+ }
+ }
+ if (result != JBG_EOK) {
+ fprintf(stderr, "Problem with input file '%s': %s\n"
+ "(error code 0x%02x, %lu = 0x%04lx BIE bytes "
+ "and %lu pixel rows processed)\n",
+ fnin, jbg85_strerror(result), result,
+ (unsigned long) bytes_read, (unsigned long) bytes_read, s.y);
+ if (fout != stdout) {
+ fclose(fout);
+ /*remove(fnout);*/
+ }
+ exit(1);
+ }
+
+ /* do we have to update the image height in the PBM header? */
+ if (!ypos_error && y_0 != jbg85_dec_getheight(&s)) {
+ if (fsetpos(fout, &ypos) == 0) {
+ fprintf(fout, "%10lu", jbg85_dec_getheight(&s)); /* pad to 10 bytes */
+ } else {
+ fprintf(stderr, "Problem while updating height in output file '%s",
+ fnout);
+ perror("'");
+ exit(1);
+ }
+ }
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/thirdparty/jbigkit/pbmtools/pbm.5 b/thirdparty/jbigkit/pbmtools/pbm.5
new file mode 100644
index 000000000..9b46dc0b1
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/pbm.5
@@ -0,0 +1,91 @@
+.TH pbm 5 "27 September 1991"
+.SH NAME
+pbm - portable bitmap file format
+.SH DESCRIPTION
+The portable bitmap format is a lowest common denominator monochrome
+file format.
+.IX "PBM file format"
+It was originally designed to make it reasonable to mail bitmaps
+between different types of machines using the typical stupid network
+mailers we have today.
+Now it serves as the common language of a large family of bitmap
+conversion filters.
+The definition is as follows:
+.IP - 2
+A "magic number" for identifying the file type.
+A pbm file's magic number is the two characters "P1".
+.IX "magic numbers"
+.IP - 2
+Whitespace (blanks, TABs, CRs, LFs).
+.IP - 2
+A width, formatted as ASCII characters in decimal.
+.IP - 2
+Whitespace.
+.IP - 2
+A height, again in ASCII decimal.
+.IP - 2
+Whitespace.
+.IP - 2
+Width * height bits, each either '1' or '0', starting at the top-left
+corner of the bitmap, proceeding in normal English reading order.
+.IP - 2
+The character '1' means black, '0' means white.
+.IP - 2
+Whitespace in the bits section is ignored.
+.IP - 2
+Characters from a "#" to the next end-of-line are ignored (comments).
+.IP - 2
+No line should be longer than 70 characters.
+.PP
+Here is an example of a small bitmap in this format:
+.nf
+P1
+# feep.pbm
+24 7
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0
+0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0
+0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 0 0 0 1 1 1 1 0
+0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0
+0 1 0 0 0 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+.fi
+.PP
+Programs that read this format should be as lenient as possible,
+accepting anything that looks remotely like a bitmap.
+.PP
+There is also a variant on the format, available
+by setting the RAWBITS option at compile time. This variant is
+.IX RAWBITS
+different in the following ways:
+.IP - 2
+The "magic number" is "P4" instead of "P1".
+.IP - 2
+The bits are stored eight per byte, high bit first low bit last.
+.IP - 2
+No whitespace is allowed in the bits section, and only a single character
+of whitespace (typically a newline) is allowed after the height.
+.IP - 2
+The files are eight times smaller and many times faster to read and write.
+.SH "SEE ALSO"
+atktopbm(1), brushtopbm(1), cmuwmtopbm(1), g3topbm(1),
+gemtopbm(1), icontopbm(1),
+macptopbm(1), mgrtopbm(1), pi3topbm(1), xbmtopbm(1),
+ybmtopbm(1),
+pbmto10x(1), pnmtoascii(1), pbmtoatk(1), pbmtobbnbg(1),
+pbmtocmuwm(1), pbmtoepson(1),
+pbmtog3(1), pbmtogem(1), pbmtogo(1), pbmtoicon(1), pbmtolj(1),
+pbmtomacp(1), pbmtomgr(1), pbmtopi3(1), pbmtoplot(1), pbmtoptx(1),
+pbmtox10bm(1), pbmtoxbm(1), pbmtoybm(1),
+pbmtozinc(1),
+pbmlife(1), pbmmake(1), pbmmask(1), pbmreduce(1),
+pbmtext(1), pbmupc(1),
+pnm(5), pgm(5), ppm(5)
+.SH AUTHOR
+Copyright (C) 1989, 1991 by Jef Poskanzer.
+.\" Permission to use, copy, modify, and distribute this software and its
+.\" documentation for any purpose and without fee is hereby granted, provided
+.\" that the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation. This software is provided "as is" without express or
+.\" implied warranty.
diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg.1 b/thirdparty/jbigkit/pbmtools/pbmtojbg.1
new file mode 100644
index 000000000..63a49eac3
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/pbmtojbg.1
@@ -0,0 +1,306 @@
+.TH PBMTOJBG 1 "2014-08-22"
+.SH NAME
+pbmtojbg \- portable bitmap to JBIG1 file converter
+.SH SYNOPSIS
+.B pbmtojbg
+[
+.I options
+]
+[
+.I input-file
+| \- [
+.I output-file
+]]
+.br
+.SH DESCRIPTION
+Reads a file in portable bitmap (PBM) format, compresses it,
+and outputs the image as a
+.I JBIG1
+bi-level image entity (BIE).
+
+.I JBIG1
+is a highly effective, lossless compression algorithm for
+bi-level images (one bit per pixel), which is particularly suitable
+for scanned document pages.
+
+A
+.I JBIG1
+encoded image can be stored in several resolution layers (progressive mode).
+This allows the decoder to recover a lower-resolution version of the
+encoded image without having to read the complete file.
+These resolution layers can be stored all in one single BIE or they
+can be stored in several separate BIE files.
+All resolution layers, except the lowest one, are stored merely as
+differences to the next lower resolution layer. This requires less
+space than encoding the full image completely every time. Each resolution
+layer has twice the number of horizontal and vertical pixels than
+the next lower layer.
+
+For best speed and compression, if you are not interested in
+efficiently extracting lower-resolution versions from the compressed
+file, use sequential mode (single resolution layer, option
+.BR \-q ).
+
+.I JBIG1
+files can also store several bits per pixel, as separate bitmap planes,
+and
+.I pbmtojbg
+can read a portable graymap format (PGM) file and transform it into
+a multi-plane BIE.
+
+.SH OPTIONS
+.TP 12
+.BI \-
+A single hyphen instead of an input file name causes
+.I pbmtojbg
+to read the data from standard input instead of from a file.
+.TP
+.BI \-v
+List technical details of the created file (verbose mode).
+.TP
+.BI \-f
+This option makes the output file comply with the \[lq]facsimile application
+profile\[rq] defined in ITU-T Recommendation T.85. It is a shortcut for
+.BR "-q -o 0 -p 8 -s 128 -t 1 -m 127" .
+.TP
+.BI \-C " string"
+Add the
+.I string
+in a comment marker segment to the produced data stream.
+.br
+(There is no support at present for adding comments that contain a
+zero byte.)
+.P
+Options affecting the number of resolution layers produced:
+.TP 12
+.BI \-q
+Encode the image in one single resolution layer (sequential mode), which
+is usually the most efficient compression method. By default, the number
+of resolution layers is instead chosen automatically such that the lowest layer
+image is not larger than 640 \(mu 480 pixels.
+This option is just a shortcut for
+.BR "-d 0" .
+.TP
+.BI \-x " number"
+Specify the maximal horizontal size of the lowest resolution layer.
+Default: 640 pixels
+.TP
+.BI \-y " number"
+Specify the maximal vertical size of the lowest resolution layer.
+Default: 480 pixels
+.TP
+.BI \-d " number"
+Specify the total number of differential resolution layers into which to split
+the input image (in addition to the lowest layer). Each additional
+layer reduces both the width and height of layer 0 by 50%.
+This option overrides options
+.B \-x
+and
+.BR \-y ,
+which are usually a more convenient way of selecting the number of
+resolution layers.
+.TP
+.BI \-l " number"
+Select the lowest resolution layer
+.I D\s-2\dL\u\s0
+that will appear in the generated
+BIE.
+.I JBIG1
+can store the various resolution layers of an image in progressive mode
+split across several BIEs. Options
+.B \-l
+and
+.B \-h
+allow you to select the resolution-layer interval that will appear
+in the created BIE. The lowest resolution layer has number 0 and
+this is also the default value. The default is to write all layers.
+.TP
+.BI \-h " number"
+Select the highest resolution layer
+.I D
+that will appear in the generated BIE. The default is to write all layers.
+See also option
+.BR \-l .
+.P
+Options for changing other parameters indicated in the BIE header:
+.TP 12
+.BI \-s " number"
+The
+.I JBIG1
+algorithm splits each image into horizontal stripes. This
+option specifies
+.IR L\s-2\d0\u\s0 ,
+the layer-0 height of each such stripe (except for the last one,
+which can be shorter).
+The default is to split the whole image into approximately 35 stripes.
+.TP
+.BI \-m " number"
+Select the maximum horizontal offset
+.I M\s-2\dX\u\s0
+of the adaptive template pixel.
+The
+.I JBIG1
+encoder uses ten neighbour pixels to estimate the probability of the
+next pixel being black or white. It can adjust the location of one
+of these ten context pixels.
+This is especially useful for dithered images, as long as the
+distance of this adaptive pixel can be adjusted to the period of the
+dither pattern. By default, the adaptive template pixel is allowed to
+move up to 8 pixels away horizontally. This encoder supports distances
+up to 127 pixels.
+.br
+Annex A of the standard suggests that decoders should support at least
+a horizontal distance of 16 pixels, so using values not higher than 16
+for
+.I number
+might increase the chances of interoperability with other
+.I JBIG1
+implementations. On the other hand, the T.85 fax application profile
+requires decoders to support horizontal offsets up to 127 pixels,
+which is the maximum value permitted by the standard. (The maximal
+vertical offset
+.I M\s-2\dY\u\s0
+of the adaptive template pixel is always zero for this
+encoder.)
+.TP
+.BI \-o " number"
+Specify the order in which image data appears in the output.
+.I JBIG1
+separates an image into several horizontal stripes, resolution layers
+and planes, were each plane contains one bit per pixel. One single
+stripe in one plane and layer is encoded as a data unit called stripe
+data entity (SDE) inside the BIE. There are 12 different possible
+orders in which the SDEs can be stored inside the BIE and
+.I number
+selects which one shall be used. For receiving applications, the order of
+the SDEs mainly matters if they want to start decoding an image before
+it has been received completely.
+For instance, some applications may prefer that the outermost of the
+three loops (stripes, layers, planes) is over all layers so that all
+data of the lowest resolution layer is transmitted first.
+.br
+The following values for
+.I number
+select these loop arrangements for writing the SDEs (outermost
+loop first):
+
+ 0 planes, layers, stripes
+.br
+ 2 layers, planes, stripes
+.br
+ 3 layers, stripes, planes
+.br
+ 4 stripes, planes, layers
+.br
+ 5 planes, stripes, layers
+.br
+ 6 stripes, layers, planes
+
+All loops count starting with zero, however by adding 8 to the above
+order code, the layer loop can be reversed so that it counts down to zero
+and then higher resolution layers will be stored before lower layers.
+The default order is 3, which writes at first all planes of the first
+stripe and then completes layer 0 before continuing with the next
+layer, and so on.
+.TP
+.BI \-p " number"
+This option activates or deactivates various optional algorithms
+defined in the
+.I JBIG1
+standard. Just add the numbers of the following options which you want to
+activate in
+order to get the
+.I number
+value:
+
+ 4 deterministic prediction (DPON)
+.br
+ 8 layer 0 typical prediction (TPBON)
+.br
+ 16 diff. layer typ. pred. (TPDON)
+.br
+ 64 layer 0 two-line template (LRLTWO)
+
+This option is only for specialist applications (e.g., communication with
+.I JBIG1
+subset implementations, debugging). The default is 28, which usually
+provides the best compression result.
+.P
+Options affecting the processing of PGM files:
+.TP 12
+.BI \-b
+Use binary values instead of Gray code words in order to encode pixel
+values in multiple bit planes. This option has only an effect if the
+input is a PGM file and if more than one plane is produced. Note that
+the decoder has to make the same choice, but the BIE does not
+indicate whether Gray or binary code words were used by the encoder.
+.TP
+.BI \-t " number"
+Encode only the specified number of most significant bit planes. This
+option reduces the depth of an input PGM file if not all
+bits per pixel are needed in the output.
+.P
+Options to help generating test files:
+.TP 12
+.BI \-r
+Use the SDRST marker instead of the normal SDNORM marker. The probably
+only useful application for this option is to generate test data for
+checking whether a
+.I JBIG1
+decoder has implemented SDRST correctly. In a normal
+.I JBIG1
+data stream, each stripe data entity (SDE) is terminated by an SDNORM
+marker, which preserves the state of the arithmetic encoder (and more)
+for the next stripe in the same layer. The alternative SDRST marker
+resets this state at the end of the stripe.
+.TP
+.BI \-Y " number"
+Specify a preliminary image height
+.IR Y\s-2\dD\u\s0 .
+A long time ago, there were fax
+machines that couldn't even hold a single page in memory. They had to
+start transmitting data before the page was scanned in completely and
+before even the height of the resulting image was known.
+The authors of the standard added a rather ugly hack to JBIG1
+to support this use case. The NEWLEN marker segment can
+override the image height stated in the BIE header anywhere later in
+the data stream. Normally
+.I pbmtojbg
+never generates NEWLEN marker segments, as it knows the correct image
+height when it outputs the header. This option is solely intended for
+the purpose of generating test files with NEWLEN marker segments. It
+can be used to specify a higher initial image height for use in the
+BIE header, and
+.I pbmtojbg
+will then add a NEWLEN marker segment at the latest possible
+opportunity to the data stream to signal the correct final height.
+It will also set the VLENGTH flag in the BIE header.
+.TP
+.BI \-c
+Determine the adaptive template pixel movement as suggested in Annex C
+of the standard. By default the template change takes place directly
+in the next line, which is most effective. However, a few conformance
+test examples in the standard require the adaptive template change to
+be delayed until the first line of the next stripe. This option
+selects this special behavior, which is normally not useful other than
+for conformance testing.
+.SH BUGS
+Using standard input and standard output for binary data works only on
+systems where there is no difference between binary and text streams
+(e.g., Unix). On other systems (e.g., MS-DOS), using standard input or
+standard output may cause control characters like CR or LF to be
+inserted or deleted and this will damage the binary data.
+.SH STANDARDS
+This program implements the
+.I JBIG1
+image coding algorithm as specified in international standard ISO/IEC
+11544:1993 and ITU-T Recommendation T.82(1993).
+.SH AUTHOR
+Markus Kuhn wrote
+.UR http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+.I JBIG-KIT
+.UE ,
+which includes
+.IR pbmtojbg .
+.SH SEE ALSO
+pbm(5), pgm(5), jbgtopbm(1)
diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg.c b/thirdparty/jbigkit/pbmtools/pbmtojbg.c
new file mode 100644
index 000000000..8892a0878
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/pbmtojbg.c
@@ -0,0 +1,455 @@
+/*
+ * pbmtojbg - Portable Bitmap to JBIG converter
+ *
+ * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "jbig.h"
+
+
+char *progname; /* global pointer to argv[0] */
+unsigned long total_length = 0; /* used for determining output file length */
+
+
+/*
+ * Print usage message and abort
+ */
+static void usage(void)
+{
+ fprintf(stderr,
+ "PBMtoJBIG converter " JBG_VERSION " -- "
+ "creates bi-level image entity (BIE) as output file\n\n"
+ "usage: %s [] [ | - []]\n\n"
+ "options:\n\n", progname);
+ fprintf(stderr,
+ " -q\t\tsequential coding, no differential layers (like -d 0)\n"
+ " -x number\tmaximum width of lowest resolution layer (default 640)\n"
+ " -y number\tmaximum height of lowest resolution layer (default 480)\n"
+ " -l number\tlowest layer written to output file (default 0)\n"
+ " -h number\thighest layer written to output file (default max)\n"
+ " -b\t\tuse binary code for multiple bitplanes (default: Gray code)\n"
+ " -d number\ttotal number of differential layers (overrides -x and -y)\n"
+ " -s number\theight of a stripe in layer 0\n");
+ fprintf(stderr,
+ " -m number\tmaximum adaptive template pixel horizontal offset (default 8)\n"
+ " -t number\tencode only that many most significant planes\n"
+ " -o number\torder byte value: add 1=SMID, 2=ILEAVE, 4=SEQ, 8=HITOLO\n"
+ "\t\t(default 3 = ILEAVE+SMID)\n"
+ " -p number\toptions byte value: add DPON=4, TPBON=8, TPDON=16, LRLTWO=64\n"
+ "\t\t(default 28 = DPON+TPBON+TPDON)\n");
+ fprintf(stderr,
+ " -C string\tadd the provided string as a comment marker segment\n"
+ " -c\t\tdelay adaptive template changes to first line of next stripe\n"
+ "\t\t(only provided for a conformance test)\n"
+ " -r\t\tterminate each stripe with SDRST marker\n"
+ "\t\t(only intended for decoder testing)\n" );
+ fprintf(stderr,
+ " -Y number\tannounce in header initially this larger image height\n"
+ "\t\t(only for generating test files with NEWLEN and VLENGTH=1)\n"
+ " -f\t\tchose encoding options for T.85 fax profile complianance\n"
+ " -v\t\tverbose output\n\n");
+ exit(1);
+}
+
+
+/*
+ * malloc() with exception handler
+ */
+void *checkedmalloc(size_t n)
+{
+ void *p;
+
+ if ((p = malloc(n)) == NULL) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ return p;
+}
+
+
+/*
+ * Read an ASCII integer number from file f and skip any PBM
+ * comments which are encountered.
+ */
+static unsigned long getint(FILE *f)
+{
+ int c;
+ unsigned long i;
+
+ while ((c = getc(f)) != EOF)
+ if (c == '#')
+ while ((c = getc(f)) != EOF && !(c == 13 || c == 10)) ;
+ else if (!isspace(c))
+ break;
+ if (c == EOF) return 0;
+ ungetc(c, f);
+ if (fscanf(f, "%lu", &i) != 1) {
+ fprintf(stderr, "Unsigned integer value expected!\n");
+ exit(1);
+ }
+
+ return i;
+}
+
+
+/*
+ * Callback procedure which is used by JBIG encoder to deliver the
+ * encoded data. It simply sends the bytes to the output file.
+ */
+static void data_out(unsigned char *start, size_t len, void *file)
+{
+ fwrite(start, len, 1, (FILE *) file);
+ total_length += len;
+ return;
+}
+
+
+int main (int argc, char **argv)
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, j, c;
+ int all_args = 0, files = 0;
+ unsigned long x, y;
+ unsigned long width, height, max, v;
+ unsigned long bpl;
+ int bpp, planes, encode_planes = -1;
+ size_t bitmap_size;
+ char type;
+ unsigned char **bitmap, *p, *image;
+ struct jbg_enc_state s;
+ int verbose = 0, delay_at = 0, reset = 0, use_graycode = 1;
+ long mwidth = 640, mheight = 480;
+ int dl = -1, dh = -1, d = -1, mx = -1;
+ unsigned long l0 = 0, y1 = 0;
+ char *comment = NULL;
+ int options = JBG_TPDON | JBG_TPBON | JBG_DPON;
+ int order = JBG_ILEAVE | JBG_SMID;
+
+ /* parse command line arguments */
+ progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (!all_args && argv[i][0] == '-')
+ if (argv[i][1] == 0) {
+ if (files++) usage();
+ } else
+ for (j = 1; j > 0 && argv[i][j]; j++)
+ switch(argv[i][j]) {
+ case '-' :
+ all_args = 1;
+ break;
+ case 0 :
+ if (files++) usage();
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'b':
+ use_graycode = 0;
+ break;
+ case 'c':
+ delay_at = 1;
+ break;
+ case 'r':
+ reset = 1;
+ break;
+ case 'f':
+ d = 0;
+ order = 0;
+ options = 8;
+ l0 = 128;
+ encode_planes = 1;
+ mx = 127;
+ break;
+ case 'x':
+ if (++i >= argc) usage();
+ j = -1;
+ mwidth = atol(argv[i]);
+ break;
+ case 'y':
+ if (++i >= argc) usage();
+ j = -1;
+ mheight = atol(argv[i]);
+ break;
+ case 'Y':
+ if (++i >= argc) usage();
+ j = -1;
+ y1 = atol(argv[i]);
+ break;
+ case 'o':
+ if (++i >= argc) usage();
+ j = -1;
+ order = atoi(argv[i]);
+ break;
+ case 'p':
+ if (++i >= argc) usage();
+ j = -1;
+ options = atoi(argv[i]);
+ break;
+ case 'l':
+ if (++i >= argc) usage();
+ j = -1;
+ dl = atoi(argv[i]);
+ break;
+ case 'h':
+ if (++i >= argc) usage();
+ j = -1;
+ dh = atoi(argv[i]);
+ break;
+ case 'q':
+ d = 0;
+ break;
+ case 'd':
+ if (++i >= argc) usage();
+ j = -1;
+ d = atoi(argv[i]);
+ break;
+ case 's':
+ if (++i >= argc) usage();
+ j = -1;
+ l0 = atol(argv[i]);
+ break;
+ case 't':
+ if (++i >= argc) usage();
+ j = -1;
+ encode_planes = atoi(argv[i]);
+ break;
+ case 'm':
+ if (++i >= argc) usage();
+ j = -1;
+ mx = atoi(argv[i]);
+ break;
+ case 'C':
+ if (++i >= argc) usage();
+ j = -1;
+ comment = argv[i];
+ break;
+ default:
+ usage();
+ }
+ else
+ switch (files++) {
+ case 0: fnin = argv[i]; break;
+ case 1: fnout = argv[i]; break;
+ default:
+ usage();
+ }
+ }
+
+ if (fnin) {
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ fprintf(stderr, "Can't open input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnin = "";
+ if (fnout) {
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fprintf(stderr, "Can't open input file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnout = "";
+
+ /* read PBM header */
+ while ((c = getc(fin)) != EOF && (isspace(c) || c == '#'))
+ if (c == '#')
+ while ((c = getc(fin)) != EOF && !(c == 13 || c == 10)) ;
+ if (c != 'P') {
+ fprintf(stderr, "Input file '%s' does not look like a PBM file!\n", fnin);
+ exit(1);
+ }
+ type = getc(fin);
+ width = getint(fin);
+ height = getint(fin);
+ if (width < 1 || height < 1 ||
+ width > 0xffffffff || height > 0xffffffff) {
+ fprintf(stderr, "Invalid width or height!\n");
+ exit(1);
+ }
+ if (type == '2' || type == '5' ||
+ type == '3' || type == '6')
+ max = getint(fin);
+ else
+ max = 1;
+ if (max < 1) {
+ fprintf(stderr, "Invalid maxval!\n");
+ exit(1);
+ }
+ for (planes = 0, v = max; v; planes++, v >>= 1) ;
+ bpp = (planes + 7) / 8;
+ if (encode_planes < 1 || encode_planes > planes)
+ encode_planes = planes;
+ fgetc(fin); /* skip line feed */
+
+ /* read PBM image data */
+ bpl = jbg_ceil_half(width, 3); /* bytes per line */
+ if (ULONG_MAX / height < bpl) {
+ fprintf(stderr, "Image too large!\n");
+ exit(1);
+ }
+ bitmap_size = bpl * (size_t) height;
+ bitmap = (unsigned char **) checkedmalloc(sizeof(unsigned char *) *
+ encode_planes);
+ for (i = 0; i < encode_planes; i++)
+ bitmap[i] = (unsigned char *) checkedmalloc(bitmap_size);
+ switch (type) {
+ case '1':
+ /* PBM text format */
+ p = bitmap[0];
+ for (y = 0; y < height; y++)
+ for (x = 0; x <= ((width-1) | 7); x++) {
+ *p <<= 1;
+ if (x < width)
+ *p |= getint(fin) & 1;
+ if ((x & 7) == 7)
+ ++p;
+ }
+ break;
+ case '4':
+ /* PBM raw binary format */
+ fread(bitmap[0], bitmap_size, 1, fin);
+ break;
+ case '2':
+ case '5':
+ /* PGM */
+ if ((ULONG_MAX / bpp) / height < width) {
+ fprintf(stderr, "Image too large!\n");
+ exit(1);
+ }
+ image = (unsigned char *) checkedmalloc(width * height * bpp);
+ if (type == '2') {
+ for (x = 0; x < width * height; x++) {
+ v = getint(fin);
+ for (j = 0; j < bpp; j++)
+ image[x * bpp + (bpp - 1) - j] = v >> (j * 8);
+ }
+ } else
+ fread(image, width * height, bpp, fin);
+ jbg_split_planes(width, height, planes, encode_planes, image, bitmap,
+ use_graycode);
+ free(image);
+ break;
+ default:
+ fprintf(stderr, "Unsupported PBM type P%c!\n", type);
+ exit(1);
+ }
+ if (ferror(fin)) {
+ fprintf(stderr, "Problem while reading input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ if (feof(fin)) {
+ fprintf(stderr, "Unexpected end of input file '%s'!\n", fnin);
+ exit(1);
+ }
+
+ /* Test for valid parameters */
+ if (width < 1 || height < 1) {
+ fprintf(stderr, "Image dimensions must be positive!\n");
+ exit(1);
+ }
+ if (encode_planes < 1 || encode_planes > 255) {
+ fprintf(stderr, "Number of planes must be in range 1-255!\n");
+ exit(1);
+ }
+
+ /* Test the final byte in each image line for correct zero padding */
+ if ((width & 7) && type == '4') {
+ for (y = 0; y < height; y++)
+ if (bitmap[0][y * bpl + bpl - 1] & ((1 << (8 - (width & 7))) - 1)) {
+ fprintf(stderr, "Warning: No zero padding in last byte (0x%02x) of "
+ "line %lu!\n", bitmap[0][y * bpl + bpl - 1], y + 1);
+ break;
+ }
+ }
+
+ /* Apply JBIG algorithm and write BIE to output file */
+
+ /* initialize parameter struct for JBIG encoder*/
+ jbg_enc_init(&s, width, height, encode_planes, bitmap, data_out, fout);
+
+ /* Select number of resolution layers either directly or based
+ * on a given maximum size for the lowest resolution layer */
+ if (d >= 0)
+ jbg_enc_layers(&s, d);
+ else
+ jbg_enc_lrlmax(&s, mwidth, mheight);
+
+ /* Specify a few other options (each is ignored if negative) */
+ if (delay_at)
+ options |= JBG_DELAY_AT;
+ if (reset)
+ options |= JBG_SDRST;
+ if (comment) {
+ s.comment_len = strlen(comment);
+ s.comment = (unsigned char *) comment;
+ }
+ if (y1)
+ s.yd1 = y1;
+ jbg_enc_lrange(&s, dl, dh);
+ jbg_enc_options(&s, order, options, l0, mx, -1);
+
+ /* now encode everything and send it to data_out() */
+ jbg_enc_out(&s);
+
+ /* give encoder a chance to free its temporary data structures */
+ jbg_enc_free(&s);
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+
+ /* In case the user wants to know all the gory details ... */
+ if (verbose) {
+ fprintf(stderr, "Information about the created JBIG bi-level image entity "
+ "(BIE):\n\n");
+ fprintf(stderr, " input image size: %lu x %lu pixel\n",
+ s.xd, s.yd);
+ fprintf(stderr, " bit planes: %d\n", s.planes);
+ if (s.planes > 1)
+ fprintf(stderr, " encoding: %s code, MSB first\n",
+ use_graycode ? "Gray" : "binary");
+ fprintf(stderr, " stripes: %lu\n", s.stripes);
+ fprintf(stderr, " lines per stripe in layer 0: %lu\n", s.l0);
+ fprintf(stderr, " total number of diff. layers: %d\n", s.d);
+ fprintf(stderr, " lowest layer in BIE: %d\n", s.dl);
+ fprintf(stderr, " highest layer in BIE: %d\n", s.dh);
+ fprintf(stderr, " lowest layer size: %lu x %lu pixel\n",
+ jbg_ceil_half(s.xd, s.d - s.dl), jbg_ceil_half(s.yd, s.d - s.dl));
+ fprintf(stderr, " highest layer size: %lu x %lu pixel\n",
+ jbg_ceil_half(s.xd, s.d - s.dh), jbg_ceil_half(s.yd, s.d - s.dh));
+ fprintf(stderr, " option bits:%s%s%s%s%s%s%s\n",
+ s.options & JBG_LRLTWO ? " LRLTWO" : "",
+ s.options & JBG_VLENGTH ? " VLENGTH" : "",
+ s.options & JBG_TPDON ? " TPDON" : "",
+ s.options & JBG_TPBON ? " TPBON" : "",
+ s.options & JBG_DPON ? " DPON" : "",
+ s.options & JBG_DPPRIV ? " DPPRIV" : "",
+ s.options & JBG_DPLAST ? " DPLAST" : "");
+ fprintf(stderr, " order bits:%s%s%s%s\n",
+ s.order & JBG_HITOLO ? " HITOLO" : "",
+ s.order & JBG_SEQ ? " SEQ" : "",
+ s.order & JBG_ILEAVE ? " ILEAVE" : "",
+ s.order & JBG_SMID ? " SMID" : "");
+ fprintf(stderr, " AT maximum x-offset: %d\n"
+ " AT maximum y-offset: %d\n", s.mx, s.my);
+ fprintf(stderr, " length of output file: %lu byte\n\n",
+ total_length);
+ }
+
+ return 0;
+}
diff --git a/thirdparty/jbigkit/pbmtools/pbmtojbg85.c b/thirdparty/jbigkit/pbmtools/pbmtojbg85.c
new file mode 100644
index 000000000..710efe1df
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/pbmtojbg85.c
@@ -0,0 +1,280 @@
+/*
+ * pbmtojbg85 - Portable Bitmap to JBIG converter (T.85 version)
+ *
+ * Markus Kuhn - http://www.cl.cam.ac.uk/~mgk25/jbigkit/
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include "jbig85.h"
+
+
+char *progname; /* global pointer to argv[0] */
+
+
+/*
+ * Print usage message and abort
+ */
+static void usage(void)
+{
+ fprintf(stderr,
+ "PBMtoJBIG converter " JBG85_VERSION " (T.85 version) --\n"
+ "creates bi-level image entity (BIE) as output file\n\n"
+ "usage: %s [] [ | - []]\n\n"
+ "options:\n\n", progname);
+ fprintf(stderr,
+ " -s number\theight of a stripe\n");
+ fprintf(stderr,
+ " -m number\tmaximum adaptive template pixel horizontal offset (default 8)\n"
+ " -p number\toptions byte value: add TPBON=8, LRLTWO=64\n"
+ "\t\t(default 8 = TPBON)\n");
+ fprintf(stderr,
+ " -C string\tadd the provided string as a comment marker segment\n");
+ fprintf(stderr,
+ " -Y yi yr\tannounce in header initially the larger image height yi\n"
+ "\t\tand then announce after line yr has been encoded the real height\n"
+ "\t\tusing NEWLEN marker (for testing NEWLEN and VLENGTH=1 function)\n\n");
+ exit(1);
+}
+
+
+/*
+ * malloc() with exception handler
+ */
+void *checkedmalloc(size_t n)
+{
+ void *p;
+
+ if ((p = malloc(n)) == NULL) {
+ fprintf(stderr, "Sorry, not enough memory available!\n");
+ exit(1);
+ }
+
+ return p;
+}
+
+
+/*
+ * Read an ASCII integer number from file f and skip any PBM
+ * comments which are encountered.
+ */
+static unsigned long getint(FILE *f)
+{
+ int c;
+ unsigned long i;
+
+ while ((c = getc(f)) != EOF)
+ if (c == '#')
+ while ((c = getc(f)) != EOF && !(c == 13 || c == 10)) ;
+ else if (!isspace(c))
+ break;
+ if (c == EOF) return 0;
+ ungetc(c, f);
+ if (fscanf(f, "%lu", &i) != 1) {
+ fprintf(stderr, "Unsigned integer value expected!\n");
+ exit(1);
+ }
+
+ return i;
+}
+
+
+/*
+ * Callback procedure which is used by JBIG encoder to deliver the
+ * encoded data. It simply sends the bytes to the output file.
+ */
+static void data_out(unsigned char *start, size_t len, void *file)
+{
+ fwrite(start, len, 1, (FILE *) file);
+ return;
+}
+
+
+int main (int argc, char **argv)
+{
+ FILE *fin = stdin, *fout = stdout;
+ const char *fnin = NULL, *fnout = NULL;
+ int i, j, c;
+ int all_args = 0, files = 0;
+ unsigned long x, y;
+ unsigned long width, height;
+ size_t bpl;
+ char type;
+ unsigned char *p, *lines, *next_line;
+ unsigned char *prev_line = NULL, *prevprev_line = NULL;
+ struct jbg85_enc_state s;
+ int mx = -1;
+ unsigned long l0 = 0, yi = 0, yr = 0;
+ char *comment = NULL;
+ int options = JBG_TPBON;
+
+ /* parse command line arguments */
+ progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (!all_args && argv[i][0] == '-')
+ if (argv[i][1] == 0) {
+ if (files++) usage();
+ } else
+ for (j = 1; j > 0 && argv[i][j]; j++)
+ switch(argv[i][j]) {
+ case '-' :
+ all_args = 1;
+ break;
+ case 0 :
+ if (files++) usage();
+ break;
+ case 'Y':
+ if (i+2 >= argc) usage();
+ j = -1;
+ yi = atol(argv[++i]);
+ yr = atol(argv[++i]);
+ break;
+ case 'p':
+ if (++i >= argc) usage();
+ j = -1;
+ options = atoi(argv[i]);
+ break;
+ case 's':
+ if (++i >= argc) usage();
+ j = -1;
+ l0 = atol(argv[i]);
+ break;
+ case 'm':
+ if (++i >= argc) usage();
+ j = -1;
+ mx = atoi(argv[i]);
+ break;
+ case 'C':
+ if (++i >= argc) usage();
+ j = -1;
+ comment = argv[i];
+ break;
+ default:
+ usage();
+ }
+ else
+ switch (files++) {
+ case 0: fnin = argv[i]; break;
+ case 1: fnout = argv[i]; break;
+ default:
+ usage();
+ }
+ }
+
+ /* open input file */
+ if (fnin) {
+ fin = fopen(fnin, "rb");
+ if (!fin) {
+ fprintf(stderr, "Can't open input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnin = "";
+
+ /* read PBM header */
+ while ((c = getc(fin)) != EOF && (isspace(c) || c == '#'))
+ if (c == '#')
+ while ((c = getc(fin)) != EOF && !(c == 13 || c == 10)) ;
+ type = getc(fin);
+ if (c != 'P' || (type != '1' && type != '4')) {
+ fprintf(stderr, "Input file '%s' does not look like a PBM file!\n", fnin);
+ exit(1);
+ }
+ width = getint(fin);
+ height = getint(fin);
+ fgetc(fin); /* skip line feed */
+
+ /* Test for valid parameters */
+ if (width < 1 || height < 1 ||
+ width > 0xffffffff || height > 0xffffffff) {
+ fprintf(stderr, "Invalid width or height!\n");
+ exit(1);
+ }
+
+ /* allocate buffer for a single image line */
+ bpl = (width >> 3) + !!(width & 7); /* bytes per line */
+ lines = (unsigned char *) checkedmalloc(bpl * 3);
+
+ /* open output file */
+ if (fnout) {
+ fout = fopen(fnout, "wb");
+ if (!fout) {
+ fprintf(stderr, "Can't open input file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+ } else
+ fnout = "";
+
+ /* initialize parameter struct for JBIG encoder*/
+ jbg85_enc_init(&s, width, yi ? yi : height, data_out, fout);
+
+ /* Specify a few other options (each is ignored if negative) */
+ if (yi)
+ options |= JBG_VLENGTH;
+ if (comment) {
+ s.comment_len = strlen(comment);
+ s.comment = (unsigned char *) comment;
+ }
+ jbg85_enc_options(&s, options, l0, mx);
+
+ for (y = 0; y < height; y++) {
+
+ /* Use a 3-line ring buffer, because the encoder requires that the two
+ * previously supplied lines are still in memory when the next line is
+ * processed. */
+ next_line = lines + (y%3)*bpl;
+
+ switch (type) {
+ case '1':
+ /* PBM text format */
+ p = next_line;
+ for (x = 0; x <= ((width-1) | 7); x++) {
+ *p <<= 1;
+ if (x < width)
+ *p |= getint(fin) & 1;
+ if ((x & 7) == 7)
+ ++p;
+ }
+ break;
+ case '4':
+ /* PBM raw binary format */
+ fread(next_line, bpl, 1, fin);
+ break;
+ default:
+ fprintf(stderr, "Unsupported PBM type P%c!\n", type);
+ exit(1);
+ }
+ if (ferror(fin)) {
+ fprintf(stderr, "Problem while reading input file '%s", fnin);
+ perror("'");
+ exit(1);
+ }
+ if (feof(fin)) {
+ fprintf(stderr, "Unexpected end of input file '%s'!\n", fnin);
+ exit(1);
+ }
+
+ /* JBIG compress another line and write out result via callback */
+ jbg85_enc_lineout(&s, next_line, prev_line, prevprev_line);
+ prevprev_line = prev_line;
+ prev_line = next_line;
+
+ /* adjust final image height via NEWLEN */
+ if (yi && y == yr)
+ jbg85_enc_newlen(&s, height);
+ }
+
+ /* check for file errors and close fout */
+ if (ferror(fout) || fclose(fout)) {
+ fprintf(stderr, "Problem while writing output file '%s", fnout);
+ perror("'");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/thirdparty/jbigkit/pbmtools/pgm.5 b/thirdparty/jbigkit/pbmtools/pgm.5
new file mode 100644
index 000000000..94a352a1e
--- /dev/null
+++ b/thirdparty/jbigkit/pbmtools/pgm.5
@@ -0,0 +1,90 @@
+.TH pgm 5 "12 November 1991"
+.SH NAME
+pgm - portable graymap file format
+.SH DESCRIPTION
+The portable graymap format is a lowest common denominator grayscale
+file format.
+.IX "PGM file format"
+The definition is as follows:
+.IP - 2
+A "magic number" for identifying the file type.
+A pgm file's magic number is the two characters "P2".
+.IX "magic numbers"
+.IP - 2
+Whitespace (blanks, TABs, CRs, LFs).
+.IP - 2
+A width, formatted as ASCII characters in decimal.
+.IP - 2
+Whitespace.
+.IP - 2
+A height, again in ASCII decimal.
+.IP - 2
+Whitespace.
+.IP - 2
+The maximum gray value, again in ASCII decimal.
+.IP - 2
+Whitespace.
+.IP - 2
+Width * height gray values, each in ASCII decimal, between 0 and the specified
+maximum value, separated by whitespace, starting at the top-left
+corner of the graymap, proceeding in normal English reading order.
+A value of 0 means black, and the maximum value means white.
+.IP - 2
+Characters from a "#" to the next end-of-line are ignored (comments).
+.IP - 2
+No line should be longer than 70 characters.
+.PP
+Here is an example of a small graymap in this format:
+.nf
+P2
+# feep.pgm
+24 7
+15
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
+0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
+0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
+0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
+0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+.fi
+.PP
+Programs that read this format should be as lenient as possible,
+accepting anything that looks remotely like a graymap.
+.PP
+There is also a variant on the format, available
+by setting the RAWBITS option at compile time. This variant is
+different in the following ways:
+.IX RAWBITS
+.IP - 2
+The "magic number" is "P5" instead of "P2".
+.IP - 2
+The gray values are stored as plain bytes, instead of ASCII decimal.
+.IP - 2
+No whitespace is allowed in the grays section, and only a single character
+of whitespace (typically a newline) is allowed after the maxval.
+.IP - 2
+The files are smaller and many times faster to read and write.
+.PP
+Note that this raw format can only be used for maxvals less than
+or equal to 255.
+If you use the
+.I pgm
+library and try to write a file with a larger maxval,
+it will automatically fall back on the slower but more general plain
+format.
+.SH "SEE ALSO"
+fitstopgm(1), fstopgm(1), hipstopgm(1), lispmtopgm(1), psidtopgm(1),
+rawtopgm(1),
+pgmbentley(1), pgmcrater(1), pgmedge(1), pgmenhance(1), pgmhist(1), pgmnorm(1),
+pgmoil(1), pgmramp(1), pgmtexture(1),
+pgmtofits(1), pgmtofs(1), pgmtolispm(1), pgmtopbm(1),
+pnm(5), pbm(5), ppm(5)
+.SH AUTHOR
+Copyright (C) 1989, 1991 by Jef Poskanzer.
+.\" Permission to use, copy, modify, and distribute this software and its
+.\" documentation for any purpose and without fee is hereby granted, provided
+.\" that the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation. This software is provided "as is" without express or
+.\" implied warranty.